win-pvdrivers

changeset 435:29da24ccca8a

Crash Dump wasn't always working properly because ring bit-width detection doesn't work properly unless the ring pointers are all zero. Now save the state and read it in event of a crash dump.

This may correct an issue where crashdumps could have been causing corruption.
author James Harper <james.harper@bendigoit.com.au>
date Sun Nov 02 16:10:40 2008 +1100 (2008-11-02)
parents b6fb4cf3e0fa
children c4204f69c506
files xenvbd/xenvbd.c xenvbd/xenvbd.h
line diff
     1.1 --- a/xenvbd/xenvbd.c	Wed Oct 29 21:53:30 2008 +1100
     1.2 +++ b/xenvbd/xenvbd.c	Sun Nov 02 16:10:40 2008 +1100
     1.3 @@ -153,7 +153,7 @@ XenVbd_InitFromConfig(PXENVBD_DEVICE_DAT
     1.4          FRONT_RING_INIT(&xvdd->ring, xvdd->sring, PAGE_SIZE);
     1.5          /* this bit is for when we have to take over an existing ring on a bug check */
     1.6          xvdd->ring.req_prod_pvt = xvdd->sring->req_prod;
     1.7 -        xvdd->ring.rsp_cons = xvdd->sring->rsp_prod;
     1.8 +        xvdd->ring.rsp_cons = xvdd->ring.req_prod_pvt;
     1.9        }
    1.10        break;
    1.11      case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
    1.12 @@ -161,7 +161,14 @@ XenVbd_InitFromConfig(PXENVBD_DEVICE_DAT
    1.13        //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, PtrToUlong(value)));
    1.14        if (strcmp(setting, "event-channel") == 0)
    1.15        {
    1.16 -        xvdd->event_channel = PtrToUlong(value);
    1.17 +        /* cheat here - save the state of the ring in the topmost bits of the event-channel */
    1.18 +        xvdd->event_channel_ptr = (ULONG *)(((PCHAR)ptr) - sizeof(ULONG));
    1.19 +        xvdd->event_channel = PtrToUlong(value) & 0x3FFFFFFF;
    1.20 +        if (PtrToUlong(value) & 0x80000000)
    1.21 +        {
    1.22 +          xvdd->cached_use_other = (BOOLEAN)!!(PtrToUlong(value) & 0x40000000);
    1.23 +          KdPrint((__DRIVER_NAME "     cached_use_other = %d\n", xvdd->cached_use_other));
    1.24 +        }
    1.25        }
    1.26        break;
    1.27      case XEN_INIT_TYPE_READ_STRING_BACK:
    1.28 @@ -569,8 +576,6 @@ XenVbd_HwScsiFindAdapter(PVOID DeviceExt
    1.29      KdPrint((__DRIVER_NAME "     Dma64BitAddresses not supported\n"));
    1.30    }
    1.31  
    1.32 -  xvdd->ring_detect_state = 0;
    1.33 -
    1.34    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));  
    1.35  
    1.36    return SP_RETURN_FOUND;
    1.37 @@ -587,32 +592,45 @@ XenVbd_HwScsiInitialize(PVOID DeviceExte
    1.38    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    1.39    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
    1.40  
    1.41 -  req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
    1.42 -  req->operation = 0xff;
    1.43 -  req->nr_segments = 0;
    1.44 -  for (i = 0; i < BLKIF_MAX_SEGMENTS_PER_REQUEST; i++)
    1.45 +  if (!dump_mode)
    1.46    {
    1.47 -    req->seg[i].gref = 0; //0xffffffff;
    1.48 -    req->seg[i].first_sect = 0; //0xff;
    1.49 -    req->seg[i].last_sect = 0; //0xff;
    1.50 -  }
    1.51 -  xvdd->ring.req_prod_pvt++;
    1.52 +    req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
    1.53 +    req->operation = 0xff;
    1.54 +    req->nr_segments = 0;
    1.55 +    for (i = 0; i < BLKIF_MAX_SEGMENTS_PER_REQUEST; i++)
    1.56 +    {
    1.57 +      req->seg[i].gref = 0; //0xffffffff;
    1.58 +      req->seg[i].first_sect = 0; //0xff;
    1.59 +      req->seg[i].last_sect = 0; //0xff;
    1.60 +    }
    1.61 +    xvdd->ring.req_prod_pvt++;
    1.62  
    1.63 -  req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
    1.64 -  req->operation = 0xff;
    1.65 -  req->nr_segments = 0;
    1.66 -  for (i = 0; i < BLKIF_MAX_SEGMENTS_PER_REQUEST; i++)
    1.67 +    req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
    1.68 +    req->operation = 0xff;
    1.69 +    req->nr_segments = 0;
    1.70 +    for (i = 0; i < BLKIF_MAX_SEGMENTS_PER_REQUEST; i++)
    1.71 +    {
    1.72 +      req->seg[i].gref = 0; //0xffffffff;
    1.73 +      req->seg[i].first_sect = 0; //0xff;
    1.74 +      req->seg[i].last_sect = 0; //0xff;
    1.75 +    }
    1.76 +    xvdd->ring.req_prod_pvt++;
    1.77 +
    1.78 +    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
    1.79 +    if (notify)
    1.80 +      xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
    1.81 +    xvdd->ring_detect_state = 0;
    1.82 +  }
    1.83 +  else
    1.84    {
    1.85 -    req->seg[i].gref = 0; //0xffffffff;
    1.86 -    req->seg[i].first_sect = 0; //0xff;
    1.87 -    req->seg[i].last_sect = 0; //0xff;
    1.88 +    if (xvdd->cached_use_other)
    1.89 +    {
    1.90 +      xvdd->ring.nr_ents = BLK_OTHER_RING_SIZE;
    1.91 +      xvdd->use_other = TRUE;
    1.92 +    }
    1.93 +    xvdd->ring_detect_state = 2;
    1.94    }
    1.95 -  xvdd->ring.req_prod_pvt++;
    1.96 -
    1.97 -  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
    1.98 -  if (notify)
    1.99 -    xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
   1.100 -
   1.101 +  
   1.102    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.103  
   1.104    return TRUE;
   1.105 @@ -785,13 +803,13 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
   1.106      return FALSE;
   1.107    }
   1.108  
   1.109 -  if (!(stat_interrupts_for_me & 0x3FF))
   1.110 +  if (!(stat_interrupts_for_me & 0xFFFF))
   1.111      XenVbd_DumpStats();
   1.112    while (more_to_do)
   1.113    {
   1.114      rp = xvdd->ring.sring->rsp_prod;
   1.115      KeMemoryBarrier();
   1.116 -    for (i = xvdd->ring.rsp_cons; i != rp; i++)
   1.117 +    for (i = xvdd->ring.rsp_cons; i < rp; i++)
   1.118      {
   1.119        rep = XenVbd_GetResponse(xvdd, i);
   1.120  /*
   1.121 @@ -815,10 +833,12 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
   1.122          break;
   1.123        case 1:
   1.124          KdPrint((__DRIVER_NAME "     ring_detect_state = %d, operation = %x, id = %lx, status = %d\n", xvdd->ring_detect_state, rep->operation, rep->id, rep->status));
   1.125 +        *xvdd->event_channel_ptr |= 0x80000000;
   1.126          if (rep->operation != 0xff)
   1.127          {
   1.128            xvdd->ring.nr_ents = BLK_OTHER_RING_SIZE;
   1.129            xvdd->use_other = TRUE;
   1.130 +          *xvdd->event_channel_ptr |= 0x40000000;
   1.131          }
   1.132          xvdd->ring_detect_state = 2;
   1.133          ScsiPortNotification(NextRequest, DeviceExtension);
   1.134 @@ -1309,11 +1329,18 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   1.135    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   1.136  
   1.137    conf_info = IoGetConfigurationInformation();
   1.138 -  KdPrint((__DRIVER_NAME "     conf_info->DiskCount = %d\n", conf_info->DiskCount));
   1.139 +  if (conf_info == NULL)
   1.140 +  {
   1.141 +    KdPrint((__DRIVER_NAME "     conf_info == NULL\n"));
   1.142 +  }
   1.143 +  else
   1.144 +  {
   1.145 +    KdPrint((__DRIVER_NAME "     conf_info->DiskCount = %d\n", conf_info->DiskCount));
   1.146 +  }
   1.147    /* RegistryPath == NULL when we are invoked as a crash dump driver */
   1.148    if (!RegistryPath)
   1.149      dump_mode = TRUE;
   1.150 -  if (conf_info->DiskCount && RegistryPath)
   1.151 +  if (conf_info != NULL && conf_info->DiskCount && RegistryPath)
   1.152    {
   1.153      global_inactive = TRUE;
   1.154      KdPrint((__DRIVER_NAME "     Not loaded at boot time so setting inactive\n"));
     2.1 --- a/xenvbd/xenvbd.h	Wed Oct 29 21:53:30 2008 +1100
     2.2 +++ b/xenvbd/xenvbd.h	Sun Nov 02 16:10:40 2008 +1100
     2.3 @@ -122,12 +122,14 @@ struct
     2.4  
     2.5    blkif_sring_t *sring;
     2.6    evtchn_port_t event_channel;
     2.7 +  ULONG *event_channel_ptr;
     2.8    union {
     2.9      blkif_front_ring_t ring;
    2.10      blkif_other_front_ring_t other_ring;
    2.11    };
    2.12    int ring_detect_state;
    2.13    BOOLEAN use_other;
    2.14 +  BOOLEAN cached_use_other;
    2.15    UCHAR last_sense_key;
    2.16    UCHAR last_additional_sense_code;
    2.17    blkif_response_t tmp_rep;