diff options
author | Penchala Narasimha Reddy Chilakala, ERS-HCLTech <narasimhareddyc@hcl.in> | 2009-12-21 18:39:27 +0530 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-01-17 12:16:17 -0600 |
commit | cacb6dc3d7fea751879a225c15e48228415e6359 (patch) | |
tree | f0d1b3792febab8910274e15f0076053a825e392 /drivers/scsi/aacraid/dpcsup.c | |
parent | e6622df3bb1a8e1135f4b84928e24d4c6802f6b5 (diff) | |
download | kernel_goldelico_gta04-cacb6dc3d7fea751879a225c15e48228415e6359.zip kernel_goldelico_gta04-cacb6dc3d7fea751879a225c15e48228415e6359.tar.gz kernel_goldelico_gta04-cacb6dc3d7fea751879a225c15e48228415e6359.tar.bz2 |
[SCSI] aacraid: fix File System going into read-only mode
These particular problems were reported by Cisco and SAP and customers
as well. Cisco reported on RHEL4 U6 and SAP reported on SLES9 SP4 and
SLES10 SP2. We added these fixes on RHEL4 U6 and gave a private build
to IBM and Cisco. Cisco and IBM tested it for more than 15 days and
they reported that they did not see the issue so far. Before the fix,
Cisco used to see the issue within 5 days. We generated a patch for
SLES9 SP4 and SLES10 SP2 and submitted to Novell. Novell applied the
patch and gave a test build to SAP. SAP tested and reported that the
build is working properly.
We also tested in our lab using the tools "dishogsync", which is IO
stress tool and the tool was provided by Cisco.
Issue1: File System going into read-only mode
Root cause: The driver tends to not free the memory (FIB) when the
management request exits prematurely. The accumulation of such
un-freed memory causes the driver to fail to allocate anymore memory
(FIB) and hence return 0x70000 value to the upper layer, which puts
the file system into read only mode.
Fix details: The fix makes sure to free the memory (FIB) even if the
request exits prematurely hence ensuring the driver wouldn't run out
of memory (FIBs).
Issue2: False Raid Alert occurs
When the Physical Drives and Logical drives are reported as deleted or
added, even though there is no change done on the system
Root cause: Driver IOCTLs is signaled with EINTR while waiting on
response from the lower layers. Returning "EINTR" will never initiate
internal retry.
Fix details: The issue was fixed by replacing "EINTR" with
"ERESTARTSYS" for mid-layer retries.
Signed-off-by: Penchala Narasimha Reddy <ServeRAIDDriver@hcl.in>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/aacraid/dpcsup.c')
-rw-r--r-- | drivers/scsi/aacraid/dpcsup.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c index abc9ef5..9c7408fe 100644 --- a/drivers/scsi/aacraid/dpcsup.c +++ b/drivers/scsi/aacraid/dpcsup.c @@ -57,9 +57,9 @@ unsigned int aac_response_normal(struct aac_queue * q) struct hw_fib * hwfib; struct fib * fib; int consumed = 0; - unsigned long flags; + unsigned long flags, mflags; - spin_lock_irqsave(q->lock, flags); + spin_lock_irqsave(q->lock, flags); /* * Keep pulling response QEs off the response queue and waking * up the waiters until there are no more QEs. We then return @@ -125,12 +125,21 @@ unsigned int aac_response_normal(struct aac_queue * q) } else { unsigned long flagv; spin_lock_irqsave(&fib->event_lock, flagv); - if (!fib->done) + if (!fib->done) { fib->done = 1; - up(&fib->event_wait); + up(&fib->event_wait); + } spin_unlock_irqrestore(&fib->event_lock, flagv); + + spin_lock_irqsave(&dev->manage_lock, mflags); + dev->management_fib_count--; + spin_unlock_irqrestore(&dev->manage_lock, mflags); + FIB_COUNTER_INCREMENT(aac_config.NormalRecved); if (fib->done == 2) { + spin_lock_irqsave(&fib->event_lock, flagv); + fib->done = 0; + spin_unlock_irqrestore(&fib->event_lock, flagv); aac_fib_complete(fib); aac_fib_free(fib); } @@ -232,6 +241,7 @@ unsigned int aac_command_normal(struct aac_queue *q) unsigned int aac_intr_normal(struct aac_dev * dev, u32 index) { + unsigned long mflags; dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, index)); if ((index & 0x00000002L)) { struct hw_fib * hw_fib; @@ -320,11 +330,25 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 index) unsigned long flagv; dprintk((KERN_INFO "event_wait up\n")); spin_lock_irqsave(&fib->event_lock, flagv); - if (!fib->done) + if (!fib->done) { fib->done = 1; - up(&fib->event_wait); + up(&fib->event_wait); + } spin_unlock_irqrestore(&fib->event_lock, flagv); + + spin_lock_irqsave(&dev->manage_lock, mflags); + dev->management_fib_count--; + spin_unlock_irqrestore(&dev->manage_lock, mflags); + FIB_COUNTER_INCREMENT(aac_config.NormalRecved); + if (fib->done == 2) { + spin_lock_irqsave(&fib->event_lock, flagv); + fib->done = 0; + spin_unlock_irqrestore(&fib->event_lock, flagv); + aac_fib_complete(fib); + aac_fib_free(fib); + } + } return 0; } |