Skip to content

Commit

Permalink
vioscsi: add logic to make reset mechanism configurable
Browse files Browse the repository at this point in the history
We have seen many cases where we see vioscsi 129 reset events leading to a
complete guest hang. While overall reset logic added in
#684 likely
mitigates the problem, we still see sporadic requests from customer where
they see guest OSes hangs.

This change will make it possible configure system to bugcheck and get a
memory dump and the state of the VQs.

By default, the behavior will remain intact - complete pending SRBs, but
can be changed to either to do nothing or bugcheck the guest by setting
the registry value:

Path:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vioscsi\Parameters

Name:    VioscsiActionOnReset
Type:    REG_DWORD
Values:
         0x0 - Complete all pending SRBs (default)
         0x1 - Do nothing (all unserved SRBs will be stored in memory)
         0xdeaddead - Bugcheck on the reset event

Signed-off-by: Sergey Bykov <[email protected]>
  • Loading branch information
sb-ntnx authored and vrozenfe committed Aug 25, 2023
1 parent 322f1a4 commit eff7b43
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 7 deletions.
24 changes: 19 additions & 5 deletions vioscsi/vioscsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ ENTER_FN();
* [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vioscsi\Parameters\Device]
* "PhysicalBreaks"={dword value here}
*/
VioScsiReadRegistryParameter(DeviceExtension, MAX_PH_BREAKS, FIELD_OFFSET(ADAPTER_EXTENSION, max_physical_breaks));
VioScsiReadRegistryParameter(DeviceExtension, REGISTRY_MAX_PH_BREAKS, FIELD_OFFSET(ADAPTER_EXTENSION, max_physical_breaks));
adaptExt->max_physical_breaks = min(
max(SCSI_MINIMUM_PHYSICAL_BREAKS, adaptExt->max_physical_breaks),
MAX_PHYS_SEGMENTS);
Expand Down Expand Up @@ -520,6 +520,9 @@ ENTER_FN();
adaptExt->num_queues = min(adaptExt->num_queues, (USHORT)num_cpus);
}

adaptExt->action_on_reset = VioscsiResetCompleteRequests;
VioScsiReadRegistryParameter(DeviceExtension, REGISTRY_ACTION_ON_RESET, FIELD_OFFSET(ADAPTER_EXTENSION, action_on_reset));

RhelDbgPrint(TRACE_LEVEL_INFORMATION, " Queues %d CPUs %d\n", adaptExt->num_queues, num_cpus);

/* Figure out the maximum number of queues we will ever need to set up. Note that this may
Expand Down Expand Up @@ -1493,10 +1496,21 @@ ENTER_FN_SRB();
case SRB_FUNCTION_RESET_DEVICE:
case SRB_FUNCTION_RESET_LOGICAL_UNIT:
RhelDbgPrint(TRACE_LEVEL_INFORMATION, " <--> SRB_FUNCTION_RESET_LOGICAL_UNIT Target (%d::%d::%d), SRB 0x%p\n", SRB_PATH_ID(Srb), SRB_TARGET_ID(Srb), SRB_LUN(Srb), Srb);
CompletePendingRequests(DeviceExtension);
SRB_SET_SRB_STATUS(Srb, SRB_STATUS_SUCCESS);
return TRUE;

switch (adaptExt->action_on_reset) {
case VioscsiResetCompleteRequests:
RhelDbgPrint(TRACE_LEVEL_INFORMATION, " Completing all pending SRBs\n");
CompletePendingRequests(DeviceExtension);
SRB_SET_SRB_STATUS(Srb, SRB_STATUS_SUCCESS);
return TRUE;
case VioscsiResetDoNothing:
RhelDbgPrint(TRACE_LEVEL_INFORMATION, " Doing nothing with all pending SRBs\n");
SRB_SET_SRB_STATUS(Srb, SRB_STATUS_SUCCESS);
return TRUE;
case VioscsiResetBugCheck:
RhelDbgPrint(TRACE_LEVEL_INFORMATION, " Let's bugcheck due to this reset event\n");
KeBugCheckEx(0xDEADDEAD, (ULONG_PTR)Srb, SRB_PATH_ID(Srb), SRB_TARGET_ID(Srb), SRB_LUN(Srb));
return TRUE;
}
case SRB_FUNCTION_WMI:
VioScsiWmiSrb(DeviceExtension, Srb);
return TRUE;
Expand Down
12 changes: 10 additions & 2 deletions vioscsi/vioscsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ typedef struct VirtIOBufferDescriptor VIO_SG, *PVIO_SG;
#define IO_PORT_LENGTH 0x40
#define MAX_CPU 256

#define MAX_PH_BREAKS "PhysicalBreaks"
#define REGISTRY_MAX_PH_BREAKS "PhysicalBreaks"
#define REGISTRY_ACTION_ON_RESET "VioscsiActionOnReset"


/* Feature Bits */
Expand Down Expand Up @@ -271,6 +272,12 @@ typedef struct virtio_bar {
BOOLEAN bPortSpace;
} VIRTIO_BAR, *PVIRTIO_BAR;

typedef enum ACTION_ON_RESET {
VioscsiResetCompleteRequests,
VioscsiResetDoNothing,
VioscsiResetBugCheck = 0xDEADDEAD,
} ACTION_ON_RESET;

typedef struct _ADAPTER_EXTENSION {
VirtIODevice vdev;

Expand Down Expand Up @@ -326,10 +333,11 @@ typedef struct _ADAPTER_EXTENSION {
UCHAR prod_id[16 + 1];
UCHAR rev_id[4 + 1];
BOOLEAN reset_in_progress;
ACTION_ON_RESET action_on_reset;
#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
ULONGLONG fw_ver;
#endif
}ADAPTER_EXTENSION, * PADAPTER_EXTENSION;
} ADAPTER_EXTENSION, * PADAPTER_EXTENSION;

#ifndef PCIX_TABLE_POINTER
typedef struct {
Expand Down

0 comments on commit eff7b43

Please sign in to comment.