Messages in this thread Patch in this message | | | Date | Thu, 7 Sep 2000 16:15:53 +0100 (BST) | From | Tigran Aivazian <> | Subject | [patch-2.4.0-test8-pre6] misc fixes |
| |
Hi Linus,
This patch was reviewed by human kind for several hours and there was found no fault in it.
It fixes:
a) bugfix to read_kmem() which currently can fail on low memory when it should succeed (i.e. when it doesn't need that page)
b) nvram driver doesn't handle failures from misc_register() and create_proc_read_entry() properly. Also it initializes static variable to 0 which increases the kernel size - silly.
c) wdt driver doesn't handle failures from request_irq(), request_region(), misc_register() and register_reboot_notifier()
d) same fixes for wdt_pci as for wdt
e) BusLogic drivers initializes some stuff to 0 which is not needed
f) block_dev.c:block_write() can be optimized a tiny bit
g) inodes_stat doesn't need to be initialised to 0
h) init_procfs_fs() doesn't handle failures from kern_mount gracefully
i) kernel/signal.c contains a typo sigueue -> sigqueue
j) mem_map is initialized to NULL - unnecessary
k) all swapout functions in mm/vmscan.c can be optimized by removing 'mm' argument. This part was reviewed by Rick van Riel and approved.
l) if sk_cachep SLAB cache creation fails we must at least print a KERN_CRIT message to the console. I agree with Alan Cox that panic may be a bit over the top for this one...
Everything tested under 2.4.0-test8-pre6.
Regards, Tigran
diff -urN -X dontdiff linux/drivers/char/mem.c linux-2.4.0-test8-p6/drivers/char/mem.c --- linux/drivers/char/mem.c Sat Jun 24 12:44:26 2000 +++ linux-2.4.0-test8-p6/drivers/char/mem.c Thu Sep 7 02:52:41 2000 @@ -258,25 +258,27 @@ count -= read; } - kbuf = (char *)__get_free_page(GFP_KERNEL); - if (!kbuf) - return -ENOMEM; - while (count > 0) { - int len = count; + if (count > 0) { + kbuf = (char *)__get_free_page(GFP_KERNEL); + if (!kbuf) + return -ENOMEM; + while (count > 0) { + int len = count; - if (len > PAGE_SIZE) - len = PAGE_SIZE; - len = vread(kbuf, (char *)p, len); - if (len && copy_to_user(buf, kbuf, len)) { - free_page((unsigned long)kbuf); - return -EFAULT; + if (len > PAGE_SIZE) + len = PAGE_SIZE; + len = vread(kbuf, (char *)p, len); + if (len && copy_to_user(buf, kbuf, len)) { + free_page((unsigned long)kbuf); + return -EFAULT; + } + count -= len; + buf += len; + virtr += len; + p += len; } - count -= len; - buf += len; - virtr += len; - p += len; + free_page((unsigned long)kbuf); } - free_page((unsigned long)kbuf); *ppos = p; return virtr + read; } diff -urN -X dontdiff linux/drivers/char/nvram.c linux-2.4.0-test8-p6/drivers/char/nvram.c --- linux/drivers/char/nvram.c Thu Sep 7 02:03:52 2000 +++ linux-2.4.0-test8-p6/drivers/char/nvram.c Thu Sep 7 03:07:38 2000 @@ -109,7 +109,7 @@ extern spinlock_t rtc_lock; -static int nvram_open_cnt = 0; /* #times opened */ +static int nvram_open_cnt; /* #times opened */ static int nvram_open_mode; /* special open modes */ #define NVRAM_WRITE 1 /* opened for writing (exclusive) */ #define NVRAM_EXCL 2 /* opened with O_EXCL */ @@ -415,14 +415,29 @@ static int __init nvram_init(void) { + int ret; + /* First test whether the driver should init at all */ if (!CHECK_DRIVER_INIT()) return( -ENXIO ); - printk(KERN_INFO "Non-volatile memory driver v%s\n", NVRAM_VERSION ); - misc_register( &nvram_dev ); - create_proc_read_entry("driver/nvram",0,0,nvram_read_proc,NULL); - return( 0 ); + ret = misc_register( &nvram_dev ); + if (ret) { + printk(KERN_ERR "nvram: can't misc_register on minor=%d\n", NVRAM_MINOR); + goto out; + } + if (!create_proc_read_entry("driver/nvram",0,0,nvram_read_proc,NULL)) { + printk(KERN_ERR "nvram: can't create /proc/driver/nvram\n"); + ret = -ENOMEM; + goto outmisc; + } + ret = 0; + printk(KERN_INFO "Non-volatile memory driver v" NVRAM_VERSION "\n"); +out: + return( ret ); +outmisc: + misc_deregister( &nvram_dev ); + goto out; } static void __exit nvram_cleanup_module (void) diff -urN -X dontdiff linux/drivers/char/wdt.c linux-2.4.0-test8-p6/drivers/char/wdt.c --- linux/drivers/char/wdt.c Fri Jul 28 09:58:59 2000 +++ linux-2.4.0-test8-p6/drivers/char/wdt.c Thu Sep 7 04:00:04 2000 @@ -26,6 +26,7 @@ * Alan Cox : Cleaned up copy/user stuff * Tim Hockin : Added insmod parameters, comment cleanup * Parameterized timeout + * Tigran Aivazian : Restructured wdt_init() to handle failures */ #include <linux/config.h> @@ -49,7 +50,7 @@ #include <linux/reboot.h> #include <linux/init.h> -static int wdt_is_open=0; +static int wdt_is_open; /* * You must set these - there is no sane way to probe for this board. @@ -495,18 +496,53 @@ int __init wdt_init(void) { - printk(KERN_INFO "WDT500/501-P driver 0.07 at %X (Interrupt %d)\n", io,irq); - if(request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p", &wdt_miscdev)) - { - printk(KERN_ERR "IRQ %d is not free.\n", irq); - return -EIO; + int ret; + + ret = misc_register(&wdt_miscdev); + if (ret) { + printk(KERN_ERR "wdt: can't misc_register on minor=%d\n", WATCHDOG_MINOR); + goto out; } - misc_register(&wdt_miscdev); -#ifdef CONFIG_WDT_501 - misc_register(&temp_miscdev); -#endif - request_region(io, 8, "wdt501p"); - register_reboot_notifier(&wdt_notifier); - return 0; + ret = request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p", NULL); + if(ret) { + printk(KERN_ERR "wdt: IRQ %d is not free.\n", irq); + goto outmisc; + } + if (!request_region(io, 8, "wdt501p")) { + printk(KERN_ERR "wdt: IO %X is not free.\n", io); + ret = -EBUSY; + goto outirq; + } + ret = register_reboot_notifier(&wdt_notifier); + if(ret) { + printk(KERN_ERR "wdt: can't register reboot notifier (err=%d)\n", ret); + goto outreg; + } + +#ifdef CONFIG_WDT_501 + ret = misc_register(&temp_miscdev); + if (ret) { + printk(KERN_ERR "wdt: can't misc_register (temp) on minor=%d\n", TEMP_MINOR); + goto outrbt; + } +#endif + + ret = 0; + printk(KERN_INFO "WDT500/501-P driver 0.07 at %X (Interrupt %d)\n", io, irq); +out: + return ret; + +#ifdef CONFIG_WDT_501 +outrbt: + unregister_reboot_notifier(&wdt_notifier); +#endif + +outreg: + release_region(io,8); +outirq: + free_irq(irq, NULL); +outmisc: + misc_deregister(&wdt_miscdev); + goto out; } diff -urN -X dontdiff linux/drivers/char/wdt_pci.c linux-2.4.0-test8-p6/drivers/char/wdt_pci.c --- linux/drivers/char/wdt_pci.c Fri Jul 14 20:52:15 2000 +++ linux-2.4.0-test8-p6/drivers/char/wdt_pci.c Thu Sep 7 04:06:48 2000 @@ -29,6 +29,7 @@ * JP Nollmann : Added support for PCI wdt501p * Alan Cox : Split ISA and PCI cards into two drivers * Jeff Garzik : PCI cleanups + * Tigran Aivazian : Restructured wdtpci_init_one() to handle failures */ #include <linux/config.h> @@ -70,7 +71,7 @@ #define PCI_DEVICE_ID_WDG_CSM 0x22c0 #endif -static int wdt_is_open=0; +static int wdt_is_open; /* * You must set these - there is no sane way to probe for this board. @@ -499,6 +500,7 @@ const struct pci_device_id *ent) { static int dev_count = 0; + int ret = -EIO; dev_count++; if (dev_count > 1) { @@ -513,33 +515,53 @@ "(Interrupt %d)\n", io, irq); if (pci_enable_device (dev)) - goto err_out; + goto out; if (request_region (io, 16, "wdt-pci") == NULL) { printk (KERN_ERR PFX "I/O %d is not free.\n", io); - goto err_out; + goto out; } if (request_irq (irq, wdtpci_interrupt, SA_INTERRUPT | SA_SHIRQ, "wdt-pci", &wdtpci_miscdev)) { printk (KERN_ERR PFX "IRQ %d is not free.\n", irq); - goto err_out_free_res; + goto out_reg; } - misc_register (&wdtpci_miscdev); + ret = misc_register (&wdtpci_miscdev); + if (ret) { + printk (KERN_ERR PFX "can't misc_register on minor=%d\n", WATCHDOG_MINOR); + goto out_irq; + } + ret = register_reboot_notifier (&wdtpci_notifier); + if (ret) { + printk (KERN_ERR PFX "can't misc_register on minor=%d\n", WATCHDOG_MINOR); + goto out_misc; + } #ifdef CONFIG_WDT_501 - misc_register (&temp_miscdev); + ret = misc_register (&temp_miscdev); + if (ret) { + printk (KERN_ERR PFX "can't misc_register (temp) on minor=%d\n", TEMP_MINOR); + goto out_rbt; + } #endif - register_reboot_notifier (&wdtpci_notifier); + ret = 0; +out: + return ret; - return 0; - -err_out_free_res: +#ifdef CONFIG_WDT_501 +out_rbt: + unregister_reboot_notifier(&wdtpci_notifier); +#endif +out_misc: + misc_deregister(&wdtpci_miscdev); +out_irq: + free_irq(irq, &wdtpci_miscdev); +out_reg: release_region (io, 16); -err_out: - return -EIO; + goto out; } diff -urN -X dontdiff linux/drivers/scsi/BusLogic.c linux-2.4.0-test8-p6/drivers/scsi/BusLogic.c --- linux/drivers/scsi/BusLogic.c Tue Jul 11 19:26:48 2000 +++ linux-2.4.0-test8-p6/drivers/scsi/BusLogic.c Thu Sep 7 02:56:03 2000 @@ -61,7 +61,7 @@ */ static int - BusLogic_DriverOptionsCount = 0; + BusLogic_DriverOptionsCount; /* @@ -79,7 +79,7 @@ */ #ifdef MODULE -static char *BusLogic = NULL; +static char *BusLogic; MODULE_PARM(BusLogic, "s"); #endif @@ -90,7 +90,7 @@ */ static BusLogic_ProbeOptions_T - BusLogic_ProbeOptions = { 0 }; + BusLogic_ProbeOptions; /* @@ -99,7 +99,7 @@ */ static BusLogic_GlobalOptions_T - BusLogic_GlobalOptions = { 0 }; + BusLogic_GlobalOptions; /* @@ -108,8 +108,8 @@ */ static BusLogic_HostAdapter_T - *BusLogic_FirstRegisteredHostAdapter = NULL, - *BusLogic_LastRegisteredHostAdapter = NULL; + *BusLogic_FirstRegisteredHostAdapter, + *BusLogic_LastRegisteredHostAdapter; /* @@ -117,7 +117,7 @@ */ static int - BusLogic_ProbeInfoCount = 0; + BusLogic_ProbeInfoCount; /* @@ -128,7 +128,7 @@ */ static BusLogic_ProbeInfo_T - *BusLogic_ProbeInfoList = NULL; + *BusLogic_ProbeInfoList; /* diff -urN -X dontdiff linux/fs/block_dev.c linux-2.4.0-test8-p6/fs/block_dev.c --- linux/fs/block_dev.c Thu Sep 7 02:03:53 2000 +++ linux-2.4.0-test8-p6/fs/block_dev.c Thu Sep 7 03:13:16 2000 @@ -30,17 +30,17 @@ ssize_t block, blocks; loff_t offset; ssize_t chars; - ssize_t written = 0; + ssize_t written; struct buffer_head * bhlist[NBUF]; size_t size; - kdev_t dev; + kdev_t dev = inode->i_rdev; struct buffer_head * bh, *bufferlist[NBUF]; register char * p; - write_error = buffercount = 0; - dev = inode->i_rdev; - if ( is_read_only( inode->i_rdev )) + if (is_read_only(dev)) return -EPERM; + + written = write_error = buffercount = 0; blocksize = BLOCK_SIZE; if (blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)]) blocksize = blksize_size[MAJOR(dev)][MINOR(dev)]; diff -urN -X dontdiff linux/fs/inode.c linux-2.4.0-test8-p6/fs/inode.c --- linux/fs/inode.c Thu Aug 24 08:08:46 2000 +++ linux-2.4.0-test8-p6/fs/inode.c Thu Sep 7 03:09:28 2000 @@ -71,7 +71,7 @@ int nr_inodes; int nr_unused; int dummy[5]; -} inodes_stat = {0, 0,}; +} inodes_stat; static kmem_cache_t * inode_cachep; diff -urN -X dontdiff linux/fs/proc/procfs_syms.c linux-2.4.0-test8-p6/fs/proc/procfs_syms.c --- linux/fs/proc/procfs_syms.c Sat May 13 09:32:35 2000 +++ linux-2.4.0-test8-p6/fs/proc/procfs_syms.c Thu Sep 7 02:50:47 2000 @@ -28,7 +28,9 @@ if (!err) { proc_mnt = kern_mount(&proc_fs_type); err = PTR_ERR(proc_mnt); - if (!IS_ERR(proc_mnt)) + if (IS_ERR(proc_mnt)) + unregister_filesystem(&proc_fs_type); + else err = 0; } return err; diff -urN -X dontdiff linux/kernel/signal.c linux-2.4.0-test8-p6/kernel/signal.c --- linux/kernel/signal.c Thu Sep 7 02:03:53 2000 +++ linux-2.4.0-test8-p6/kernel/signal.c Thu Sep 7 02:58:09 2000 @@ -41,7 +41,7 @@ __alignof__(struct sigqueue), SIG_SLAB_DEBUG, NULL, NULL); if (!sigqueue_cachep) - panic("signals_init(): cannot create sigueue SLAB cache"); + panic("signals_init(): cannot create sigqueue SLAB cache"); } diff -urN -X dontdiff linux/mm/memory.c linux-2.4.0-test8-p6/mm/memory.c --- linux/mm/memory.c Thu Sep 7 02:03:53 2000 +++ linux-2.4.0-test8-p6/mm/memory.c Thu Sep 7 02:47:43 2000 @@ -67,7 +67,7 @@ copy_user_highpage(to, from, address); } -mem_map_t * mem_map = NULL; +mem_map_t * mem_map; /* * Note: this doesn't free the actual pages themselves. That diff -urN -X dontdiff linux/mm/vmscan.c linux-2.4.0-test8-p6/mm/vmscan.c --- linux/mm/vmscan.c Thu Sep 7 02:03:53 2000 +++ linux-2.4.0-test8-p6/mm/vmscan.c Thu Sep 7 02:44:23 2000 @@ -34,11 +34,12 @@ * using a process that no longer actually exists (it might * have died while we slept). */ -static int try_to_swap_out(struct mm_struct * mm, struct vm_area_struct* vma, unsigned long address, pte_t * page_table, int gfp_mask) +static int try_to_swap_out(struct vm_area_struct* vma, unsigned long address, pte_t * page_table, int gfp_mask) { pte_t pte; swp_entry_t entry; struct page * page; + struct mm_struct * mm = vma->vm_mm; int (*swapout)(struct page *, struct file *); pte = *page_table; @@ -79,7 +80,7 @@ set_pte(page_table, swp_entry_to_pte(entry)); drop_pte: UnlockPage(page); - vma->vm_mm->rss--; + mm->rss--; flush_tlb_page(vma, address); page_cache_release(page); goto out_failed; @@ -144,9 +145,9 @@ struct file *file = vma->vm_file; if (file) get_file(file); pte_clear(page_table); - vma->vm_mm->rss--; + mm->rss--; flush_tlb_page(vma, address); - vmlist_access_unlock(vma->vm_mm); + vmlist_access_unlock(mm); error = swapout(page, file); UnlockPage(page); if (file) fput(file); @@ -175,10 +176,10 @@ add_to_swap_cache(page, entry); /* Put the swap entry into the pte after the page is in swapcache */ - vma->vm_mm->rss--; + mm->rss--; set_pte(page_table, swp_entry_to_pte(entry)); flush_tlb_page(vma, address); - vmlist_access_unlock(vma->vm_mm); + vmlist_access_unlock(mm); /* OK, do a physical asynchronous write to swap. */ rw_swap_page(WRITE, page, 0); @@ -209,10 +210,11 @@ * (C) 1993 Kai Petzke, wpp@marie.physik.tu-berlin.de */ -static inline int swap_out_pmd(struct mm_struct * mm, struct vm_area_struct * vma, pmd_t *dir, unsigned long address, unsigned long end, int gfp_mask) +static inline int swap_out_pmd(struct vm_area_struct * vma, pmd_t *dir, unsigned long address, unsigned long end, int gfp_mask) { pte_t * pte; unsigned long pmd_end; + struct mm_struct * mm = vma->vm_mm; if (pmd_none(*dir)) return 0; @@ -230,8 +232,8 @@ do { int result; - vma->vm_mm->swap_address = address + PAGE_SIZE; - result = try_to_swap_out(mm, vma, address, pte, gfp_mask); + mm->swap_address = address + PAGE_SIZE; + result = try_to_swap_out(vma, address, pte, gfp_mask); if (result) return result; if (!mm->swap_cnt) @@ -242,10 +244,11 @@ return 0; } -static inline int swap_out_pgd(struct mm_struct * mm, struct vm_area_struct * vma, pgd_t *dir, unsigned long address, unsigned long end, int gfp_mask) +static inline int swap_out_pgd(struct vm_area_struct * vma, pgd_t *dir, unsigned long address, unsigned long end, int gfp_mask) { pmd_t * pmd; unsigned long pgd_end; + struct mm_struct * mm = vma->vm_mm; if (pgd_none(*dir)) return 0; @@ -262,7 +265,7 @@ end = pgd_end; do { - int result = swap_out_pmd(mm, vma, pmd, address, end, gfp_mask); + int result = swap_out_pmd(vma, pmd, address, end, gfp_mask); if (result) return result; if (!mm->swap_cnt) @@ -273,22 +276,23 @@ return 0; } -static int swap_out_vma(struct mm_struct * mm, struct vm_area_struct * vma, unsigned long address, int gfp_mask) +static int swap_out_vma(struct vm_area_struct * vma, unsigned long address, int gfp_mask) { pgd_t *pgdir; unsigned long end; + struct mm_struct * mm = vma->vm_mm; /* Don't swap out areas which are locked down */ if (vma->vm_flags & VM_LOCKED) return 0; - pgdir = pgd_offset(vma->vm_mm, address); + pgdir = pgd_offset(mm, address); end = vma->vm_end; if (address >= end) BUG(); do { - int result = swap_out_pgd(mm, vma, pgdir, address, end, gfp_mask); + int result = swap_out_pgd(vma, pgdir, address, end, gfp_mask); if (result) return result; if (!mm->swap_cnt) @@ -302,7 +306,7 @@ static int swap_out_mm(struct mm_struct * mm, int gfp_mask) { unsigned long address; - struct vm_area_struct* vma; + struct vm_area_struct * vma; /* * Go through process' page directory. @@ -320,7 +324,7 @@ address = vma->vm_start; for (;;) { - int result = swap_out_vma(mm, vma, address, gfp_mask); + int result = swap_out_vma(vma, address, gfp_mask); if (result) return result; vma = vma->vm_next; diff -urN -X dontdiff linux/net/core/sock.c linux-2.4.0-test8-p6/net/core/sock.c --- linux/net/core/sock.c Thu Aug 24 08:08:47 2000 +++ linux-2.4.0-test8-p6/net/core/sock.c Thu Sep 7 02:46:51 2000 @@ -609,7 +609,9 @@ { sk_cachep = kmem_cache_create("sock", sizeof(struct sock), 0, SLAB_HWCACHE_ALIGN, 0, 0); - + if (!sk_cachep) + printk(KERN_CRIT "sk_init: Cannot create sock SLAB cache!"); + if (num_physpages <= 4096) { sysctl_wmem_max = 32767; sysctl_rmem_max = 32767;
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/
| |