• R/O
  • HTTP
  • SSH
  • HTTPS

linux-2.4.36: Commit

2.4.36-stable kernel tree


Commit MetaInfo

Revisionee731f57c03a321e73eb700a06e9c0172d505ffa (tree)
Time2007-11-12 02:44:01
AuthorTony Battersby <tonyb@cybe...>
CommiterWilly Tarreau

Log Message

[PATCH] sym53c8xx_2 SMP deadlock on driver load

This patch fixes two problems with sym53c8xx_2.o in 2.4.x kernels:

1) A system hang when loading sym53c8xx_2.o on a SMP system with two
dual-channel LSI HBAs (http://bugzilla.kernel.org/show_bug.cgi?id=3680)

2) A function improperly marked init.

Comment from Matthew Wilcox:
" This is a pretty ugly patch, but I think the three alternatives are

worse:
- Drop the iorl at the beginning of ->detect and reacquire it at exit.
We don't know what else the iorl might be protecting. Probably
nothing, but I don't want to audit it.
- Convert sym2 back to old error handling so the midlayer doesn't
acquire the iorl for us in ->detect.
- Acquire the iorl in ->release. We might deadlock on something.
So, sure, apply this patch. "

Signed-off-by: Tony Battersby <tonyb@cybernetics.com>

Change Summary

Incremental Difference

--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -224,15 +224,26 @@ static u_long __init pci_map_mem(u_long base, u_long size)
224224 {
225225 u_long page_base = ((u_long) base) & PAGE_MASK;
226226 u_long page_offs = ((u_long) base) - page_base;
227- u_long page_remapped = (u_long) ioremap(page_base, page_offs+size);
227+ u_long page_remapped;
228+
229+ spin_unlock_irq(&io_request_lock);
230+ page_remapped = (u_long) ioremap(page_base, page_offs+size);
231+ spin_lock_irq(&io_request_lock);
228232
229233 return page_remapped? (page_remapped + page_offs) : 0UL;
230234 }
231235
232-static void __init pci_unmap_mem(u_long vaddr, u_long size)
236+static void pci_unmap_mem(u_long vaddr,
237+ u_long size,
238+ int holding_io_request_lock)
233239 {
234- if (vaddr)
240+ if (vaddr) {
241+ if (holding_io_request_lock)
242+ spin_unlock_irq(&io_request_lock);
235243 iounmap((void *) (vaddr & PAGE_MASK));
244+ if (holding_io_request_lock)
245+ spin_lock_irq(&io_request_lock);
246+ }
236247 }
237248 #endif
238249
@@ -1840,7 +1851,7 @@ static int sym53c8xx_proc_info(char *buffer, char **start, off_t offset,
18401851 /*
18411852 * Free controller resources.
18421853 */
1843-static void sym_free_resources(hcb_p np)
1854+static void sym_free_resources(hcb_p np, int holding_io_request_lock)
18441855 {
18451856 /*
18461857 * Free O/S specific resources.
@@ -1851,9 +1862,13 @@ static void sym_free_resources(hcb_p np)
18511862 release_region(np->s.io_port, np->s.io_ws);
18521863 #ifndef SYM_OPT_NO_BUS_MEMORY_MAPPING
18531864 if (np->s.mmio_va)
1854- pci_unmap_mem(np->s.mmio_va, np->s.io_ws);
1865+ pci_unmap_mem(np->s.mmio_va,
1866+ np->s.io_ws,
1867+ holding_io_request_lock);
18551868 if (np->s.ram_va)
1856- pci_unmap_mem(np->s.ram_va, np->ram_ws);
1869+ pci_unmap_mem(np->s.ram_va,
1870+ np->ram_ws,
1871+ holding_io_request_lock);
18571872 #endif
18581873 /*
18591874 * Free O/S independant resources.
@@ -2155,7 +2170,7 @@ attach_failed:
21552170 if (!instance) return -1;
21562171 printf_info("%s: giving up ...\n", sym_name(np));
21572172 if (np)
2158- sym_free_resources(np);
2173+ sym_free_resources(np, 1);
21592174 scsi_unregister(instance);
21602175
21612176 return -1;
@@ -2197,7 +2212,7 @@ static void __init sym_get_nvram(sym_device *devp, sym_nvram *nvp)
21972212 #ifdef SYM_CONF_IOMAPPED
21982213 release_region(devp->s.io_port, 128);
21992214 #else
2200- pci_unmap_mem((u_long) devp->s.mmio_va, 128ul);
2215+ pci_unmap_mem((u_long) devp->s.mmio_va, 128ul, 1);
22012216 #endif
22022217 }
22032218 #endif /* SYM_CONF_NVRAM_SUPPORT */
@@ -2551,7 +2566,7 @@ sym53c8xx_pci_init(Scsi_Host_Template *tpnt, pcidev_t pdev, sym_device *device)
25512566 ram_ptr = pci_map_mem(base_2_c, ram_size);
25522567 if (ram_ptr) {
25532568 ram_val = readl_raw(ram_ptr + ram_size - 16);
2554- pci_unmap_mem(ram_ptr, ram_size);
2569+ pci_unmap_mem(ram_ptr, ram_size, 1);
25552570 if (ram_val == 0x52414944) {
25562571 printf_info("%s: not initializing, "
25572572 "driven by RAID controller.\n",
@@ -2980,7 +2995,7 @@ static int sym_detach(hcb_p np)
29802995 /*
29812996 * Free host resources
29822997 */
2983- sym_free_resources(np);
2998+ sym_free_resources(np, 0);
29842999
29853000 return 1;
29863001 }
Show on old repository browser