NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/39526: adh driver crashes system if it runs out of memory



The following reply was made to PR kern/39526; it has been noted by GNATS.

From: Wolfgang Stukenbrock <Wolfgang.Stukenbrock%nagler-company.com@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: 
Subject: Re: kern/39526: adh driver crashes system if it runs out of memory
Date: Fri, 26 Sep 2008 13:48:36 +0200

 Hi again,
 
 now I've a workaround that avoids crashing the system by the ahd driver.
 
 The workaround will allocate all SCB structures during startup if 64-bit 
 bus is detected. By dooing this it avoids any call to GROW the number of 
 SCB's later.
 That is the place where no memory was found and after some failed 
 allocations a kernel crash with "fatal page fault in supervisour mode" 
 happens.
 
 Wit this fix I've go no longer the kernel panic.
 So this workaround leads to a stable running driver, but it does not fix 
 the main cause of the problem!
 There seems to be something wrong in either this driver or the uvm stuff!
 
 I assume that the problem is in the uvm stuff, because I've a similar 
 problem with the ahc driver. It will crash too after more than 4G is 
 used by the system and the ahc driver will also try to allocate more SCB's.
 
 Output of "diff -u" for ic/aic79xx.c ic/aic79xx_osm.c and pci/ahd_pci.c 
 below.
 
 Please integrate this workaround into the next possible release. Thanks 
 in advance.
 A similar fix should be added to the ahc driver to work around the 
 problem there.
 
 
 W. Stukenbrock
 
 
 in /usr/src/sys/dev/ic:
 
 
 --- aic79xx.c   2008/09/26 11:19:07     1.1
 +++ aic79xx.c   2008/09/26 11:26:57
 @@ -5441,6 +5441,24 @@
                        ahd_name(ahd));
                 goto error_exit;
         }
 +/*
 + * Workaround for the "more than 4GB main memory" crash.
 + * We allocate all SCB's now - no additional request taht may fail
 + * later.
 + * This will work around a bug in either this driver or the uvm part.
 + * Without this, the system will crash after some failed GROW requests with
 + * a "fatal page fault in supoervisor mode".
 + *
 + * This fix requires setting the 64-Bit Flag in ahd_pci.c too.
 + * Perhaps the amount of main memory should be checked here too ..
 + *
 +  W. Stukenbrock (09.2008)
 + */
 +       if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
 +               printf("%s: allocating all SCB entries - 64 bit workaround for 
4G memory bug\n",
 +                       ahd_name(ahd));
 +               while (ahd_alloc_scbs(ahd) != 0);
 +       }
  
         /*
          * Note that we were successfull
 
 ===================================================================
 
 --- aic79xx_osm.c       2008/09/26 11:19:07     1.1
 +++ aic79xx_osm.c       2008/09/26 10:26:51
 @@ -95,7 +95,9 @@
           ahd->sc_channel.chan_ntargets = AHD_NUM_TARGETS;
           ahd->sc_channel.chan_nluns = 8 /*AHD_NUM_LUNS*/;
           ahd->sc_channel.chan_id = ahd->our_id;
 -        ahd->sc_channel.chan_flags |= SCSIPI_CHAN_CANGROW;
 +/* do not wast time if everything is allread allocated ... */
 +        if (ahd->scb_data.numscbs < AHD_SCB_MAX_ALLOC)
 +               ahd->sc_channel.chan_flags |= SCSIPI_CHAN_CANGROW;
 
          ahd->sc_child = config_found((void *)ahd, &ahd->sc_channel, 
 scsiprint);
 
 ===================================================================
 
 in /usr/src/sys/dev/pci:
 
 --- ahd_pci.c   2008/09/12 14:37:11     1.1
 +++ ahd_pci.c   2008/09/26 11:17:42
 @@ -400,6 +400,12 @@
                  ahd->chip |= AHD_PCI;
                  ahd->bugs &= ~AHD_PCIX_BUG_MASK;
          }
 +       else if (devconfig & PCI64BIT) {
 +               ahd->flags |= AHD_64BIT_ADDRESSING;
 +       } else {
 +               aprint_normal("\n%s: WARNING: not on 64 bit Bus - may be 
 a problem with more than 4GB main memory",
 +                       ahd_name(ahd));
 +       }
 
          /*
           * Map PCI Registers
 @@ -502,7 +508,8 @@
          if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) 
 != 0) {
                  uint32_t dvconfig;
 
 -               aprint_normal("%s: Enabling 39Bit Addressing\n", 
 ahd_name(ahd));
 +               aprint_normal("%s: Enabling %sBit Addressing\n", 
 ahd_name(ahd),
 +                 ((ahd->flags & AHD_64BIT_ADDRESSING) ? "64" : "39"));
                  dvconfig = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
                  dvconfig |= DACEN;
                  pci_conf_write(pa->pa_pc, pa->pa_tag, DEVCONFIG, dvconfig);
 ===================================================================
 
 
 
 
 


Home | Main Index | Thread Index | Old Index