From be7a02dd2b97c2ae3ee8892d8716a09ce7b8b04e Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sun, 29 Dec 2002 18:59:06 -0800 Subject: [PATCH] Fix MODULE_PARM for arrays of s. I interpreted "1-10s" to mean a string of 1-10 chars. It actually means 1-10 comma-separated strings. --- kernel/module.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) (limited to 'kernel') diff --git a/kernel/module.c b/kernel/module.c index 4b789cf97f5d..c33aac2d23b9 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -569,20 +569,6 @@ static int param_set_byte(const char *val, struct kernel_param *kp) return 0; } -static int param_string(const char *name, const char *val, - unsigned int min, unsigned int max, - char *dest) -{ - if (strlen(val) < min || strlen(val) > max) { - printk(KERN_ERR - "Parameter %s length must be %u-%u characters\n", - name, min, max); - return -EINVAL; - } - strcpy(dest, val); - return 0; -} - extern int set_obsolete(const char *val, struct kernel_param *kp) { unsigned int min, max; @@ -618,7 +604,8 @@ extern int set_obsolete(const char *val, struct kernel_param *kp) return param_array(kp->name, val, min, max, obsparm->addr, sizeof(long), param_set_long); case 's': - return param_string(kp->name, val, min, max, obsparm->addr); + return param_array(kp->name, val, min, max, obsparm->addr, + sizeof(char *), param_set_charp); } printk(KERN_ERR "Unknown obsolete parameter type %s\n", obsparm->type); return -EINVAL; -- cgit v1.2.3 From 2cea9523ee55d8bda0b14287d5761c956868572c Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sun, 29 Dec 2002 19:52:11 -0800 Subject: [PATCH] more obsolete module API fixes completly remove the old try_inc_mod_count() --- drivers/block/genhd.c | 4 ++-- drivers/char/busmouse.c | 2 +- drivers/ide/ide.c | 2 +- drivers/ieee1394/ieee1394_core.c | 3 +-- drivers/isdn/capi/capi.c | 11 ++--------- drivers/isdn/capi/kcapi.c | 12 +++--------- drivers/isdn/eicon/eicon_mod.c | 10 ---------- drivers/isdn/hardware/eicon/i4lididrv.c | 10 ---------- drivers/isdn/hisax/callc.c | 3 --- drivers/media/video/cpia.c | 2 +- drivers/mtd/chips/chipreg.c | 2 +- drivers/net/irda/sir_dev.c | 6 +----- drivers/net/irda/sir_dongle.c | 6 +++--- drivers/s390/block/dasd.c | 2 +- drivers/s390/block/dasd_ioctl.c | 11 ++++------- drivers/s390/char/tape_core.c | 2 +- drivers/serial/core.c | 2 +- fs/devfs/base.c | 2 +- fs/dquot.c | 2 +- fs/exec.c | 4 ++-- fs/filesystems.c | 10 +++++----- fs/nls/nls_base.c | 4 ++-- include/linux/fs.h | 10 ++-------- include/linux/module.h | 1 - include/linux/mtd/mtd.h | 5 +---- kernel/exec_domain.c | 4 ++-- kernel/intermodule.c | 2 +- net/core/dev.c | 2 +- net/ipv4/xfrm_policy.c | 2 +- net/rxrpc/krxsecd.c | 2 +- sound/core/control.c | 2 +- sound/core/info.c | 2 +- sound/core/init.c | 7 ++----- sound/core/oss/mixer_oss.c | 2 +- sound/core/oss/pcm_oss.c | 2 +- sound/core/pcm_native.c | 2 +- sound/core/rawmidi.c | 2 +- sound/core/seq/oss/seq_oss_synth.c | 2 +- sound/core/seq/seq_ports.c | 2 +- sound/core/seq/seq_virmidi.c | 4 ++-- sound/core/timer.c | 2 +- sound/drivers/opl3/opl3_seq.c | 2 +- sound/isa/gus/gus_main.c | 2 +- sound/isa/wavefront/wavefront_fx.c | 2 +- sound/isa/wavefront/wavefront_synth.c | 2 +- sound/synth/emux/emux_seq.c | 4 ++-- 46 files changed, 62 insertions(+), 119 deletions(-) (limited to 'kernel') diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c index c133b454b2fb..c7541b2fe264 100644 --- a/drivers/block/genhd.c +++ b/drivers/block/genhd.c @@ -160,7 +160,7 @@ retry: read_unlock(&gendisk_lock); return NULL; } - if (!try_inc_mod_count(p->owner)) + if (!try_module_get(p->owner)) continue; owner = p->owner; data = p->data; @@ -422,7 +422,7 @@ struct gendisk *get_disk(struct gendisk *disk) if (!disk->fops) return NULL; owner = disk->fops->owner; - if (owner && !try_inc_mod_count(owner)) + if (owner && !try_module_get(owner)) return NULL; return to_disk(kobject_get(&disk->kobj)); } diff --git a/drivers/char/busmouse.c b/drivers/char/busmouse.c index 85baa0cdf51b..c574177b5418 100644 --- a/drivers/char/busmouse.c +++ b/drivers/char/busmouse.c @@ -200,7 +200,7 @@ static int busmouse_open(struct inode *inode, struct file *file) if (!mse || !mse->ops) /* shouldn't happen, but... */ goto end; - if (mse->ops->owner && !try_inc_mod_count(mse->ops->owner)) + if (!try_module_get(mse->ops->owner)) goto end; ret = 0; diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 0ae396abfcc1..a138e13d6b44 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -1332,7 +1332,7 @@ int ata_attach(ide_drive_t *drive) spin_lock(&drivers_lock); list_for_each(p, &drivers) { ide_driver_t *driver = list_entry(p, ide_driver_t, drivers); - if (!try_inc_mod_count(driver->owner)) + if (!try_module_get(driver->owner)) continue; spin_unlock(&drivers_lock); if (driver->attach(drive) == 0) { diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c index b5e00b4b12b5..5433a0466ce9 100644 --- a/drivers/ieee1394/ieee1394_core.c +++ b/drivers/ieee1394/ieee1394_core.c @@ -1066,8 +1066,7 @@ static int ieee1394_get_chardev(int blocknum, if(*file_ops == NULL) goto out; - /* don't need try_inc_mod_count if the driver is non-modular */ - if(*module && (try_inc_mod_count(*module) == 0)) + if(!try_module_get(*module)) goto out; /* success! */ diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index ad595be2a0a6..4e01b76e1fcb 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -207,9 +207,7 @@ static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci) printk(KERN_ERR "capi: can't alloc capiminor\n"); return 0; } -#ifdef _DEBUG_REFCOUNT - printk(KERN_DEBUG "capiminor_alloc %d\n", GET_USE_COUNT(THIS_MODULE)); -#endif + memset(mp, 0, sizeof(struct capiminor)); mp->ap = ap; mp->ncci = ncci; @@ -252,9 +250,6 @@ static void capiminor_free(struct capiminor *mp) capiminor_del_all_ack(mp); kfree(mp); MOD_DEC_USE_COUNT; -#ifdef _DEBUG_REFCOUNT - printk(KERN_DEBUG "capiminor_free %d\n", GET_USE_COUNT(THIS_MODULE)); -#endif } struct capiminor *capiminor_find(unsigned int minor) @@ -980,9 +975,7 @@ static int capinc_tty_open(struct tty_struct * tty, struct file * file) return -ENXIO; tty->driver_data = (void *)mp; -#ifdef _DEBUG_REFCOUNT - printk(KERN_DEBUG "capi_tty_open %d\n", GET_USE_COUNT(THIS_MODULE)); -#endif + if (atomic_read(&mp->ttyopencount) == 0) mp->tty = tty; atomic_inc(&mp->ttyopencount); diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c index 337124784e9c..0e07e706a576 100644 --- a/drivers/isdn/capi/kcapi.c +++ b/drivers/isdn/capi/kcapi.c @@ -77,15 +77,9 @@ static struct work_struct tq_recv_notify; static inline struct capi_ctr * capi_ctr_get(struct capi_ctr *card) { - if (card->owner) { - if (try_inc_mod_count(card->owner)) { - DBG("MOD_COUNT INC"); - return card; - } else - return NULL; - } - DBG("MOD_COUNT INC"); - return card; + if (try_module_get(card->owner)) + return card; + return NULL; } static inline void diff --git a/drivers/isdn/eicon/eicon_mod.c b/drivers/isdn/eicon/eicon_mod.c index 54edc7d3f470..4fd7dbcb6968 100644 --- a/drivers/isdn/eicon/eicon_mod.c +++ b/drivers/isdn/eicon/eicon_mod.c @@ -54,10 +54,6 @@ extern int do_ioctl(struct inode *pDivasInode, struct file *pDivasFile, unsigned int command, unsigned long arg); extern void eicon_pci_init_conf(eicon_card *card); -#ifdef MODULE -#define MOD_USE_COUNT (GET_USE_COUNT (&__this_module)) -#endif - #define EICON_CTRL_VERSION 2 ulong DebugVar; @@ -370,12 +366,6 @@ eicon_command(eicon_card * card, isdn_ctrl * c) DebugVar = a; eicon_log(card, 1, "Eicon: Debug Value set to %ld\n", DebugVar); return 0; -#ifdef MODULE - case EICON_IOCTL_FREEIT: - while (MOD_USE_COUNT > 0) MOD_DEC_USE_COUNT; - MOD_INC_USE_COUNT; - return 0; -#endif case EICON_IOCTL_LOADPCI: eicon_log(card, 1, "Eicon: Wrong version of load-utility,\n"); eicon_log(card, 1, "Eicon: re-compile eiconctrl !\n"); diff --git a/drivers/isdn/hardware/eicon/i4lididrv.c b/drivers/isdn/hardware/eicon/i4lididrv.c index d086cdd17d00..38cf7c984607 100644 --- a/drivers/isdn/hardware/eicon/i4lididrv.c +++ b/drivers/isdn/hardware/eicon/i4lididrv.c @@ -40,10 +40,6 @@ static char *DRIVERRELEASE = "2.0"; static char *eicon_revision = "$Revision: 1.1.2.2 $"; extern char *eicon_idi_revision; -#ifdef MODULE -#define MOD_USE_COUNT (GET_USE_COUNT (&__this_module)) -#endif - #define EICON_CTRL_VERSION 2 ulong DebugVar; @@ -507,12 +503,6 @@ eicon_command(eicon_card * card, isdn_ctrl * c) DebugVar = a; eicon_log(card, 1, "%s: Debug Value set to %ld\n", DRIVERLNAME, DebugVar); return 0; -#ifdef MODULE - case EICON_IOCTL_FREEIT: - while (MOD_USE_COUNT > 0) MOD_DEC_USE_COUNT; - MOD_INC_USE_COUNT; - return 0; -#endif case EICON_IOCTL_LOADPCI: eicon_log(card, 1, "%s: Wrong version of load-utility,\n", DRIVERLNAME); eicon_log(card, 1, "%s: re-compile eiconctrl !\n", DRIVERLNAME); diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c index 4e366732644d..d2958c806c62 100644 --- a/drivers/isdn/hisax/callc.c +++ b/drivers/isdn/hisax/callc.c @@ -21,9 +21,6 @@ #include "hisax.h" #include -#ifdef MODULE -#define MOD_USE_COUNT ( GET_USE_COUNT (&__this_module)) -#endif /* MODULE */ const char *lli_revision = "$Revision: 2.51.6.6 $"; diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c index bcc26db53c6a..af042ec7b2ad 100644 --- a/drivers/media/video/cpia.c +++ b/drivers/media/video/cpia.c @@ -3173,7 +3173,7 @@ static int cpia_open(struct inode *inode, struct file *file) return -ENODEV; } - if (!try_inc_mod_count(cam->ops->owner)) + if (!try_module_get(cam->ops->owner)) return -ENODEV; down(&cam->busy_lock); diff --git a/drivers/mtd/chips/chipreg.c b/drivers/mtd/chips/chipreg.c index efdd7ee41d34..b33292c88be6 100644 --- a/drivers/mtd/chips/chipreg.c +++ b/drivers/mtd/chips/chipreg.c @@ -44,7 +44,7 @@ static struct mtd_chip_driver *get_mtd_chip_driver (char *name) break; } } - if (ret && !try_inc_mod_count(ret->module)) { + if (ret && !try_module_get(ret->module)) { /* Eep. Failed. */ ret = NULL; } diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c index a27737026547..09823085fa2d 100644 --- a/drivers/net/irda/sir_dev.c +++ b/drivers/net/irda/sir_dev.c @@ -466,13 +466,9 @@ static int sirdev_open(struct net_device *ndev) if (!drv) return -ENODEV; - lock_kernel(); /* serialize with rmmod */ /* increase the reference count of the driver module before doing serious stuff */ - if (drv->owner && !try_inc_mod_count(drv->owner)) { - unlock_kernel(); + if (!try_module_get(drv->owner)) return -ESTALE; - } - unlock_kernel(); IRDA_DEBUG(2, "%s()\n", __FUNCTION__); diff --git a/drivers/net/irda/sir_dongle.c b/drivers/net/irda/sir_dongle.c index cf7a17a002d3..b23cd3480519 100644 --- a/drivers/net/irda/sir_dongle.c +++ b/drivers/net/irda/sir_dongle.c @@ -95,13 +95,13 @@ int sirdev_get_dongle(struct sir_dev *dev, IRDA_DONGLE type) * 1) dongle driver was already unregistered - then we haven't found the * requested dongle above and are already out here * 2) the module is already marked deleted but the driver is still - * registered - then the try_inc_mod_count() below will fail - * 3) the try_inc_mod_count() below succeeds before the module is marked + * registered - then the try_module_get() below will fail + * 3) the try_module_get() below succeeds before the module is marked * deleted - then sys_delete_module() fails and prevents the removal * because the module is in use. */ - if (drv->owner && !try_inc_mod_count(drv->owner)) { + if (!try_module_get(drv->owner)) { err = -ESTALE; goto out_unlock; /* rmmod already pending */ } diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 8eedee623a04..5be431297f86 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -1734,7 +1734,7 @@ dasd_open(struct inode *inp, struct file *filp) rc = 0; if (atomic_inc_return(&device->open_count) == 1) { - if (!try_inc_mod_count(device->discipline->owner)) { + if (!try_module_get(device->discipline->owner)) { /* Discipline is currently unloaded! */ atomic_dec(&device->open_count); rc = -ENODEV; diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index 9047d68fb20a..e570db2497bd 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c @@ -111,13 +111,10 @@ dasd_ioctl(struct inode *inp, struct file *filp, ioctl = list_entry(l, dasd_ioctl_list_t, list); if (ioctl->no == no) { /* Found a matching ioctl. Call it. */ - if (ioctl->owner) { - if (try_inc_mod_count(ioctl->owner) != 0) - continue; - rc = ioctl->handler(bdev, no, data); - module_put(ioctl->owner); - } else - rc = ioctl->handler(bdev, no, data); + if (try_module_get(ioctl->owner) != 0) + continue; + rc = ioctl->handler(bdev, no, data); + module_put(ioctl->owner); return rc; } } diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index af71fadf2f52..7da7493a6a63 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -837,7 +837,7 @@ tape_open(struct tape_device *device) DBF_EVENT(6, "TAPE:dbusy\n"); rc = -EBUSY; } else if (device->discipline != NULL && - !try_inc_mod_count(device->discipline->owner)) { + !try_module_get(device->discipline->owner)) { DBF_EVENT(6, "TAPE:nodisc\n"); rc = -ENODEV; } else { diff --git a/drivers/serial/core.c b/drivers/serial/core.c index 39fe785bf275..22d42e3b18e9 100644 --- a/drivers/serial/core.c +++ b/drivers/serial/core.c @@ -1584,7 +1584,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp) * is about to be unloaded). Therefore, it is safe to set * tty->driver_data to be NULL, so uart_close() doesn't bite us. */ - if (!try_inc_mod_count(drv->owner)) { + if (!try_module_get(drv->owner)) { tty->driver_data = NULL; goto fail; } diff --git a/fs/devfs/base.c b/fs/devfs/base.c index 186dc63d327b..b4cbba51d30e 100644 --- a/fs/devfs/base.c +++ b/fs/devfs/base.c @@ -1874,7 +1874,7 @@ static struct file_operations *devfs_get_ops (devfs_handle_t de) return NULL; owner = ops->owner; read_lock (&de->parent->u.dir.lock); /* Prevent module from unloading */ - if ( (de->next == de) || !try_inc_mod_count (owner) ) + if ( (de->next == de) || !try_module_get (owner) ) { /* Entry is already unhooked or module is unloading */ read_unlock (&de->parent->u.dir.lock); return NULL; diff --git a/fs/dquot.c b/fs/dquot.c index 8781f7201a87..4d8ea00be1f9 100644 --- a/fs/dquot.c +++ b/fs/dquot.c @@ -103,7 +103,7 @@ static struct quota_format_type *find_quota_format(int id) lock_kernel(); for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id; actqf = actqf->qf_next); - if (actqf && !try_inc_mod_count(actqf->qf_owner)) + if (actqf && !try_module_get:(actqf->qf_owner)) actqf = NULL; unlock_kernel(); return actqf; diff --git a/fs/exec.c b/fs/exec.c index 901b8e12388f..8f0b41fd3a28 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -142,7 +142,7 @@ asmlinkage long sys_uselib(const char * library) for (fmt = formats ; fmt ; fmt = fmt->next) { if (!fmt->load_shlib) continue; - if (!try_inc_mod_count(fmt->module)) + if (!try_module_get(fmt->module)) continue; read_unlock(&binfmt_lock); error = fmt->load_shlib(file); @@ -971,7 +971,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary; if (!fn) continue; - if (!try_inc_mod_count(fmt->module)) + if (!try_module_get(fmt->module)) continue; read_unlock(&binfmt_lock); retval = fn(bprm, regs); diff --git a/fs/filesystems.c b/fs/filesystems.c index 223305689d30..824b04137c3a 100644 --- a/fs/filesystems.c +++ b/fs/filesystems.c @@ -20,7 +20,7 @@ * We can access the fields of list element if: * 1) spinlock is held or * 2) we hold the reference to the module. - * The latter can be guaranteed by call of try_inc_mod_count(); if it + * The latter can be guaranteed by call of try_module_get(); if it * returned 0 we must skip the element, otherwise we got the reference. * Once the reference is obtained we can drop the spinlock. */ @@ -153,8 +153,8 @@ static int fs_name(unsigned int index, char * buf) read_lock(&file_systems_lock); for (tmp = file_systems; tmp; tmp = tmp->next, index--) - if (index <= 0 && try_inc_mod_count(tmp->owner)) - break; + if (index <= 0 && try_module_get(tmp->owner)) + break; read_unlock(&file_systems_lock); if (!tmp) return -EINVAL; @@ -224,13 +224,13 @@ struct file_system_type *get_fs_type(const char *name) read_lock(&file_systems_lock); fs = *(find_filesystem(name)); - if (fs && !try_inc_mod_count(fs->owner)) + if (fs && !try_module_get(fs->owner)) fs = NULL; read_unlock(&file_systems_lock); if (!fs && (request_module(name) == 0)) { read_lock(&file_systems_lock); fs = *(find_filesystem(name)); - if (fs && !try_inc_mod_count(fs->owner)) + if (fs && !try_module_get(fs->owner)) fs = NULL; read_unlock(&file_systems_lock); } diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c index 3ea711688341..99c26613525c 100644 --- a/fs/nls/nls_base.c +++ b/fs/nls/nls_base.c @@ -205,9 +205,9 @@ static struct nls_table *find_nls(char *charset) struct nls_table *nls; spin_lock(&nls_lock); for (nls = tables; nls; nls = nls->next) - if (! strcmp(nls->charset, charset)) + if (!strcmp(nls->charset, charset)) break; - if (nls && !try_inc_mod_count(nls->owner)) + if (nls && !try_module_get(nls->owner)) nls = NULL; spin_unlock(&nls_lock); return nls; diff --git a/include/linux/fs.h b/include/linux/fs.h index 6c3188b991e6..3fa13b80747d 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -982,15 +982,9 @@ struct super_block *get_sb_pseudo(struct file_system_type *, char *, /* Alas, no aliases. Too much hassle with bringing module.h everywhere */ #define fops_get(fops) \ - (((fops) && (fops)->owner) \ - ? (try_inc_mod_count((fops)->owner) ? (fops) : NULL) \ - : (fops)) - + (((fops) && try_module_get((fops)->owner) ? (fops) : NULL)) #define fops_put(fops) \ -do { \ - if ((fops) && (fops)->owner) \ - module_put((fops)->owner); \ -} while(0) + do { if (fops) module_put((fops)->owner); } while(0) extern int register_filesystem(struct file_system_type *); extern int unregister_filesystem(struct file_system_type *); diff --git a/include/linux/module.h b/include/linux/module.h index ebdfc27efbb8..8e1954a89913 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -357,7 +357,6 @@ static inline void __deprecated _MOD_INC_USE_COUNT(struct module *module) _MOD_INC_USE_COUNT(THIS_MODULE) #define MOD_DEC_USE_COUNT \ __MOD_DEC_USE_COUNT(THIS_MODULE) -#define try_inc_mod_count(mod) try_module_get(mod) #define EXPORT_NO_SYMBOLS extern int module_dummy_usage; #define GET_USE_COUNT(module) (module_dummy_usage) diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 52d38241e91e..503a715fe014 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -215,10 +215,8 @@ static inline struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num) struct mtd_info *ret; ret = __get_mtd_device(mtd, num); - - if (ret && ret->module && !try_inc_mod_count(ret->module)) + if (ret && !try_module_get(ret->module)) return NULL; - return ret; } @@ -227,7 +225,6 @@ static inline void put_mtd_device(struct mtd_info *mtd) module_put(mtd->module); } - struct mtd_notifier { void (*add)(struct mtd_info *mtd); void (*remove)(struct mtd_info *mtd); diff --git a/kernel/exec_domain.c b/kernel/exec_domain.c index 162a5c23e606..5d53353d57b0 100644 --- a/kernel/exec_domain.c +++ b/kernel/exec_domain.c @@ -82,7 +82,7 @@ lookup_exec_domain(u_long personality) read_lock(&exec_domains_lock); for (ep = exec_domains; ep; ep = ep->next) { if (pers >= ep->pers_low && pers <= ep->pers_high) - if (try_inc_mod_count(ep->module)) + if (try_module_get(ep->module)) goto out; } @@ -97,7 +97,7 @@ lookup_exec_domain(u_long personality) for (ep = exec_domains; ep; ep = ep->next) { if (pers >= ep->pers_low && pers <= ep->pers_high) - if (try_inc_mod_count(ep->module)) + if (try_module_get(ep->module)) goto out; } #endif diff --git a/kernel/intermodule.c b/kernel/intermodule.c index 9228ca4fe035..5171df7d70fb 100644 --- a/kernel/intermodule.c +++ b/kernel/intermodule.c @@ -123,7 +123,7 @@ const void *inter_module_get(const char *im_name) list_for_each(tmp, &ime_list) { ime = list_entry(tmp, struct inter_module_entry, list); if (strcmp(ime->im_name, im_name) == 0) { - if (try_inc_mod_count(ime->owner)) + if (try_module_get(ime->owner)) result = ime->userdata; break; } diff --git a/net/core/dev.c b/net/core/dev.c index 97e772ff5f82..72f606980694 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -697,7 +697,7 @@ int dev_open(struct net_device *dev) /* * Call device private open method */ - if (try_inc_mod_count(dev->owner)) { + if (try_module_get(dev->owner)) { set_bit(__LINK_STATE_START, &dev->state); if (dev->open) { ret = dev->open(dev); diff --git a/net/ipv4/xfrm_policy.c b/net/ipv4/xfrm_policy.c index fe30556f78d6..f2c15d116118 100644 --- a/net/ipv4/xfrm_policy.c +++ b/net/ipv4/xfrm_policy.c @@ -192,7 +192,7 @@ struct xfrm_type *xfrm_get_type(u8 proto) read_lock(&xfrm_type_lock); type = xfrm_type_map[proto]; - if (type && !try_inc_mod_count(type->owner)) + if (type && !try_module_get(type->owner)) type = NULL; read_unlock(&xfrm_type_lock); return type; diff --git a/net/rxrpc/krxsecd.c b/net/rxrpc/krxsecd.c index 0e50f85416d6..4e35bd351412 100644 --- a/net/rxrpc/krxsecd.c +++ b/net/rxrpc/krxsecd.c @@ -233,7 +233,7 @@ void rxrpc_krxsecd_process_incoming_call(struct rxrpc_message *msg) spin_lock(&trans->lock); list_for_each(_p,&trans->services) { srv = list_entry(_p,struct rxrpc_service,link); - if (srv->service_id==sid && try_inc_mod_count(srv->owner)) { + if (srv->service_id==sid && try_module_get(srv->owner)) { /* found a match (made sure it won't vanish) */ _debug("found service '%s'",srv->name); call->owner = srv->owner; diff --git a/sound/core/control.c b/sound/core/control.c index 7de5256c19fc..85a0a656c5b8 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -61,7 +61,7 @@ static int snd_ctl_open(struct inode *inode, struct file *file) err = -ENODEV; goto __error1; } - if (!try_inc_mod_count(card->module)) { + if (!try_module_get(card->module)) { err = -EFAULT; goto __error2; } diff --git a/sound/core/info.c b/sound/core/info.c index 0ae2541810a6..45bf36503596 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -296,7 +296,7 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) #ifdef LINUX_2_2 MOD_INC_USE_COUNT; #endif - if (entry->module && !try_inc_mod_count(entry->module)) { + if (!try_module_get(entry->module)) { err = -EFAULT; goto __error1; } diff --git a/sound/core/init.c b/sound/core/init.c index 10768c6f2898..bc320cb1d2bd 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -294,17 +294,14 @@ static void snd_card_free_thread(void * __card) snd_card_t *card = __card; struct module * module; - if (!try_inc_mod_count(module = card->module)) { + if (!try_module_get(module = card->module)) { snd_printk(KERN_ERR "unable to lock toplevel module for card %i in free thread\n", card->number); module = NULL; } wait_event(card->shutdown_sleep, card->files == NULL); - snd_card_free(card); - - if (module) - __MOD_DEC_USE_COUNT(module); + module_put(module); } /** diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index 088bf5ea33c1..c4c6d4d3ff59 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c @@ -59,7 +59,7 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file) #ifdef LINUX_2_2 MOD_INC_USE_COUNT; #endif - if (!try_inc_mod_count(card->module)) { + if (!try_module_get(card->module)) { kfree(fmixer); #ifdef LINUX_2_2 MOD_DEC_USE_COUNT; diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 4febec2769c2..4c7d5c33f134 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -1551,7 +1551,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) err = snd_card_file_add(pcm->card, file); if (err < 0) goto __error1; - if (!try_inc_mod_count(pcm->card->module)) { + if (!try_module_get(pcm->card->module)) { err = -EFAULT; goto __error2; } diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 57f2a9c0f4a2..405fe698896e 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1791,7 +1791,7 @@ int snd_pcm_open(struct inode *inode, struct file *file) err = snd_card_file_add(pcm->card, file); if (err < 0) goto __error1; - if (!try_inc_mod_count(pcm->card->module)) { + if (!try_module_get(pcm->card->module)) { err = -EFAULT; goto __error2; } diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index a03924780f93..301445309d17 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -189,7 +189,7 @@ int snd_rawmidi_kernel_open(int cardnum, int device, int subdevice, err = -ENODEV; goto __error1; } - if (!try_inc_mod_count(rmidi->card->module)) { + if (!try_module_get(rmidi->card->module)) { err = -EFAULT; goto __error1; } diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c index 837ef15abb69..af140edbdead 100644 --- a/sound/core/seq/oss/seq_oss_synth.c +++ b/sound/core/seq/oss/seq_oss_synth.c @@ -234,7 +234,7 @@ snd_seq_oss_synth_setup(seq_oss_devinfo_t *dp) else info->arg.event_passing = SNDRV_SEQ_OSS_PASS_EVENTS; info->opened = 0; - if (!try_inc_mod_count(rec->oper.owner)) { + if (!try_module_get(rec->oper.owner)) { snd_use_lock_free(&rec->use_lock); continue; } diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c index 14943f8fecb8..d6654a1ab336 100644 --- a/sound/core/seq/seq_ports.c +++ b/sound/core/seq/seq_ports.c @@ -401,7 +401,7 @@ static int subscribe_port(client_t *client, client_port_t *port, port_subs_info_ { int err = 0; - if (!try_inc_mod_count(port->owner)) + if (!try_module_get(port->owner)) return -EFAULT; grp->count++; if (grp->open && (port->callback_all || grp->count == 1)) { diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c index 0719b6ad0ee8..c493a659d3f5 100644 --- a/sound/core/seq/seq_virmidi.c +++ b/sound/core/seq/seq_virmidi.c @@ -282,7 +282,7 @@ static int snd_virmidi_subscribe(void *private_data, snd_seq_port_subscribe_t *i snd_virmidi_dev_t *rdev; rdev = snd_magic_cast(snd_virmidi_dev_t, private_data, return -EINVAL); - if (!try_inc_mod_count(rdev->card->module)) + if (!try_module_get(rdev->card->module)) return -EFAULT; rdev->flags |= SNDRV_VIRMIDI_SUBSCRIBE; return 0; @@ -310,7 +310,7 @@ static int snd_virmidi_use(void *private_data, snd_seq_port_subscribe_t *info) snd_virmidi_dev_t *rdev; rdev = snd_magic_cast(snd_virmidi_dev_t, private_data, return -EINVAL); - if (!try_inc_mod_count(rdev->card->module)) + if (!try_module_get(rdev->card->module)) return -EFAULT; rdev->flags |= SNDRV_VIRMIDI_USE; return 0; diff --git a/sound/core/timer.c b/sound/core/timer.c index 1b571b00728d..b386bdeb48c8 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -102,7 +102,7 @@ static snd_timer_instance_t *snd_timer_instance_new(char *owner, snd_timer_t *ti timeri->in_use = (atomic_t)ATOMIC_INIT(0); timeri->timer = timer; - if (timer && timer->card && !try_inc_mod_count(timer->card->module)) { + if (timer && timer->card && !try_module_get(timer->card->module)) { kfree(timeri->owner); kfree(timeri); return NULL; diff --git a/sound/drivers/opl3/opl3_seq.c b/sound/drivers/opl3/opl3_seq.c index c622456c6136..c1f8429679f3 100644 --- a/sound/drivers/opl3/opl3_seq.c +++ b/sound/drivers/opl3/opl3_seq.c @@ -37,7 +37,7 @@ MODULE_PARM_DESC(use_internal_drums, "Enable internal OPL2/3 drums."); int snd_opl3_synth_use_inc(opl3_t * opl3) { - if (!try_inc_mod_count(opl3->card->module)) + if (!try_module_get(opl3->card->module)) return -EFAULT; return 0; diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c index a3473afd0118..7a9adec95248 100644 --- a/sound/isa/gus/gus_main.c +++ b/sound/isa/gus/gus_main.c @@ -42,7 +42,7 @@ static int snd_gus_init_dma_irq(snd_gus_card_t * gus, int latches); int snd_gus_use_inc(snd_gus_card_t * gus) { MOD_INC_USE_COUNT; - if (!try_inc_mod_count(gus->card->module)) { + if (!try_module_get(gus->card->module)) { MOD_DEC_USE_COUNT; return 0; } diff --git a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c index 817b6d807a86..a9de8cb5dff2 100644 --- a/sound/isa/wavefront/wavefront_fx.c +++ b/sound/isa/wavefront/wavefront_fx.c @@ -145,7 +145,7 @@ snd_wavefront_fx_open (snd_hwdep_t *hw, struct file *file) { MOD_INC_USE_COUNT; - if (!try_inc_mod_count(hw->card->module)) { + if (!try_module_get(hw->card->module)) { MOD_DEC_USE_COUNT; return -EFAULT; } diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c index f3e26ef9473f..88b88d23c3fd 100644 --- a/sound/isa/wavefront/wavefront_synth.c +++ b/sound/isa/wavefront/wavefront_synth.c @@ -1604,7 +1604,7 @@ snd_wavefront_synth_open (snd_hwdep_t *hw, struct file *file) { MOD_INC_USE_COUNT; - if (!try_inc_mod_count(hw->card->module)) { + if (!try_module_get(hw->card->module)) { MOD_DEC_USE_COUNT; return -EFAULT; } diff --git a/sound/synth/emux/emux_seq.c b/sound/synth/emux/emux_seq.c index 0dd6ef8c376c..a06961482fa5 100644 --- a/sound/synth/emux/emux_seq.c +++ b/sound/synth/emux/emux_seq.c @@ -274,9 +274,9 @@ int snd_emux_inc_count(snd_emux_t *emu) { emu->used++; - if (!try_inc_mod_count(emu->ops.owner)) + if (!try_module_get(emu->ops.owner)) goto __error; - if (!try_inc_mod_count(emu->card->module)) { + if (!try_module_get(emu->card->module)) { module_put(emu->ops.owner); __error: emu->used--; -- cgit v1.2.3 From 105114880f3f0d4dfbf0621dc08000c764333d66 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sun, 29 Dec 2002 20:08:37 -0800 Subject: [PATCH] more module parameter parsing bugs We restore the ","s after parsing: if expect to keep pointers to this stuff, we must not do that. --- kernel/params.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/params.c b/kernel/params.c index 5c5e9b3c23fe..0e9938a6bf23 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -233,6 +233,7 @@ int param_array(const char *name, int ret; unsigned int count = 0; struct kernel_param kp; + char save; /* Get the name right for errors. */ kp.name = name; @@ -247,7 +248,6 @@ int param_array(const char *name, /* We expect a comma-separated list of values. */ do { int len; - char save; if (count > max) { printk(KERN_ERR "%s: can only take %i arguments\n", @@ -256,18 +256,17 @@ int param_array(const char *name, } len = strcspn(val, ","); - /* Temporarily nul-terminate and parse */ + /* nul-terminate and parse */ save = val[len]; ((char *)val)[len] = '\0'; ret = set(val, &kp); - ((char *)val)[len] = save; if (ret != 0) return ret; kp.arg += elemsize; val += len+1; count++; - } while (val[-1] == ','); + } while (save == ','); if (count < min) { printk(KERN_ERR "%s: needs at least %i arguments\n", -- cgit v1.2.3 From 123c66ee8147175762360e06188648fa7e6a15db Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 29 Dec 2002 20:29:16 -0800 Subject: [PATCH] cpufreq: deprecated usage of CPUFREQ_ALL_CPUS The usage of CPUFREQ_ALL_CPUS is deprecated. Only exception is cpufreq_set, which needs to iterate over all CPUS now. Also, remove some unneeded code. --- arch/i386/kernel/cpu/cpufreq/elanfreq.c | 2 +- arch/i386/kernel/cpu/cpufreq/longhaul.c | 2 +- arch/i386/kernel/cpu/cpufreq/powernow-k6.c | 2 +- arch/i386/kernel/cpu/cpufreq/speedstep.c | 2 +- include/linux/cpufreq.h | 11 ------ kernel/cpufreq.c | 54 +++++++++++------------------- 6 files changed, 24 insertions(+), 49 deletions(-) (limited to 'kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/elanfreq.c b/arch/i386/kernel/cpu/cpufreq/elanfreq.c index 2c751897ce36..2623e01b2d87 100644 --- a/arch/i386/kernel/cpu/cpufreq/elanfreq.c +++ b/arch/i386/kernel/cpu/cpufreq/elanfreq.c @@ -124,7 +124,7 @@ static void elanfreq_set_cpu_state (unsigned int state) { freqs.old = elanfreq_get_cpu_frequency(); freqs.new = elan_multiplier[state].clock; - freqs.cpu = CPUFREQ_ALL_CPUS; /* elanfreq.c is UP only driver */ + freqs.cpu = 0; /* elanfreq.c is UP only driver */ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c index 72395b13eb00..5936a37a291b 100644 --- a/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c @@ -315,7 +315,7 @@ static void longhaul_setstate (unsigned int clock_ratio_index, unsigned int newf freqs.old = longhaul_get_cpu_mult() * longhaul_get_cpu_fsb() * 100; freqs.new = clock_ratio[clock_ratio_index] * newfsb * 100; - freqs.cpu = CPUFREQ_ALL_CPUS; /* longhaul.c is UP only driver */ + freqs.cpu = 0; /* longhaul.c is UP only driver */ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k6.c b/arch/i386/kernel/cpu/cpufreq/powernow-k6.c index 8021e8a21590..8a3404123f44 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k6.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k6.c @@ -83,7 +83,7 @@ static void powernow_k6_set_state (unsigned int best_i) freqs.old = busfreq * powernow_k6_get_cpu_multiplier(); freqs.new = busfreq * clock_ratio[best_i]; - freqs.cpu = CPUFREQ_ALL_CPUS; /* powernow-k6.c is UP only driver */ + freqs.cpu = 0; /* powernow-k6.c is UP only driver */ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep.c b/arch/i386/kernel/cpu/cpufreq/speedstep.c index 227e726aa4bd..349f18b8d942 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep.c @@ -154,7 +154,7 @@ static void speedstep_set_state (unsigned int state, int notify) freqs.old = (oldstate == SPEEDSTEP_HIGH) ? speedstep_high_freq : speedstep_low_freq; freqs.new = (state == SPEEDSTEP_HIGH) ? speedstep_high_freq : speedstep_low_freq; - freqs.cpu = CPUFREQ_ALL_CPUS; /* speedstep.c is UP only driver */ + freqs.cpu = 0; /* speedstep.c is UP only driver */ if (notify) cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index e93501c7a0b8..542983a24130 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -103,14 +103,6 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div, u_int mu }; -/********************************************************************* - * DYNAMIC CPUFREQ INTERFACE * - *********************************************************************/ -#ifdef CONFIG_CPU_FREQ_DYNAMIC -/* TBD */ -#endif /* CONFIG_CPU_FREQ_DYNAMIC */ - - /********************************************************************* * CPUFREQ DRIVER INTERFACE * *********************************************************************/ @@ -122,9 +114,6 @@ struct cpufreq_driver { cpufreq_policy_t verify; cpufreq_policy_t setpolicy; struct cpufreq_policy *policy; -#ifdef CONFIG_CPU_FREQ_DYNAMIC - /* TBD */ -#endif /* 2.4. compatible API */ #ifdef CONFIG_CPU_FREQ_24_API unsigned int cpu_cur_freq[NR_CPUS]; diff --git a/kernel/cpufreq.c b/kernel/cpufreq.c index c8208fb2191a..5dff6da1a73f 100644 --- a/kernel/cpufreq.c +++ b/kernel/cpufreq.c @@ -365,7 +365,7 @@ int cpufreq_set(unsigned int freq, unsigned int cpu) { struct cpufreq_policy policy; down(&cpufreq_driver_sem); - if (!cpufreq_driver || !cpu_max_freq) { + if (!cpufreq_driver || !freq || (cpu > NR_CPUS)) { up(&cpufreq_driver_sem); return -EINVAL; } @@ -377,7 +377,20 @@ int cpufreq_set(unsigned int freq, unsigned int cpu) up(&cpufreq_driver_sem); - return cpufreq_set_policy(&policy); + if (policy.cpu == CPUFREQ_ALL_CPUS) + { + unsigned int i; + unsigned int ret = 0; + for (i=0; icpu == CPUFREQ_ALL_CPUS) { - for (i=0;ipolicy[i].min = policy->min; - cpufreq_driver->policy[i].max = policy->max; - cpufreq_driver->policy[i].policy = policy->policy; - } - } else { - cpufreq_driver->policy[policy->cpu].min = policy->min; - cpufreq_driver->policy[policy->cpu].max = policy->max; - cpufreq_driver->policy[policy->cpu].policy = policy->policy; - } + cpufreq_driver->policy[policy->cpu].min = policy->min; + cpufreq_driver->policy[policy->cpu].max = policy->max; + cpufreq_driver->policy[policy->cpu].policy = policy->policy; #ifdef CONFIG_CPU_FREQ_24_API - if (policy->cpu == CPUFREQ_ALL_CPUS) { - for (i=0;imax; - } else - cpu_cur_freq[policy->cpu] = policy->max; + cpu_cur_freq[policy->cpu] = policy->max; #endif ret = cpufreq_driver->setpolicy(policy); @@ -919,15 +919,6 @@ EXPORT_SYMBOL(cpufreq_set_policy); -/********************************************************************* - * DYNAMIC CPUFREQ SWITCHING * - *********************************************************************/ -#ifdef CONFIG_CPU_FREQ_DYNAMIC -/* TBD */ -#endif /* CONFIG_CPU_FREQ_DYNAMIC */ - - - /********************************************************************* * EXTERNALLY AFFECTING FREQUENCY CHANGES * *********************************************************************/ @@ -967,12 +958,7 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state) adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_POSTCHANGE, freqs); #ifdef CONFIG_CPU_FREQ_24_API - if (freqs->cpu == CPUFREQ_ALL_CPUS) { - int i; - for (i=0;inew; - } else - cpu_cur_freq[freqs->cpu] = freqs->new; + cpu_cur_freq[freqs->cpu] = freqs->new; #endif break; } -- cgit v1.2.3 From 09619fdbe8b07911722e2ed8894f193160cdd1a8 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sun, 29 Dec 2002 21:04:02 -0800 Subject: [PATCH] MODULE_PARM "c" support Turns out there was an undocumented "c" flag for MODULE_PARM. This implementation is a little ugly, but it works, and will do for compatibility (I haven't implemented such a two-dimensional array primitive, but the whole point of the module_parm et al is that they are extensible). --- kernel/module.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/module.c b/kernel/module.c index c73b19336f1e..bc940cfa7d3b 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -569,10 +569,19 @@ static int param_string(const char *name, const char *val, return 0; } +/* Bounds checking done below */ +static int obsparm_copy_string(const char *val, struct kernel_param *kp) +{ + strcpy(kp->arg, val); + return 0; +} + extern int set_obsolete(const char *val, struct kernel_param *kp) { unsigned int min, max; - char *p, *endp; + unsigned int size, maxsize; + char *endp; + const char *p; struct obsolete_modparm *obsparm = kp->arg; if (!val) { @@ -605,9 +614,30 @@ extern int set_obsolete(const char *val, struct kernel_param *kp) sizeof(long), param_set_long); case 's': return param_string(kp->name, val, min, max, obsparm->addr); + + case 'c': + /* Undocumented: 1-5c50 means 1-5 strings of up to 49 chars, + and the decl is "char xxx[5][50];" */ + p = endp+1; + maxsize = simple_strtol(p, &endp, 10); + /* We check lengths here (yes, this is a hack). */ + p = val; + while (p[size = strcspn(p, ",")]) { + if (size >= maxsize) + goto oversize; + p += size+1; + } + if (size >= maxsize) + goto oversize; + return param_array(kp->name, val, min, max, obsparm->addr, + maxsize, obsparm_copy_string); } printk(KERN_ERR "Unknown obsolete parameter type %s\n", obsparm->type); return -EINVAL; + oversize: + printk(KERN_ERR + "Parameter %s doesn't fit in %u chars.\n", kp->name, maxsize); + return -EINVAL; } static int obsolete_params(const char *name, -- cgit v1.2.3 From 29621f41b70cb609f46db52e2a92faca9e6186ea Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sun, 29 Dec 2002 21:40:37 -0800 Subject: [PATCH] kmalloc_percpu -- stripped down version Patch from Ravikiran G Thirumalai Creates a simple "kmalloc for each CPU" API. This will be used for net statistics, disk statistics, etc. (davem has acked the net patches which use this code). kmalloc_per_cpu() is available to modules, unlike the current static per-cpu infrastructure. --- include/linux/percpu.h | 61 +++++++++++++++++++++++++++++++++++++++++++ kernel/ksyms.c | 4 +++ mm/slab.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+) (limited to 'kernel') diff --git a/include/linux/percpu.h b/include/linux/percpu.h index a79d04de4fd5..74c3d9786874 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -1,10 +1,71 @@ #ifndef __LINUX_PERCPU_H #define __LINUX_PERCPU_H #include /* For preempt_disable() */ +#include /* For kmalloc_percpu() */ #include /* Must be an lvalue. */ #define get_cpu_var(var) (*({ preempt_disable(); &__get_cpu_var(var); })) #define put_cpu_var(var) preempt_enable() +#ifdef CONFIG_SMP + +struct percpu_data { + void *ptrs[NR_CPUS]; + void *blkp; +}; + +/* + * Use this to get to a cpu's version of the per-cpu object allocated using + * kmalloc_percpu. If you want to get "this cpu's version", maybe you want + * to use get_cpu_ptr... + */ +#define per_cpu_ptr(ptr, cpu) \ +({ \ + struct percpu_data *__p = (struct percpu_data *)~(unsigned long)(ptr); \ + (__typeof__(ptr))__p->ptrs[(cpu)]; \ +}) + +extern void *kmalloc_percpu(size_t size, int flags); +extern void kfree_percpu(const void *); +extern void kmalloc_percpu_init(void); + +#else /* CONFIG_SMP */ + +#define per_cpu_ptr(ptr, cpu) (ptr) + +static inline void *kmalloc_percpu(size_t size, int flags) +{ + return(kmalloc(size, flags)); +} +static inline void kfree_percpu(const void *ptr) +{ + kfree(ptr); +} +static inline void kmalloc_percpu_init(void) { } + +#endif /* CONFIG_SMP */ + +/* + * Use these with kmalloc_percpu. If + * 1. You want to operate on memory allocated by kmalloc_percpu (dereference + * and read/modify/write) AND + * 2. You want "this cpu's version" of the object AND + * 3. You want to do this safely since: + * a. On multiprocessors, you don't want to switch between cpus after + * you've read the current processor id due to preemption -- this would + * take away the implicit advantage to not have any kind of traditional + * serialization for per-cpu data + * b. On uniprocessors, you don't want another kernel thread messing + * up with the same per-cpu data due to preemption + * + * So, Use get_cpu_ptr to disable preemption and get pointer to the + * local cpu version of the per-cpu object. Use put_cpu_ptr to enable + * preemption. Operations on per-cpu data between get_ and put_ is + * then considered to be safe. And ofcourse, "Thou shalt not sleep between + * get_cpu_ptr and put_cpu_ptr" + */ +#define get_cpu_ptr(ptr) per_cpu_ptr(ptr, get_cpu()) +#define put_cpu_ptr(ptr) put_cpu() + #endif /* __LINUX_PERCPU_H */ diff --git a/kernel/ksyms.c b/kernel/ksyms.c index cd49778dd1f3..414ab402325e 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -98,6 +98,10 @@ EXPORT_SYMBOL(set_shrinker); EXPORT_SYMBOL(remove_shrinker); EXPORT_SYMBOL(kmalloc); EXPORT_SYMBOL(kfree); +#ifdef CONFIG_SMP +EXPORT_SYMBOL(kmalloc_percpu); +EXPORT_SYMBOL(kfree_percpu); +#endif EXPORT_SYMBOL(vfree); EXPORT_SYMBOL(__vmalloc); EXPORT_SYMBOL(vmalloc); diff --git a/mm/slab.c b/mm/slab.c index 0b30ca1afeaa..f196fcaac2cb 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -1826,6 +1826,54 @@ void * kmalloc (size_t size, int flags) return NULL; } +#ifdef CONFIG_SMP +/** + * kmalloc_percpu - allocate one copy of the object for every present + * cpu in the system. + * Objects should be dereferenced using per_cpu_ptr/get_cpu_ptr + * macros only. + * + * @size: how many bytes of memory are required. + * @flags: the type of memory to allocate. + * The @flags argument may be one of: + * + * %GFP_USER - Allocate memory on behalf of user. May sleep. + * + * %GFP_KERNEL - Allocate normal kernel ram. May sleep. + * + * %GFP_ATOMIC - Allocation will not sleep. Use inside interrupt handlers. + */ +void * +kmalloc_percpu(size_t size, int flags) +{ + int i; + struct percpu_data *pdata = kmalloc(sizeof (*pdata), flags); + + if (!pdata) + return NULL; + + for (i = 0; i < NR_CPUS; i++) { + if (!cpu_possible(i)) + continue; + pdata->ptrs[i] = kmalloc(size, flags); + if (!pdata->ptrs[i]) + goto unwind_oom; + } + + /* Catch derefs w/o wrappers */ + return (void *) (~(unsigned long) pdata); + +unwind_oom: + while (--i >= 0) { + if (!cpu_possible(i)) + continue; + kfree(pdata->ptrs[i]); + } + kfree(pdata); + return NULL; +} +#endif + /** * kmem_cache_free - Deallocate an object * @cachep: The cache the allocation was from. @@ -1864,6 +1912,28 @@ void kfree (const void *objp) local_irq_restore(flags); } +#ifdef CONFIG_SMP +/** + * kfree_percpu - free previously allocated percpu memory + * @objp: pointer returned by kmalloc_percpu. + * + * Don't free memory not originally allocated by kmalloc_percpu() + * The complemented objp is to check for that. + */ +void +kfree_percpu(const void *objp) +{ + int i; + struct percpu_data *p = (struct percpu_data *) (~(unsigned long) objp); + + for (i = 0; i < NR_CPUS; i++) { + if (!cpu_possible(i)) + continue; + kfree(p->ptrs[i]); + } +} +#endif + unsigned int kmem_cache_size(kmem_cache_t *cachep) { #if DEBUG -- cgit v1.2.3 From d83f033a39a4bbe52b6c1ffd14bd994e70f9b6fe Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sun, 29 Dec 2002 21:40:44 -0800 Subject: [PATCH] Don't cacheline-align vm_area_struct Some workloads (Oracle...) use a huge number of VMA's. They are currently a tidy 64 bytes in size, and padding them out to 128 on P4's is not worthwhile. --- include/linux/mm.h | 3 +++ kernel/fork.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/include/linux/mm.h b/include/linux/mm.h index df49cb472866..70177c796b12 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -41,6 +41,9 @@ extern int page_cluster; * per VM-area/task. A VM area is any part of the process virtual memory * space that has a special rule for the page-fault handlers (ie a shared * library, the executable area etc). + * + * This structure is exactly 64 bytes on ia32. Please think very, very hard + * before adding anything to it. */ struct vm_area_struct { struct mm_struct * vm_mm; /* The address space we belong to. */ diff --git a/kernel/fork.c b/kernel/fork.c index 6f7298827344..56f12f280dd3 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1078,7 +1078,7 @@ void __init proc_caches_init(void) vm_area_cachep = kmem_cache_create("vm_area_struct", sizeof(struct vm_area_struct), 0, - SLAB_HWCACHE_ALIGN, NULL, NULL); + 0, NULL, NULL); if(!vm_area_cachep) panic("vma_init: Cannot alloc vm_area_struct SLAB cache"); -- cgit v1.2.3 From 3e025d63795d492854c84a8ce655f4b1d4923a1a Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sun, 29 Dec 2002 21:40:51 -0800 Subject: [PATCH] remove task_struct.swappable Remove unused task_struct.swappable. --- include/linux/sched.h | 1 - kernel/fork.c | 2 -- 2 files changed, 3 deletions(-) (limited to 'kernel') diff --git a/include/linux/sched.h b/include/linux/sched.h index 7c3bbfc255ed..9545a1957089 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -343,7 +343,6 @@ struct task_struct { unsigned long start_time; /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */ unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap; - int swappable:1; /* process credentials */ uid_t uid,euid,suid,fsuid; gid_t gid,egid,sgid,fsgid; diff --git a/kernel/fork.c b/kernel/fork.c index 56f12f280dd3..60d6d54142c6 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -757,7 +757,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->thread_info->preempt_count = 1; #endif p->did_exec = 0; - p->swappable = 0; p->state = TASK_UNINTERRUPTIBLE; copy_flags(clone_flags, p); @@ -841,7 +840,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->parent_exec_id = p->self_exec_id; /* ok, now we should be set up.. */ - p->swappable = 1; if (clone_flags & CLONE_DETACHED) p->exit_signal = -1; else -- cgit v1.2.3 From a93e679a7d1ca9cd662520a79830fec88a9654ca Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sun, 29 Dec 2002 21:41:16 -0800 Subject: [PATCH] don't call console drivers on non-online CPUs George Anzinger identified the following problem: when a secondary CPU is coming up, it calls printk() before it is "online". It calls the console drivers before its per-cpu storage has been prepared. And the vga console driver does a mod_timer(). This CPU's timers have not yet been initialised; it is not clear why this doesn't oops - George thinks it is because virtual address zero is still accessible at that time. I believe the right way to fix this is to change printk so that a not-online CPU will not call the console drivers. Because printk should always be callable. If the CPU is not online the message is buffered, so the next caller to printk who is online will actually display it. ia64 has been doing exactly this for ages, so we can remove the arch_consoles_callable() hook and just open-code the cpu_online() test in printk. That fixes things up for the secondary CPUs. But this change causes a problem for the boot CPU: it is being marked online very late in boot, so the printk buffer is being displayed much later than we would like. I believe that the solution to this is to mark the boot CPU online much earlier. So in this patch we call the new arch-provided function smp_prepare_boot_cpu() immediately after the boot CPU's per-cpu areas are set up. Its mandate is to (at least) mark the boot CPU "online". The change has been reviewed by davem and rth. No comments were received from the other arch maintainers. --- arch/alpha/kernel/smp.c | 6 ++++++ arch/i386/kernel/smpboot.c | 11 ++++++----- arch/i386/mach-voyager/voyager_smp.c | 6 ++++++ arch/ia64/kernel/smpboot.c | 6 ++++++ arch/parisc/kernel/smp.c | 6 ++++++ arch/ppc/kernel/smp.c | 6 ++++++ arch/ppc64/kernel/smp.c | 6 ++++++ arch/s390/kernel/smp.c | 6 ++++++ arch/s390x/kernel/smp.c | 6 ++++++ arch/sparc64/kernel/smp.c | 6 ++++++ arch/um/kernel/smp.c | 5 +++++ arch/x86_64/kernel/smpboot.c | 6 ++++++ include/asm-ia64/system.h | 3 --- include/linux/smp.h | 10 +++++++++- init/main.c | 7 +++++++ kernel/printk.c | 16 ++++++++-------- 16 files changed, 95 insertions(+), 17 deletions(-) (limited to 'kernel') diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index a6ab21ca5bb8..148aaaf310f3 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c @@ -607,6 +607,12 @@ smp_prepare_cpus(unsigned int max_cpus) smp_boot_cpus(); } +void __devinit +smp_prepare_boot_cpu(void) +{ + set_bit(smp_processor_id(), &cpu_present_mask); +} + int __devinit __cpu_up(unsigned int cpu) { diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 7c08f768281c..b602e889879f 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -995,11 +995,6 @@ static void __init smp_boot_cpus(unsigned int max_cpus) printk("CPU%d: ", 0); print_cpu_info(&cpu_data[0]); - /* - * We have the boot CPU online for sure. - */ - set_bit(0, &cpu_online_map); - set_bit(0, &cpu_callout_map); boot_cpu_logical_apicid = logical_smp_processor_id(); map_cpu_to_boot_apicid(0, boot_cpu_apicid); @@ -1172,6 +1167,12 @@ void __init smp_prepare_cpus(unsigned int max_cpus) smp_boot_cpus(max_cpus); } +void __devinit smp_prepare_boot_cpu(void) +{ + set_bit(smp_processor_id(), &cpu_online_map); + set_bit(smp_processor_id(), &cpu_callout_map); +} + int __devinit __cpu_up(unsigned int cpu) { /* This only works at boot for x86. See "rewrite" above. */ diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c index 6875c8346171..a6355ae320fd 100644 --- a/arch/i386/mach-voyager/voyager_smp.c +++ b/arch/i386/mach-voyager/voyager_smp.c @@ -1942,6 +1942,12 @@ smp_prepare_cpus(unsigned int max_cpus) smp_boot_cpus(); } +void __devinit smp_prepare_boot_cpu(void) +{ + set_bit(smp_processor_id(), &cpu_online_map); + set_bit(smp_processor_id(), &cpu_callout_map); +} + int __devinit __cpu_up(unsigned int cpu) { diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index e1c9a5ead71b..6223825e0beb 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -506,6 +506,12 @@ smp_prepare_cpus (unsigned int max_cpus) } } +void __devinit smp_prepare_boot_cpu(void) +{ + set_bit(smp_processor_id(), &cpu_online_map); + set_bit(smp_processor_id(), &cpu_callin_map); +} + void smp_cpus_done (unsigned int dummy) { diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 50dd06819c85..7ea4390aed85 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -706,6 +706,12 @@ void __init smp_prepare_cpus(unsigned int max_cpus) smp_boot_cpus(); } +void __devinit smp_prepare_boot_cpu(void) +{ + set_bit(smp_processor_id(), &cpu_online_map); + set_bit(smp_processor_id(), &cpu_present_mask); +} + int __devinit __cpu_up(unsigned int cpu) { return cpu_online(cpu) ? 0 : -ENOSYS; diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c index 6a10bcbe7579..8b5270afcdba 100644 --- a/arch/ppc/kernel/smp.c +++ b/arch/ppc/kernel/smp.c @@ -351,6 +351,12 @@ void __init smp_prepare_cpus(unsigned int max_cpus) smp_ops->space_timers(num_cpus); } +void __devinit smp_prepare_boot_cpu(void) +{ + set_bit(smp_processor_id(), &cpu_online_map); + set_bit(smp_processor_id(), &cpu_possible_map); +} + int __init setup_profiling_timer(unsigned int multiplier) { return 0; diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c index 7db75666d205..eeae9cb81e58 100644 --- a/arch/ppc64/kernel/smp.c +++ b/arch/ppc64/kernel/smp.c @@ -604,6 +604,12 @@ void __init smp_prepare_cpus(unsigned int max_cpus) smp_space_timers(max_cpus); } +void __devinit smp_prepare_boot_cpu(void) +{ + set_bit(smp_processor_id(), &cpu_online_map); + /* FIXME: what about cpu_possible()? */ +} + int __devinit __cpu_up(unsigned int cpu) { struct pt_regs regs; diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index a9dc74a7ca5d..e02e5c8c47fe 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -572,6 +572,12 @@ void __init smp_prepare_cpus(unsigned int max_cpus) set_prefix((u32) lowcore_ptr[smp_processor_id()]); } +void __devinit smp_prepare_boot_cpu(void) +{ + set_bit(smp_processor_id(), &cpu_online_map); + set_bit(smp_processor_id(), &cpu_possible_map); +} + void smp_cpus_done(unsigned int max_cpus) { } diff --git a/arch/s390x/kernel/smp.c b/arch/s390x/kernel/smp.c index 11b0d8f1d24e..8abfde52cb9a 100644 --- a/arch/s390x/kernel/smp.c +++ b/arch/s390x/kernel/smp.c @@ -554,6 +554,12 @@ void __init smp_prepare_cpus(unsigned int max_cpus) set_prefix((u32)(u64) lowcore_ptr[smp_processor_id()]); } +void __devinit smp_prepare_boot_cpu(void) +{ + set_bit(smp_processor_id(), &cpu_online_map); + set_bit(smp_processor_id(), &cpu_possible_map); +} + void smp_cpus_done(unsigned int max_cpis) { } diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 64963cd4e949..52c390c34dd8 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -1246,6 +1246,12 @@ void __init smp_prepare_cpus(unsigned int max_cpus) smp_store_cpu_info(boot_cpu_id); } +void __devinit smp_prepare_boot_cpu(void) +{ + set_bit(smp_processor_id(), &cpu_online_map); + set_bit(smp_processor_id(), &phys_cpu_present_map); +} + int __devinit __cpu_up(unsigned int cpu) { int ret = smp_boot_one_cpu(cpu); diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c index 3503ed13f59a..ad740a718957 100644 --- a/arch/um/kernel/smp.c +++ b/arch/um/kernel/smp.c @@ -186,6 +186,11 @@ void smp_prepare_cpus(unsigned int maxcpus) } } +void __devinit smp_prepare_boot_cpu(void) +{ + set_bit(smp_processor_id(), &cpu_online_map); +} + int __cpu_up(unsigned int cpu) { set_bit(cpu, &smp_commenced_mask); diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index e7acfed4bf2a..a305c3916e64 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c @@ -962,6 +962,12 @@ void __init smp_prepare_cpus(unsigned int max_cpus) smp_boot_cpus(max_cpus); } +void __devinit smp_prepare_boot_cpu(void) +{ + set_bit(smp_processor_id(), &cpu_online_map); + set_bit(smp_processor_id(), &cpu_callout_map); +} + int __devinit __cpu_up(unsigned int cpu) { /* This only works at boot for x86. See "rewrite" above. */ diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h index d09f11cb14ec..e621c5c08b94 100644 --- a/include/asm-ia64/system.h +++ b/include/asm-ia64/system.h @@ -234,9 +234,6 @@ extern void ia64_load_extra (struct task_struct *task); #ifdef CONFIG_SMP -/* Return true if this CPU can call the console drivers in printk() */ -#define arch_consoles_callable() (cpu_online_map & (1UL << smp_processor_id())) - /* * In the SMP case, we save the fph state when context-switching * away from a thread that modified fph. This way, when the thread diff --git a/include/linux/smp.h b/include/linux/smp.h index 7a1e22b170c2..8243c6bec130 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -78,6 +78,13 @@ extern int register_cpu_notifier(struct notifier_block *nb); extern void unregister_cpu_notifier(struct notifier_block *nb); int cpu_up(unsigned int cpu); + +/* + * Mark the boot cpu "online" so that it can call console drivers in + * printk() and can access its per-cpu storage. + */ +void smp_prepare_boot_cpu(void); + #else /* !SMP */ /* @@ -94,7 +101,8 @@ static inline void smp_send_reschedule_all(void) { } #define cpu_online(cpu) ({ BUG_ON((cpu) != 0); 1; }) #define num_online_cpus() 1 #define num_booting_cpus() 1 -#define cpu_possible(cpu) ({ BUG_ON((cpu) != 0); 1; }) +#define cpu_possible(cpu) ({ BUG_ON((cpu) != 0); 1; }) +#define smp_prepare_boot_cpu() do {} while (0) struct notifier_block; diff --git a/init/main.c b/init/main.c index 6770292ed29a..b07fac4e9f02 100644 --- a/init/main.c +++ b/init/main.c @@ -377,6 +377,13 @@ asmlinkage void __init start_kernel(void) printk(linux_banner); setup_arch(&command_line); setup_per_cpu_areas(); + + /* + * Mark the boot cpu "online" so that it can call console drivers in + * printk() and can access its per-cpu storage. + */ + smp_prepare_boot_cpu(); + build_all_zonelists(); page_alloc_init(); printk("Kernel command line: %s\n", saved_command_line); diff --git a/kernel/printk.c b/kernel/printk.c index bb1bcb0d723f..ffe724fabc0e 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -27,6 +27,7 @@ #include /* For in_interrupt() */ #include #include +#include #include @@ -42,10 +43,6 @@ #define LOG_BUF_MASK (LOG_BUF_LEN-1) -#ifndef arch_consoles_callable -#define arch_consoles_callable() (1) -#endif - /* printk's without a loglevel use this.. */ #define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */ @@ -447,10 +444,12 @@ asmlinkage int printk(const char *fmt, ...) log_level_unknown = 1; } - if (!arch_consoles_callable()) { + if (!cpu_online(smp_processor_id())) { /* - * On some architectures, the consoles are not usable - * on secondary CPUs early in the boot process. + * Some console drivers may assume that per-cpu resources have + * been allocated. So don't allow them to be called by this + * CPU until it is officially up. We shouldn't be calling into + * random console drivers on a CPU which doesn't exist yet.. */ spin_unlock_irqrestore(&logbuf_lock, flags); goto out; @@ -638,7 +637,8 @@ void register_console(struct console * console) } if (console->flags & CON_PRINTBUFFER) { /* - * release_console_sem() will print out the buffered messages for us. + * release_console_sem() will print out the buffered messages + * for us. */ spin_lock_irqsave(&logbuf_lock, flags); con_start = log_start; -- cgit v1.2.3