2.4.36-stable kernel tree
Revision | ee731f57c03a321e73eb700a06e9c0172d505ffa (tree) |
---|---|
Zeit | 2007-11-12 02:44:01 |
Autor | Tony Battersby <tonyb@cybe...> |
Commiter | Willy Tarreau |
[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
Signed-off-by: Tony Battersby <tonyb@cybernetics.com>
@@ -224,15 +224,26 @@ static u_long __init pci_map_mem(u_long base, u_long size) | ||
224 | 224 | { |
225 | 225 | u_long page_base = ((u_long) base) & PAGE_MASK; |
226 | 226 | 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); | |
228 | 232 | |
229 | 233 | return page_remapped? (page_remapped + page_offs) : 0UL; |
230 | 234 | } |
231 | 235 | |
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) | |
233 | 239 | { |
234 | - if (vaddr) | |
240 | + if (vaddr) { | |
241 | + if (holding_io_request_lock) | |
242 | + spin_unlock_irq(&io_request_lock); | |
235 | 243 | iounmap((void *) (vaddr & PAGE_MASK)); |
244 | + if (holding_io_request_lock) | |
245 | + spin_lock_irq(&io_request_lock); | |
246 | + } | |
236 | 247 | } |
237 | 248 | #endif |
238 | 249 |
@@ -1840,7 +1851,7 @@ static int sym53c8xx_proc_info(char *buffer, char **start, off_t offset, | ||
1840 | 1851 | /* |
1841 | 1852 | * Free controller resources. |
1842 | 1853 | */ |
1843 | -static void sym_free_resources(hcb_p np) | |
1854 | +static void sym_free_resources(hcb_p np, int holding_io_request_lock) | |
1844 | 1855 | { |
1845 | 1856 | /* |
1846 | 1857 | * Free O/S specific resources. |
@@ -1851,9 +1862,13 @@ static void sym_free_resources(hcb_p np) | ||
1851 | 1862 | release_region(np->s.io_port, np->s.io_ws); |
1852 | 1863 | #ifndef SYM_OPT_NO_BUS_MEMORY_MAPPING |
1853 | 1864 | 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); | |
1855 | 1868 | 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); | |
1857 | 1872 | #endif |
1858 | 1873 | /* |
1859 | 1874 | * Free O/S independant resources. |
@@ -2155,7 +2170,7 @@ attach_failed: | ||
2155 | 2170 | if (!instance) return -1; |
2156 | 2171 | printf_info("%s: giving up ...\n", sym_name(np)); |
2157 | 2172 | if (np) |
2158 | - sym_free_resources(np); | |
2173 | + sym_free_resources(np, 1); | |
2159 | 2174 | scsi_unregister(instance); |
2160 | 2175 | |
2161 | 2176 | return -1; |
@@ -2197,7 +2212,7 @@ static void __init sym_get_nvram(sym_device *devp, sym_nvram *nvp) | ||
2197 | 2212 | #ifdef SYM_CONF_IOMAPPED |
2198 | 2213 | release_region(devp->s.io_port, 128); |
2199 | 2214 | #else |
2200 | - pci_unmap_mem((u_long) devp->s.mmio_va, 128ul); | |
2215 | + pci_unmap_mem((u_long) devp->s.mmio_va, 128ul, 1); | |
2201 | 2216 | #endif |
2202 | 2217 | } |
2203 | 2218 | #endif /* SYM_CONF_NVRAM_SUPPORT */ |
@@ -2551,7 +2566,7 @@ sym53c8xx_pci_init(Scsi_Host_Template *tpnt, pcidev_t pdev, sym_device *device) | ||
2551 | 2566 | ram_ptr = pci_map_mem(base_2_c, ram_size); |
2552 | 2567 | if (ram_ptr) { |
2553 | 2568 | 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); | |
2555 | 2570 | if (ram_val == 0x52414944) { |
2556 | 2571 | printf_info("%s: not initializing, " |
2557 | 2572 | "driven by RAID controller.\n", |
@@ -2980,7 +2995,7 @@ static int sym_detach(hcb_p np) | ||
2980 | 2995 | /* |
2981 | 2996 | * Free host resources |
2982 | 2997 | */ |
2983 | - sym_free_resources(np); | |
2998 | + sym_free_resources(np, 0); | |
2984 | 2999 | |
2985 | 3000 | return 1; |
2986 | 3001 | } |