From f5c3dd719d17750779c6ac72f4dd0b06d7702ca2 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Wed, 3 Aug 2011 16:18:39 +0200 Subject: Fix kernel-doc comment typo '@id' Signed-off-by: Paul Bolle Signed-off-by: Jiri Kosina --- lib/idr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/idr.c b/lib/idr.c index e15502e8b21e..e0abbc177e30 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -858,7 +858,7 @@ EXPORT_SYMBOL(ida_get_new_above); * and go back to the idr_pre_get() call. If the idr is full, it will * return %-ENOSPC. * - * @id returns a value in the range %0 ... %0x7fffffff. + * @p_id returns a value in the range %0 ... %0x7fffffff. */ int ida_get_new(struct ida *ida, int *p_id) { -- cgit From cbc4663552ee476f57933920d782222d94878e7e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 11 Aug 2011 14:36:21 -0400 Subject: dynamic_debug: Add __dynamic_dev_dbg Unlike dynamic_pr_debug, dynamic uses of dev_dbg can not currently add task_pid/KBUILD_MODNAME/__func__/__LINE__ to selected debug output. Add a new function similar to dynamic_pr_debug to optionally emit these prefixes. Cc: Aloisio Almeida Noticed-by: Aloisio Almeida Signed-off-by: Joe Perches Signed-off-by: Jason Baron Signed-off-by: Greg Kroah-Hartman --- lib/dynamic_debug.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'lib') diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 75ca78f3a8c9..63b6f95ac552 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -30,6 +30,7 @@ #include #include #include +#include extern struct _ddebug __start___verbose[]; extern struct _ddebug __stop___verbose[]; @@ -456,6 +457,43 @@ int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...) } EXPORT_SYMBOL(__dynamic_pr_debug); +int __dynamic_dev_dbg(struct _ddebug *descriptor, + const struct device *dev, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + int res; + + BUG_ON(!descriptor); + BUG_ON(!fmt); + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + res = printk(KERN_DEBUG); + if (descriptor->flags & _DPRINTK_FLAGS_INCL_TID) { + if (in_interrupt()) + res += printk(KERN_CONT " "); + else + res += printk(KERN_CONT "[%d] ", task_pid_vnr(current)); + } + if (descriptor->flags & _DPRINTK_FLAGS_INCL_MODNAME) + res += printk(KERN_CONT "%s:", descriptor->modname); + if (descriptor->flags & _DPRINTK_FLAGS_INCL_FUNCNAME) + res += printk(KERN_CONT "%s:", descriptor->function); + if (descriptor->flags & _DPRINTK_FLAGS_INCL_LINENO) + res += printk(KERN_CONT "%d ", descriptor->lineno); + + res += __dev_printk(KERN_CONT, dev, &vaf); + + va_end(args); + + return res; +} +EXPORT_SYMBOL(__dynamic_dev_dbg); + static __initdata char ddebug_setup_string[1024]; static __init int ddebug_setup_query(char *str) { -- cgit From 6c2140ee0ebf91258f93d3019922b5f520a18d88 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 11 Aug 2011 14:36:25 -0400 Subject: dynamic_debug: Consolidate prefix output to single routine Adding dynamic_dev_dbg duplicated prefix output. Consolidate that output to a single routine. Signed-off-by: Joe Perches Signed-off-by: Jason Baron Signed-off-by: Greg Kroah-Hartman --- lib/dynamic_debug.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) (limited to 'lib') diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 63b6f95ac552..37217090aacf 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -428,15 +428,10 @@ static int ddebug_exec_query(char *query_string) return 0; } -int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...) +static int dynamic_emit_prefix(const struct _ddebug *descriptor) { - va_list args; int res; - BUG_ON(!descriptor); - BUG_ON(!fmt); - - va_start(args, fmt); res = printk(KERN_DEBUG); if (descriptor->flags & _DPRINTK_FLAGS_INCL_TID) { if (in_interrupt()) @@ -450,7 +445,23 @@ int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...) res += printk(KERN_CONT "%s:", descriptor->function); if (descriptor->flags & _DPRINTK_FLAGS_INCL_LINENO) res += printk(KERN_CONT "%d ", descriptor->lineno); + + return res; +} + +int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...) +{ + va_list args; + int res; + + BUG_ON(!descriptor); + BUG_ON(!fmt); + + va_start(args, fmt); + + res = dynamic_emit_prefix(descriptor); res += vprintk(fmt, args); + va_end(args); return res; @@ -472,20 +483,7 @@ int __dynamic_dev_dbg(struct _ddebug *descriptor, vaf.fmt = fmt; vaf.va = &args; - res = printk(KERN_DEBUG); - if (descriptor->flags & _DPRINTK_FLAGS_INCL_TID) { - if (in_interrupt()) - res += printk(KERN_CONT " "); - else - res += printk(KERN_CONT "[%d] ", task_pid_vnr(current)); - } - if (descriptor->flags & _DPRINTK_FLAGS_INCL_MODNAME) - res += printk(KERN_CONT "%s:", descriptor->modname); - if (descriptor->flags & _DPRINTK_FLAGS_INCL_FUNCNAME) - res += printk(KERN_CONT "%s:", descriptor->function); - if (descriptor->flags & _DPRINTK_FLAGS_INCL_LINENO) - res += printk(KERN_CONT "%d ", descriptor->lineno); - + res = dynamic_emit_prefix(descriptor); res += __dev_printk(KERN_CONT, dev, &vaf); va_end(args); -- cgit From 5b2ebce4821c66dd33d15d076ee264b4eb86fea3 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 11 Aug 2011 14:36:29 -0400 Subject: dynamic_debug: Remove uses of KERN_CONT in dynamic_emit_prefix Multiple printks with KERN_CONT can be interleaved by other printks. Reduce the likelihood of that interleaving by consolidating multiple calls to printk. Signed-off-by: Joe Perches Signed-off-by: Jason Baron Signed-off-by: Greg Kroah-Hartman --- lib/dynamic_debug.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'lib') diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 37217090aacf..a3eb6ab074a6 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -430,23 +430,35 @@ static int ddebug_exec_query(char *query_string) static int dynamic_emit_prefix(const struct _ddebug *descriptor) { - int res; + char tid[sizeof(int) + sizeof(int)/2 + 4]; + char lineno[sizeof(int) + sizeof(int)/2]; - res = printk(KERN_DEBUG); if (descriptor->flags & _DPRINTK_FLAGS_INCL_TID) { if (in_interrupt()) - res += printk(KERN_CONT " "); + snprintf(tid, sizeof(tid), "%s", " "); else - res += printk(KERN_CONT "[%d] ", task_pid_vnr(current)); + snprintf(tid, sizeof(tid), "[%d] ", + task_pid_vnr(current)); + } else { + tid[0] = 0; } - if (descriptor->flags & _DPRINTK_FLAGS_INCL_MODNAME) - res += printk(KERN_CONT "%s:", descriptor->modname); - if (descriptor->flags & _DPRINTK_FLAGS_INCL_FUNCNAME) - res += printk(KERN_CONT "%s:", descriptor->function); - if (descriptor->flags & _DPRINTK_FLAGS_INCL_LINENO) - res += printk(KERN_CONT "%d ", descriptor->lineno); - return res; + if (descriptor->flags & _DPRINTK_FLAGS_INCL_LINENO) + snprintf(lineno, sizeof(lineno), "%d", descriptor->lineno); + else + lineno[0] = 0; + + return printk(KERN_DEBUG "%s%s%s%s%s%s", + tid, + (descriptor->flags & _DPRINTK_FLAGS_INCL_MODNAME) ? + descriptor->modname : "", + (descriptor->flags & _DPRINTK_FLAGS_INCL_MODNAME) ? + ":" : "", + (descriptor->flags & _DPRINTK_FLAGS_INCL_FUNCNAME) ? + descriptor->function : "", + (descriptor->flags & _DPRINTK_FLAGS_INCL_FUNCNAME) ? + ":" : "", + lineno); } int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...) -- cgit From 4ad275e5cb576fa4e3e12597cb81eed0d500416d Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 11 Aug 2011 14:36:33 -0400 Subject: dynamic_debug: Convert printks to pr_ Add pr_fmt(fmt) with __func__. Converts "ddebug:" prefix to "dynamic_debug:". Most likely the if (verbose) outputs could also be converted from pr_info to pr_debug. Signed-off-by: Joe Perches Signed-off-by: Jason Baron Signed-off-by: Greg Kroah-Hartman --- lib/dynamic_debug.c | 59 +++++++++++++++++++++++------------------------------ 1 file changed, 26 insertions(+), 33 deletions(-) (limited to 'lib') diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index a3eb6ab074a6..4fc03ddb05f2 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -10,6 +10,8 @@ * Copyright (C) 2011 Bart Van Assche. All Rights Reserved. */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__ + #include #include #include @@ -160,8 +162,7 @@ static void ddebug_change(const struct ddebug_query *query, else dp->enabled = 0; if (verbose) - printk(KERN_INFO - "ddebug: changed %s:%d [%s]%s %s\n", + pr_info("changed %s:%d [%s]%s %s\n", dp->filename, dp->lineno, dt->mod_name, dp->function, ddebug_describe_flags(dp, flagbuf, @@ -171,7 +172,7 @@ static void ddebug_change(const struct ddebug_query *query, mutex_unlock(&ddebug_lock); if (!nfound && verbose) - printk(KERN_INFO "ddebug: no matches for query\n"); + pr_info("no matches for query\n"); } /* @@ -216,10 +217,10 @@ static int ddebug_tokenize(char *buf, char *words[], int maxwords) if (verbose) { int i; - printk(KERN_INFO "%s: split into words:", __func__); + pr_info("split into words:"); for (i = 0 ; i < nwords ; i++) - printk(" \"%s\"", words[i]); - printk("\n"); + pr_cont(" \"%s\"", words[i]); + pr_cont("\n"); } return nwords; @@ -331,16 +332,15 @@ static int ddebug_parse_query(char *words[], int nwords, } } else { if (verbose) - printk(KERN_ERR "%s: unknown keyword \"%s\"\n", - __func__, words[i]); + pr_err("unknown keyword \"%s\"\n", words[i]); return -EINVAL; } } if (verbose) - printk(KERN_INFO "%s: q->function=\"%s\" q->filename=\"%s\" " - "q->module=\"%s\" q->format=\"%s\" q->lineno=%u-%u\n", - __func__, query->function, query->filename, + pr_info("q->function=\"%s\" q->filename=\"%s\" " + "q->module=\"%s\" q->format=\"%s\" q->lineno=%u-%u\n", + query->function, query->filename, query->module, query->format, query->first_lineno, query->last_lineno); @@ -369,7 +369,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, return -EINVAL; } if (verbose) - printk(KERN_INFO "%s: op='%c'\n", __func__, op); + pr_info("op='%c'\n", op); for ( ; *str ; ++str) { for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) { @@ -384,7 +384,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, if (flags == 0) return -EINVAL; if (verbose) - printk(KERN_INFO "%s: flags=0x%x\n", __func__, flags); + pr_info("flags=0x%x\n", flags); /* calculate final *flagsp, *maskp according to mask and op */ switch (op) { @@ -402,8 +402,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, break; } if (verbose) - printk(KERN_INFO "%s: *flagsp=0x%x *maskp=0x%x\n", - __func__, *flagsp, *maskp); + pr_info("*flagsp=0x%x *maskp=0x%x\n", *flagsp, *maskp); return 0; } @@ -508,7 +507,7 @@ static __initdata char ddebug_setup_string[1024]; static __init int ddebug_setup_query(char *str) { if (strlen(str) >= 1024) { - pr_warning("ddebug boot param string too large\n"); + pr_warn("ddebug boot param string too large\n"); return 0; } strcpy(ddebug_setup_string, str); @@ -536,8 +535,7 @@ static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf, return -EFAULT; tmpbuf[len] = '\0'; if (verbose) - printk(KERN_INFO "%s: read %d bytes from userspace\n", - __func__, (int)len); + pr_info("read %d bytes from userspace\n", (int)len); ret = ddebug_exec_query(tmpbuf); if (ret) @@ -600,8 +598,7 @@ static void *ddebug_proc_start(struct seq_file *m, loff_t *pos) int n = *pos; if (verbose) - printk(KERN_INFO "%s: called m=%p *pos=%lld\n", - __func__, m, (unsigned long long)*pos); + pr_info("called m=%p *pos=%lld\n", m, (unsigned long long)*pos); mutex_lock(&ddebug_lock); @@ -626,8 +623,8 @@ static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos) struct _ddebug *dp; if (verbose) - printk(KERN_INFO "%s: called m=%p p=%p *pos=%lld\n", - __func__, m, p, (unsigned long long)*pos); + pr_info("called m=%p p=%p *pos=%lld\n", + m, p, (unsigned long long)*pos); if (p == SEQ_START_TOKEN) dp = ddebug_iter_first(iter); @@ -650,8 +647,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p) char flagsbuf[8]; if (verbose) - printk(KERN_INFO "%s: called m=%p p=%p\n", - __func__, m, p); + pr_info("called m=%p p=%p\n", m, p); if (p == SEQ_START_TOKEN) { seq_puts(m, @@ -676,8 +672,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p) static void ddebug_proc_stop(struct seq_file *m, void *p) { if (verbose) - printk(KERN_INFO "%s: called m=%p p=%p\n", - __func__, m, p); + pr_info("called m=%p p=%p\n", m, p); mutex_unlock(&ddebug_lock); } @@ -700,7 +695,7 @@ static int ddebug_proc_open(struct inode *inode, struct file *file) int err; if (verbose) - printk(KERN_INFO "%s: called\n", __func__); + pr_info("called\n"); iter = kzalloc(sizeof(*iter), GFP_KERNEL); if (iter == NULL) @@ -752,8 +747,7 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n, mutex_unlock(&ddebug_lock); if (verbose) - printk(KERN_INFO "%u debug prints in module %s\n", - n, dt->mod_name); + pr_info("%u debug prints in module %s\n", n, dt->mod_name); return 0; } EXPORT_SYMBOL_GPL(ddebug_add_module); @@ -775,8 +769,7 @@ int ddebug_remove_module(const char *mod_name) int ret = -ENOENT; if (verbose) - printk(KERN_INFO "%s: removing module \"%s\"\n", - __func__, mod_name); + pr_info("removing module \"%s\"\n", mod_name); mutex_lock(&ddebug_lock); list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) { @@ -852,8 +845,8 @@ static int __init dynamic_debug_init(void) if (ddebug_setup_string[0] != '\0') { ret = ddebug_exec_query(ddebug_setup_string); if (ret) - pr_warning("Invalid ddebug boot param %s", - ddebug_setup_string); + pr_warn("Invalid ddebug boot param %s", + ddebug_setup_string); else pr_info("ddebug initialized with string %s", ddebug_setup_string); -- cgit From ffa10cb47a94c9b456c83301c8047e2a898dd409 Mon Sep 17 00:00:00 2001 From: Jason Baron Date: Thu, 11 Aug 2011 14:36:48 -0400 Subject: dynamic_debug: make netdev_dbg() call __netdev_printk() Previously, if dynamic debug was enabled netdev_dbg() was using dynamic_dev_dbg() to print out the underlying msg. Fix this by making sure netdev_dbg() uses __netdev_printk(). Cc: David S. Miller Signed-off-by: Jason Baron Signed-off-by: Greg Kroah-Hartman --- lib/dynamic_debug.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'lib') diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 4fc03ddb05f2..ee3b9ba625c5 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -33,6 +33,7 @@ #include #include #include +#include extern struct _ddebug __start___verbose[]; extern struct _ddebug __stop___verbose[]; @@ -503,6 +504,30 @@ int __dynamic_dev_dbg(struct _ddebug *descriptor, } EXPORT_SYMBOL(__dynamic_dev_dbg); +int __dynamic_netdev_dbg(struct _ddebug *descriptor, + const struct net_device *dev, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + int res; + + BUG_ON(!descriptor); + BUG_ON(!fmt); + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + res = dynamic_emit_prefix(descriptor); + res += __netdev_printk(KERN_CONT, dev, &vaf); + + va_end(args); + + return res; +} +EXPORT_SYMBOL(__dynamic_netdev_dbg); + static __initdata char ddebug_setup_string[1024]; static __init int ddebug_setup_query(char *str) { -- cgit From ebf4127cd677e9781b450e44dfaaa1cc595efcaa Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Mon, 22 Aug 2011 15:51:34 +0200 Subject: kobj_uevent: Ignore if some listeners cannot handle message kobject_uevent() uses a multicast socket and should ignore if one of listeners cannot handle messages or nobody is listening at all. Easily reproducible when a process in system is cloned with CLONE_NEWNET flag. (See also http://article.gmane.org/gmane.linux.kernel.device-mapper.dm-crypt/5256) Signed-off-by: Milan Broz Acked-by: Kay Sievers Cc: stable Signed-off-by: Greg Kroah-Hartman --- lib/kobject_uevent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index 70af0a7f97c0..ad72a03ce5e9 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c @@ -282,7 +282,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, kobj_bcast_filter, kobj); /* ENOBUFS should be handled in userspace */ - if (retval == -ENOBUFS) + if (retval == -ENOBUFS || retval == -ESRCH) retval = 0; } else retval = -ENOMEM; -- cgit From 52288b6646ee4b1f3b97b5b64e4e84652c2a9bbe Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Sun, 21 Aug 2011 20:02:13 -0700 Subject: lib: Kconfig.debug: Typo remove extra "it" The patch below removes an extra "it" in the comment. Signed-off-by: Justin P. Mattock Signed-off-by: Jiri Kosina --- lib/Kconfig.debug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index c0cb9c4bc46d..1b11409b5f5d 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -835,7 +835,7 @@ config DEBUG_CREDENTIALS # # Select this config option from the architecture Kconfig, if it -# it is preferred to always offer frame pointers as a config +# is preferred to always offer frame pointers as a config # option on the architecture (regardless of KERNEL_DEBUG): # config ARCH_WANT_FRAME_POINTERS -- cgit From c6a21d0b8d667f403bc6186ef215a504a26ab682 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 8 Aug 2011 15:13:54 -0400 Subject: dma-debug: hash_bucket_find needs to allow for offsets within an entry Summary: Users of the pci_dma_sync_single_* api allow users to sync address ranges within the range of a mapped entry (i.e. you can dma map address X to dma_addr_t A and then pci_dma_sync_single on dma_addr_t A+1. The dma-debug library however assume dma syncs will always occur using the base address of a mapped region, and uses that assumption to find entries in its hash table. Since thats often (but not always the case), the dma debug library can give us false errors about missing entries, which are reported as syncing of memory not allocated by the driver. This was noted in the cxgb3 driver as this error: WARNING: at lib/dma-debug.c:902 check_sync+0xdd/0x48c() Hardware name: To be filled by O.E.M. cxgb3 0000:01:00.0: DMA-API: device driver tries to sync DMA memory it has not allocated [device address=0x00000000fff97800] [size=1984 bytes] Modules linked in: autofs4 sunrpc cpufreq_ondemand acpi_cpufreq freq_table mperf ip6t_REJECT nf_conntrack_ipv6 ip6table_filter ip6_tables ipv6 uinput snd_hda_codec_intelhdmi snd_hda_codec_realtek snd_hda_intel snd_hda_codec snd_hwdep snd_seq snd_seq_device snd_pcm snd_timer e1000e snd soundcore r8169 cxgb3 iTCO_wdt snd_page_alloc mii shpchp i2c_i801 iTCO_vendor_support mdio microcode firewire_ohci firewire_core crc_itu_t ata_generic pata_acpi i915 drm_kms_helper drm i2c_algo_bit i2c_core video output [last unloaded: scsi_wait_scan] Pid: 1818, comm: ifconfig Not tainted 2.6.35-0.23.rc3.git6.fc14.x86_64 #1 Call Trace: [] warn_slowpath_common+0x85/0x9d [] warn_slowpath_fmt+0x46/0x48 [] ? check_sync+0x39/0x48c [] ? trace_hardirqs_on+0xd/0xf [] check_sync+0xdd/0x48c [] debug_dma_sync_single_for_device+0x3f/0x41 [] ? pci_map_page+0x84/0x97 [cxgb3] [] pci_dma_sync_single_for_device.clone.0+0x65/0x6e [cxgb3] [] refill_fl+0x305/0x30a [cxgb3] [] t3_sge_alloc_qset+0x6a7/0x821 [cxgb3] [] cxgb_up+0x4d0/0xe62 [cxgb3] [] ? __module_text_address+0x12/0x58 [] cxgb_open+0x3f/0x309 [cxgb3] [] __dev_open+0x8e/0xbc [] __dev_change_flags+0xbe/0x142 [] dev_change_flags+0x21/0x57 [] devinet_ioctl+0x29a/0x54b [] ? inode_has_perm+0xaa/0xce [] inet_ioctl+0x8f/0xa7 [] sock_do_ioctl+0x29/0x48 [] sock_ioctl+0x213/0x222 [] vfs_ioctl+0x32/0xa6 [] do_vfs_ioctl+0x47a/0x4b3 [] sys_ioctl+0x56/0x79 [] system_call_fastpath+0x16/0x1b ---[ end trace 69a4d4cc77b58004 ]--- (some edits by Joerg Roedel) Signed-off-by: Neil Horman Reported-by: Jay Fenalson CC: Divy LeRay CC: Stanislaw Gruszka CC: Joerg Roedel CC: Arnd Bergmann Signed-off-by: Joerg Roedel --- lib/dma-debug.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/dma-debug.c b/lib/dma-debug.c index db07bfd9298e..79700fa2dfc4 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c @@ -62,6 +62,8 @@ struct dma_debug_entry { #endif }; +typedef bool (*match_fn)(struct dma_debug_entry *, struct dma_debug_entry *); + struct hash_bucket { struct list_head list; spinlock_t lock; @@ -240,18 +242,37 @@ static void put_hash_bucket(struct hash_bucket *bucket, spin_unlock_irqrestore(&bucket->lock, __flags); } +static bool exact_match(struct dma_debug_entry *a, struct dma_debug_entry *b) +{ + return ((a->dev_addr == a->dev_addr) && + (a->dev == b->dev)) ? true : false; +} + +static bool containing_match(struct dma_debug_entry *a, + struct dma_debug_entry *b) +{ + if (a->dev != b->dev) + return false; + + if ((b->dev_addr <= a->dev_addr) && + ((b->dev_addr + b->size) >= (a->dev_addr + a->size))) + return true; + + return false; +} + /* * Search a given entry in the hash bucket list */ -static struct dma_debug_entry *hash_bucket_find(struct hash_bucket *bucket, - struct dma_debug_entry *ref) +static struct dma_debug_entry *__hash_bucket_find(struct hash_bucket *bucket, + struct dma_debug_entry *ref, + match_fn match) { struct dma_debug_entry *entry, *ret = NULL; int matches = 0, match_lvl, last_lvl = 0; list_for_each_entry(entry, &bucket->list, list) { - if ((entry->dev_addr != ref->dev_addr) || - (entry->dev != ref->dev)) + if (!match(ref, entry)) continue; /* @@ -293,6 +314,39 @@ static struct dma_debug_entry *hash_bucket_find(struct hash_bucket *bucket, return ret; } +static struct dma_debug_entry *bucket_find_exact(struct hash_bucket *bucket, + struct dma_debug_entry *ref) +{ + return __hash_bucket_find(bucket, ref, exact_match); +} + +static struct dma_debug_entry *bucket_find_contain(struct hash_bucket **bucket, + struct dma_debug_entry *ref, + unsigned long *flags) +{ + + unsigned int max_range = dma_get_max_seg_size(ref->dev); + struct dma_debug_entry *entry, index = *ref; + unsigned int range = 0; + + while (range <= max_range) { + entry = __hash_bucket_find(*bucket, &index, containing_match); + + if (entry) + return entry; + + /* + * Nothing found, go back a hash bucket + */ + put_hash_bucket(*bucket, flags); + range += (1 << HASH_FN_SHIFT); + index.dev_addr -= (1 << HASH_FN_SHIFT); + *bucket = get_hash_bucket(&index, flags); + } + + return NULL; +} + /* * Add an entry to a hash bucket */ @@ -802,7 +856,7 @@ static void check_unmap(struct dma_debug_entry *ref) } bucket = get_hash_bucket(ref, &flags); - entry = hash_bucket_find(bucket, ref); + entry = bucket_find_exact(bucket, ref); if (!entry) { err_printk(ref->dev, NULL, "DMA-API: device driver tries " @@ -902,7 +956,7 @@ static void check_sync(struct device *dev, bucket = get_hash_bucket(ref, &flags); - entry = hash_bucket_find(bucket, ref); + entry = bucket_find_contain(&bucket, ref, &flags); if (!entry) { err_printk(dev, NULL, "DMA-API: device driver tries " @@ -1060,7 +1114,7 @@ static int get_nr_mapped_entries(struct device *dev, int mapped_ents; bucket = get_hash_bucket(ref, &flags); - entry = hash_bucket_find(bucket, ref); + entry = bucket_find_exact(bucket, ref); mapped_ents = 0; if (entry) -- cgit From bd823821e68e5de6d680cbbf1c8654c9c36674e1 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 30 Aug 2011 15:17:03 +0200 Subject: bitops: Move find_next_bit.o from lib-y to obj-y If there are no builtin users of find_next_bit_le() and find_next_zero_bit_le(), these functions are not present in the kernel image, causing m68k allmodconfig to fail with: ERROR: "find_next_zero_bit_le" [fs/ufs/ufs.ko] undefined! ERROR: "find_next_bit_le" [fs/udf/udf.ko] undefined! ... This started to happen after commit 171d809df189 ("m68k: merge mmu and non-mmu bitops.h"), as m68k had its own inline versions before. commit 63e424c84429 ("arch: remove CONFIG_GENERIC_FIND_{NEXT_BIT, BIT_LE, LAST_BIT}") added find_last_bit.o to obj-y (so it's always included), but find_next_bit.o to lib-y (so it gets removed by the linker if there are no builtin users). Signed-off-by: Geert Uytterhoeven Cc: Akinobu Mita Cc: Greg Ungerer Cc: Andrew Morton Signed-off-by: Linus Torvalds --- lib/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/Makefile b/lib/Makefile index d5d175c8a6ca..3f5bc6d903e0 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -12,7 +12,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \ idr.o int_sqrt.o extable.o prio_tree.o \ sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \ proportions.o prio_heap.o ratelimit.o show_mem.o \ - is_single_threaded.o plist.o decompress.o find_next_bit.o + is_single_threaded.o plist.o decompress.o lib-$(CONFIG_MMU) += ioremap.o lib-$(CONFIG_SMP) += cpumask.o @@ -22,7 +22,7 @@ lib-y += kobject.o kref.o klist.o obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ string_helpers.o gcd.o lcm.o list_sort.o uuid.o flex_array.o \ - bsearch.o find_last_bit.o + bsearch.o find_last_bit.o find_next_bit.o obj-y += kstrtox.o obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o -- cgit From f032a450812f6c7edd532772cc7c48091bca9f27 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 25 Jul 2009 16:21:48 +0200 Subject: locking, percpu_counter: Annotate ::lock as raw The percpu_counter::lock can be taken in atomic context and therefore cannot be preempted on -rt - annotate it. In mainline this change documents the low level nature of the lock - otherwise there's no functional difference. Lockdep and Sparse checking will work as usual. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- lib/percpu_counter.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/lib/percpu_counter.c b/lib/percpu_counter.c index 28f2c33c6b53..f087105ed914 100644 --- a/lib/percpu_counter.c +++ b/lib/percpu_counter.c @@ -59,13 +59,13 @@ void percpu_counter_set(struct percpu_counter *fbc, s64 amount) { int cpu; - spin_lock(&fbc->lock); + raw_spin_lock(&fbc->lock); for_each_possible_cpu(cpu) { s32 *pcount = per_cpu_ptr(fbc->counters, cpu); *pcount = 0; } fbc->count = amount; - spin_unlock(&fbc->lock); + raw_spin_unlock(&fbc->lock); } EXPORT_SYMBOL(percpu_counter_set); @@ -76,10 +76,10 @@ void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch) preempt_disable(); count = __this_cpu_read(*fbc->counters) + amount; if (count >= batch || count <= -batch) { - spin_lock(&fbc->lock); + raw_spin_lock(&fbc->lock); fbc->count += count; __this_cpu_write(*fbc->counters, 0); - spin_unlock(&fbc->lock); + raw_spin_unlock(&fbc->lock); } else { __this_cpu_write(*fbc->counters, count); } @@ -96,13 +96,13 @@ s64 __percpu_counter_sum(struct percpu_counter *fbc) s64 ret; int cpu; - spin_lock(&fbc->lock); + raw_spin_lock(&fbc->lock); ret = fbc->count; for_each_online_cpu(cpu) { s32 *pcount = per_cpu_ptr(fbc->counters, cpu); ret += *pcount; } - spin_unlock(&fbc->lock); + raw_spin_unlock(&fbc->lock); return ret; } EXPORT_SYMBOL(__percpu_counter_sum); @@ -110,7 +110,7 @@ EXPORT_SYMBOL(__percpu_counter_sum); int __percpu_counter_init(struct percpu_counter *fbc, s64 amount, struct lock_class_key *key) { - spin_lock_init(&fbc->lock); + raw_spin_lock_init(&fbc->lock); lockdep_set_class(&fbc->lock, key); fbc->count = amount; fbc->counters = alloc_percpu(s32); @@ -173,11 +173,11 @@ static int __cpuinit percpu_counter_hotcpu_callback(struct notifier_block *nb, s32 *pcount; unsigned long flags; - spin_lock_irqsave(&fbc->lock, flags); + raw_spin_lock_irqsave(&fbc->lock, flags); pcount = per_cpu_ptr(fbc->counters, cpu); fbc->count += *pcount; *pcount = 0; - spin_unlock_irqrestore(&fbc->lock, flags); + raw_spin_unlock_irqrestore(&fbc->lock, flags); } mutex_unlock(&percpu_counters_lock); #endif -- cgit From 740969f91e950b64a18fdd0a25164cdee042abf0 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 25 Jul 2009 16:43:30 +0200 Subject: locking, lib/proportions: Annotate prop_local_percpu::lock as raw The prop_local_percpu::lock can be taken in atomic context and therefore cannot be preempted on -rt - annotate it. In mainline this change documents the low level nature of the lock - otherwise there's no functional difference. Lockdep and Sparse checking will work as usual. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- lib/proportions.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/proportions.c b/lib/proportions.c index d50746a79de2..05df84801b56 100644 --- a/lib/proportions.c +++ b/lib/proportions.c @@ -190,7 +190,7 @@ prop_adjust_shift(int *pl_shift, unsigned long *pl_period, int new_shift) int prop_local_init_percpu(struct prop_local_percpu *pl) { - spin_lock_init(&pl->lock); + raw_spin_lock_init(&pl->lock); pl->shift = 0; pl->period = 0; return percpu_counter_init(&pl->events, 0); @@ -226,7 +226,7 @@ void prop_norm_percpu(struct prop_global *pg, struct prop_local_percpu *pl) if (pl->period == global_period) return; - spin_lock_irqsave(&pl->lock, flags); + raw_spin_lock_irqsave(&pl->lock, flags); prop_adjust_shift(&pl->shift, &pl->period, pg->shift); /* @@ -247,7 +247,7 @@ void prop_norm_percpu(struct prop_global *pg, struct prop_local_percpu *pl) percpu_counter_set(&pl->events, 0); pl->period = global_period; - spin_unlock_irqrestore(&pl->lock, flags); + raw_spin_unlock_irqrestore(&pl->lock, flags); } /* @@ -324,7 +324,7 @@ void prop_fraction_percpu(struct prop_descriptor *pd, int prop_local_init_single(struct prop_local_single *pl) { - spin_lock_init(&pl->lock); + raw_spin_lock_init(&pl->lock); pl->shift = 0; pl->period = 0; pl->events = 0; @@ -356,7 +356,7 @@ void prop_norm_single(struct prop_global *pg, struct prop_local_single *pl) if (pl->period == global_period) return; - spin_lock_irqsave(&pl->lock, flags); + raw_spin_lock_irqsave(&pl->lock, flags); prop_adjust_shift(&pl->shift, &pl->period, pg->shift); /* * For each missed period, we half the local counter. @@ -367,7 +367,7 @@ void prop_norm_single(struct prop_global *pg, struct prop_local_single *pl) else pl->events = 0; pl->period = global_period; - spin_unlock_irqrestore(&pl->lock, flags); + raw_spin_unlock_irqrestore(&pl->lock, flags); } /* -- cgit From 07354eb1a74d1e1ece29f8bafe0b46e8c77a95ef Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 25 Jul 2009 17:50:36 +0200 Subject: locking, printk: Annotate logbuf_lock as raw The logbuf_lock lock can be taken in atomic context and therefore cannot be preempted on -rt - annotate it. In mainline this change documents the low level nature of the lock - otherwise there's no functional difference. Lockdep and Sparse checking will work as usual. Signed-off-by: Thomas Gleixner [ merged and fixed it ] Signed-off-by: Ingo Molnar --- lib/ratelimit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/ratelimit.c b/lib/ratelimit.c index 027a03f4c56d..c96d500577de 100644 --- a/lib/ratelimit.c +++ b/lib/ratelimit.c @@ -39,7 +39,7 @@ int ___ratelimit(struct ratelimit_state *rs, const char *func) * in addition to the one that will be printed by * the entity that is holding the lock already: */ - if (!spin_trylock_irqsave(&rs->lock, flags)) + if (!raw_spin_trylock_irqsave(&rs->lock, flags)) return 0; if (!rs->begin) @@ -60,7 +60,7 @@ int ___ratelimit(struct ratelimit_state *rs, const char *func) rs->missed++; ret = 0; } - spin_unlock_irqrestore(&rs->lock, flags); + raw_spin_unlock_irqrestore(&rs->lock, flags); return ret; } -- cgit From ddb6c9b58a19edcfac93ac670b066c836ff729f1 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 24 Feb 2010 09:54:54 +0100 Subject: locking, rwsem: Annotate inner lock as raw There is no reason to allow the lock protecting rwsems (the ownerless variant) to be preemptible on -rt. Convert it to raw. In mainline this change documents the low level nature of the lock - otherwise there's no functional difference. Lockdep and Sparse checking will work as usual. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- lib/rwsem-spinlock.c | 38 +++++++++++++++++++------------------- lib/rwsem.c | 14 +++++++------- 2 files changed, 26 insertions(+), 26 deletions(-) (limited to 'lib') diff --git a/lib/rwsem-spinlock.c b/lib/rwsem-spinlock.c index ffc9fc7f3b05..f2393c21fe85 100644 --- a/lib/rwsem-spinlock.c +++ b/lib/rwsem-spinlock.c @@ -22,9 +22,9 @@ int rwsem_is_locked(struct rw_semaphore *sem) int ret = 1; unsigned long flags; - if (spin_trylock_irqsave(&sem->wait_lock, flags)) { + if (raw_spin_trylock_irqsave(&sem->wait_lock, flags)) { ret = (sem->activity != 0); - spin_unlock_irqrestore(&sem->wait_lock, flags); + raw_spin_unlock_irqrestore(&sem->wait_lock, flags); } return ret; } @@ -44,7 +44,7 @@ void __init_rwsem(struct rw_semaphore *sem, const char *name, lockdep_init_map(&sem->dep_map, name, key, 0); #endif sem->activity = 0; - spin_lock_init(&sem->wait_lock); + raw_spin_lock_init(&sem->wait_lock); INIT_LIST_HEAD(&sem->wait_list); } EXPORT_SYMBOL(__init_rwsem); @@ -145,12 +145,12 @@ void __sched __down_read(struct rw_semaphore *sem) struct task_struct *tsk; unsigned long flags; - spin_lock_irqsave(&sem->wait_lock, flags); + raw_spin_lock_irqsave(&sem->wait_lock, flags); if (sem->activity >= 0 && list_empty(&sem->wait_list)) { /* granted */ sem->activity++; - spin_unlock_irqrestore(&sem->wait_lock, flags); + raw_spin_unlock_irqrestore(&sem->wait_lock, flags); goto out; } @@ -165,7 +165,7 @@ void __sched __down_read(struct rw_semaphore *sem) list_add_tail(&waiter.list, &sem->wait_list); /* we don't need to touch the semaphore struct anymore */ - spin_unlock_irqrestore(&sem->wait_lock, flags); + raw_spin_unlock_irqrestore(&sem->wait_lock, flags); /* wait to be given the lock */ for (;;) { @@ -189,7 +189,7 @@ int __down_read_trylock(struct rw_semaphore *sem) int ret = 0; - spin_lock_irqsave(&sem->wait_lock, flags); + raw_spin_lock_irqsave(&sem->wait_lock, flags); if (sem->activity >= 0 && list_empty(&sem->wait_list)) { /* granted */ @@ -197,7 +197,7 @@ int __down_read_trylock(struct rw_semaphore *sem) ret = 1; } - spin_unlock_irqrestore(&sem->wait_lock, flags); + raw_spin_unlock_irqrestore(&sem->wait_lock, flags); return ret; } @@ -212,12 +212,12 @@ void __sched __down_write_nested(struct rw_semaphore *sem, int subclass) struct task_struct *tsk; unsigned long flags; - spin_lock_irqsave(&sem->wait_lock, flags); + raw_spin_lock_irqsave(&sem->wait_lock, flags); if (sem->activity == 0 && list_empty(&sem->wait_list)) { /* granted */ sem->activity = -1; - spin_unlock_irqrestore(&sem->wait_lock, flags); + raw_spin_unlock_irqrestore(&sem->wait_lock, flags); goto out; } @@ -232,7 +232,7 @@ void __sched __down_write_nested(struct rw_semaphore *sem, int subclass) list_add_tail(&waiter.list, &sem->wait_list); /* we don't need to touch the semaphore struct anymore */ - spin_unlock_irqrestore(&sem->wait_lock, flags); + raw_spin_unlock_irqrestore(&sem->wait_lock, flags); /* wait to be given the lock */ for (;;) { @@ -260,7 +260,7 @@ int __down_write_trylock(struct rw_semaphore *sem) unsigned long flags; int ret = 0; - spin_lock_irqsave(&sem->wait_lock, flags); + raw_spin_lock_irqsave(&sem->wait_lock, flags); if (sem->activity == 0 && list_empty(&sem->wait_list)) { /* granted */ @@ -268,7 +268,7 @@ int __down_write_trylock(struct rw_semaphore *sem) ret = 1; } - spin_unlock_irqrestore(&sem->wait_lock, flags); + raw_spin_unlock_irqrestore(&sem->wait_lock, flags); return ret; } @@ -280,12 +280,12 @@ void __up_read(struct rw_semaphore *sem) { unsigned long flags; - spin_lock_irqsave(&sem->wait_lock, flags); + raw_spin_lock_irqsave(&sem->wait_lock, flags); if (--sem->activity == 0 && !list_empty(&sem->wait_list)) sem = __rwsem_wake_one_writer(sem); - spin_unlock_irqrestore(&sem->wait_lock, flags); + raw_spin_unlock_irqrestore(&sem->wait_lock, flags); } /* @@ -295,13 +295,13 @@ void __up_write(struct rw_semaphore *sem) { unsigned long flags; - spin_lock_irqsave(&sem->wait_lock, flags); + raw_spin_lock_irqsave(&sem->wait_lock, flags); sem->activity = 0; if (!list_empty(&sem->wait_list)) sem = __rwsem_do_wake(sem, 1); - spin_unlock_irqrestore(&sem->wait_lock, flags); + raw_spin_unlock_irqrestore(&sem->wait_lock, flags); } /* @@ -312,12 +312,12 @@ void __downgrade_write(struct rw_semaphore *sem) { unsigned long flags; - spin_lock_irqsave(&sem->wait_lock, flags); + raw_spin_lock_irqsave(&sem->wait_lock, flags); sem->activity = 1; if (!list_empty(&sem->wait_list)) sem = __rwsem_do_wake(sem, 0); - spin_unlock_irqrestore(&sem->wait_lock, flags); + raw_spin_unlock_irqrestore(&sem->wait_lock, flags); } diff --git a/lib/rwsem.c b/lib/rwsem.c index aa7c3052261f..410aa1189b13 100644 --- a/lib/rwsem.c +++ b/lib/rwsem.c @@ -22,7 +22,7 @@ void __init_rwsem(struct rw_semaphore *sem, const char *name, lockdep_init_map(&sem->dep_map, name, key, 0); #endif sem->count = RWSEM_UNLOCKED_VALUE; - spin_lock_init(&sem->wait_lock); + raw_spin_lock_init(&sem->wait_lock); INIT_LIST_HEAD(&sem->wait_list); } @@ -180,7 +180,7 @@ rwsem_down_failed_common(struct rw_semaphore *sem, set_task_state(tsk, TASK_UNINTERRUPTIBLE); /* set up my own style of waitqueue */ - spin_lock_irq(&sem->wait_lock); + raw_spin_lock_irq(&sem->wait_lock); waiter.task = tsk; waiter.flags = flags; get_task_struct(tsk); @@ -204,7 +204,7 @@ rwsem_down_failed_common(struct rw_semaphore *sem, adjustment == -RWSEM_ACTIVE_WRITE_BIAS) sem = __rwsem_do_wake(sem, RWSEM_WAKE_READ_OWNED); - spin_unlock_irq(&sem->wait_lock); + raw_spin_unlock_irq(&sem->wait_lock); /* wait to be given the lock */ for (;;) { @@ -245,13 +245,13 @@ struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem) { unsigned long flags; - spin_lock_irqsave(&sem->wait_lock, flags); + raw_spin_lock_irqsave(&sem->wait_lock, flags); /* do nothing if list empty */ if (!list_empty(&sem->wait_list)) sem = __rwsem_do_wake(sem, RWSEM_WAKE_ANY); - spin_unlock_irqrestore(&sem->wait_lock, flags); + raw_spin_unlock_irqrestore(&sem->wait_lock, flags); return sem; } @@ -265,13 +265,13 @@ struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem) { unsigned long flags; - spin_lock_irqsave(&sem->wait_lock, flags); + raw_spin_lock_irqsave(&sem->wait_lock, flags); /* do nothing if list empty */ if (!list_empty(&sem->wait_list)) sem = __rwsem_do_wake(sem, RWSEM_WAKE_READ_OWNED); - spin_unlock_irqrestore(&sem->wait_lock, flags); + raw_spin_unlock_irqrestore(&sem->wait_lock, flags); return sem; } -- cgit From f59ca05871a055a73f8e626f2d868f0da248e22c Mon Sep 17 00:00:00 2001 From: Shan Hai Date: Thu, 1 Sep 2011 11:32:03 +0800 Subject: locking, lib/atomic64: Annotate atomic64_lock::lock as raw The spinlock protected atomic64 operations must be irq safe as they are used in hard interrupt context and cannot be preempted on -rt: NIP [c068b218] rt_spin_lock_slowlock+0x78/0x3a8 LR [c068b1e0] rt_spin_lock_slowlock+0x40/0x3a8 Call Trace: [eb459b90] [c068b1e0] rt_spin_lock_slowlock+0x40/0x3a8 (unreliable) [eb459c20] [c068bdb0] rt_spin_lock+0x40/0x98 [eb459c40] [c03d2a14] atomic64_read+0x48/0x84 [eb459c60] [c001aaf4] perf_event_interrupt+0xec/0x28c [eb459d10] [c0010138] performance_monitor_exception+0x7c/0x150 [eb459d30] [c0014170] ret_from_except_full+0x0/0x4c So annotate it. In mainline this change documents the low level nature of the lock - otherwise there's no functional difference. Lockdep and Sparse checking will work as usual. Signed-off-by: Shan Hai Reviewed-by: Yong Zhang Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- lib/atomic64.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'lib') diff --git a/lib/atomic64.c b/lib/atomic64.c index e12ae0dd08a8..82b33134e141 100644 --- a/lib/atomic64.c +++ b/lib/atomic64.c @@ -29,7 +29,7 @@ * Ensure each lock is in a separate cacheline. */ static union { - spinlock_t lock; + raw_spinlock_t lock; char pad[L1_CACHE_BYTES]; } atomic64_lock[NR_LOCKS] __cacheline_aligned_in_smp; @@ -48,9 +48,9 @@ long long atomic64_read(const atomic64_t *v) spinlock_t *lock = lock_addr(v); long long val; - spin_lock_irqsave(lock, flags); + raw_spin_lock_irqsave(lock, flags); val = v->counter; - spin_unlock_irqrestore(lock, flags); + raw_spin_unlock_irqrestore(lock, flags); return val; } EXPORT_SYMBOL(atomic64_read); @@ -60,9 +60,9 @@ void atomic64_set(atomic64_t *v, long long i) unsigned long flags; spinlock_t *lock = lock_addr(v); - spin_lock_irqsave(lock, flags); + raw_spin_lock_irqsave(lock, flags); v->counter = i; - spin_unlock_irqrestore(lock, flags); + raw_spin_unlock_irqrestore(lock, flags); } EXPORT_SYMBOL(atomic64_set); @@ -71,9 +71,9 @@ void atomic64_add(long long a, atomic64_t *v) unsigned long flags; spinlock_t *lock = lock_addr(v); - spin_lock_irqsave(lock, flags); + raw_spin_lock_irqsave(lock, flags); v->counter += a; - spin_unlock_irqrestore(lock, flags); + raw_spin_unlock_irqrestore(lock, flags); } EXPORT_SYMBOL(atomic64_add); @@ -83,9 +83,9 @@ long long atomic64_add_return(long long a, atomic64_t *v) spinlock_t *lock = lock_addr(v); long long val; - spin_lock_irqsave(lock, flags); + raw_spin_lock_irqsave(lock, flags); val = v->counter += a; - spin_unlock_irqrestore(lock, flags); + raw_spin_unlock_irqrestore(lock, flags); return val; } EXPORT_SYMBOL(atomic64_add_return); @@ -95,9 +95,9 @@ void atomic64_sub(long long a, atomic64_t *v) unsigned long flags; spinlock_t *lock = lock_addr(v); - spin_lock_irqsave(lock, flags); + raw_spin_lock_irqsave(lock, flags); v->counter -= a; - spin_unlock_irqrestore(lock, flags); + raw_spin_unlock_irqrestore(lock, flags); } EXPORT_SYMBOL(atomic64_sub); @@ -107,9 +107,9 @@ long long atomic64_sub_return(long long a, atomic64_t *v) spinlock_t *lock = lock_addr(v); long long val; - spin_lock_irqsave(lock, flags); + raw_spin_lock_irqsave(lock, flags); val = v->counter -= a; - spin_unlock_irqrestore(lock, flags); + raw_spin_unlock_irqrestore(lock, flags); return val; } EXPORT_SYMBOL(atomic64_sub_return); @@ -120,11 +120,11 @@ long long atomic64_dec_if_positive(atomic64_t *v) spinlock_t *lock = lock_addr(v); long long val; - spin_lock_irqsave(lock, flags); + raw_spin_lock_irqsave(lock, flags); val = v->counter - 1; if (val >= 0) v->counter = val; - spin_unlock_irqrestore(lock, flags); + raw_spin_unlock_irqrestore(lock, flags); return val; } EXPORT_SYMBOL(atomic64_dec_if_positive); @@ -135,11 +135,11 @@ long long atomic64_cmpxchg(atomic64_t *v, long long o, long long n) spinlock_t *lock = lock_addr(v); long long val; - spin_lock_irqsave(lock, flags); + raw_spin_lock_irqsave(lock, flags); val = v->counter; if (val == o) v->counter = n; - spin_unlock_irqrestore(lock, flags); + raw_spin_unlock_irqrestore(lock, flags); return val; } EXPORT_SYMBOL(atomic64_cmpxchg); @@ -150,10 +150,10 @@ long long atomic64_xchg(atomic64_t *v, long long new) spinlock_t *lock = lock_addr(v); long long val; - spin_lock_irqsave(lock, flags); + raw_spin_lock_irqsave(lock, flags); val = v->counter; v->counter = new; - spin_unlock_irqrestore(lock, flags); + raw_spin_unlock_irqrestore(lock, flags); return val; } EXPORT_SYMBOL(atomic64_xchg); @@ -164,12 +164,12 @@ int atomic64_add_unless(atomic64_t *v, long long a, long long u) spinlock_t *lock = lock_addr(v); int ret = 0; - spin_lock_irqsave(lock, flags); + raw_spin_lock_irqsave(lock, flags); if (v->counter != u) { v->counter += a; ret = 1; } - spin_unlock_irqrestore(lock, flags); + raw_spin_unlock_irqrestore(lock, flags); return ret; } EXPORT_SYMBOL(atomic64_add_unless); @@ -179,7 +179,7 @@ static int init_atomic64_lock(void) int i; for (i = 0; i < NR_LOCKS; ++i) - spin_lock_init(&atomic64_lock[i].lock); + raw_spin_lock_init(&atomic64_lock[i].lock); return 0; } -- cgit From 003f6c9df54970d8b19578d195b3e2b398cdbde2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 9 Sep 2011 11:30:27 -0700 Subject: lib/sha1.c: quiet sparse noise about symbol not declared Include to pickup the declarations for sha_transform and sha_init to quite the sparse noise: warning: symbol 'sha_transform' was not declared. Should it be static? warning: symbol 'sha_init' was not declared. Should it be static? Signed-off-by: H Hartley Sweeten Acked-by: Mandeep Singh Baines Signed-off-by: Linus Torvalds --- lib/sha1.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/sha1.c b/lib/sha1.c index f33271dd00cb..1de509a159c8 100644 --- a/lib/sha1.c +++ b/lib/sha1.c @@ -8,6 +8,7 @@ #include #include #include +#include #include /* -- cgit From cb475de3d12df6912bc95048202ae8c280d4cad5 Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Wed, 14 Sep 2011 15:49:24 +0800 Subject: lib: atomic64: Change the type of local lock to raw_spinlock_t There are still some leftovers of commit f59ca058 [locking, lib/atomic64: Annotate atomic64_lock::lock as raw] [ tglx: Seems I picked the wrong version of that patch :( ] Signed-off-by: Yong Zhang Cc: Peter Zijlstra Cc: Shan Hai Cc: Stephen Rothwell Link: http://lkml.kernel.org/r/20110914074924.GA16096@zhy Signed-off-by: Thomas Gleixner --- lib/atomic64.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'lib') diff --git a/lib/atomic64.c b/lib/atomic64.c index 82b33134e141..3975470caf4f 100644 --- a/lib/atomic64.c +++ b/lib/atomic64.c @@ -33,7 +33,7 @@ static union { char pad[L1_CACHE_BYTES]; } atomic64_lock[NR_LOCKS] __cacheline_aligned_in_smp; -static inline spinlock_t *lock_addr(const atomic64_t *v) +static inline raw_spinlock_t *lock_addr(const atomic64_t *v) { unsigned long addr = (unsigned long) v; @@ -45,7 +45,7 @@ static inline spinlock_t *lock_addr(const atomic64_t *v) long long atomic64_read(const atomic64_t *v) { unsigned long flags; - spinlock_t *lock = lock_addr(v); + raw_spinlock_t *lock = lock_addr(v); long long val; raw_spin_lock_irqsave(lock, flags); @@ -58,7 +58,7 @@ EXPORT_SYMBOL(atomic64_read); void atomic64_set(atomic64_t *v, long long i) { unsigned long flags; - spinlock_t *lock = lock_addr(v); + raw_spinlock_t *lock = lock_addr(v); raw_spin_lock_irqsave(lock, flags); v->counter = i; @@ -69,7 +69,7 @@ EXPORT_SYMBOL(atomic64_set); void atomic64_add(long long a, atomic64_t *v) { unsigned long flags; - spinlock_t *lock = lock_addr(v); + raw_spinlock_t *lock = lock_addr(v); raw_spin_lock_irqsave(lock, flags); v->counter += a; @@ -80,7 +80,7 @@ EXPORT_SYMBOL(atomic64_add); long long atomic64_add_return(long long a, atomic64_t *v) { unsigned long flags; - spinlock_t *lock = lock_addr(v); + raw_spinlock_t *lock = lock_addr(v); long long val; raw_spin_lock_irqsave(lock, flags); @@ -93,7 +93,7 @@ EXPORT_SYMBOL(atomic64_add_return); void atomic64_sub(long long a, atomic64_t *v) { unsigned long flags; - spinlock_t *lock = lock_addr(v); + raw_spinlock_t *lock = lock_addr(v); raw_spin_lock_irqsave(lock, flags); v->counter -= a; @@ -104,7 +104,7 @@ EXPORT_SYMBOL(atomic64_sub); long long atomic64_sub_return(long long a, atomic64_t *v) { unsigned long flags; - spinlock_t *lock = lock_addr(v); + raw_spinlock_t *lock = lock_addr(v); long long val; raw_spin_lock_irqsave(lock, flags); @@ -117,7 +117,7 @@ EXPORT_SYMBOL(atomic64_sub_return); long long atomic64_dec_if_positive(atomic64_t *v) { unsigned long flags; - spinlock_t *lock = lock_addr(v); + raw_spinlock_t *lock = lock_addr(v); long long val; raw_spin_lock_irqsave(lock, flags); @@ -132,7 +132,7 @@ EXPORT_SYMBOL(atomic64_dec_if_positive); long long atomic64_cmpxchg(atomic64_t *v, long long o, long long n) { unsigned long flags; - spinlock_t *lock = lock_addr(v); + raw_spinlock_t *lock = lock_addr(v); long long val; raw_spin_lock_irqsave(lock, flags); @@ -147,7 +147,7 @@ EXPORT_SYMBOL(atomic64_cmpxchg); long long atomic64_xchg(atomic64_t *v, long long new) { unsigned long flags; - spinlock_t *lock = lock_addr(v); + raw_spinlock_t *lock = lock_addr(v); long long val; raw_spin_lock_irqsave(lock, flags); @@ -161,7 +161,7 @@ EXPORT_SYMBOL(atomic64_xchg); int atomic64_add_unless(atomic64_t *v, long long a, long long u) { unsigned long flags; - spinlock_t *lock = lock_addr(v); + raw_spinlock_t *lock = lock_addr(v); int ret = 0; raw_spin_lock_irqsave(lock, flags); -- cgit From e809ab01013dfd905004f7e367978141c5dfc49d Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Sun, 17 Apr 2011 04:08:48 +0000 Subject: Kconfig: Copyedit: DEBUG_SECTION_MISMATCH Signed-off-by: Michael Witten Signed-off-by: Jiri Kosina --- lib/Kconfig.debug | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'lib') diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 1b11409b5f5d..d0324986a3b0 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -117,31 +117,31 @@ config DEBUG_SECTION_MISMATCH help The section mismatch analysis checks if there are illegal references from one section to another section. - Linux will during link or during runtime drop some sections - and any use of code/data previously in these sections will + During linktime or runtime, some sections are dropped; + any use of code/data previously in these sections would most likely result in an oops. - In the code functions and variables are annotated with - __init, __devinit etc. (see full list in include/linux/init.h) + In the code, functions and variables are annotated with + __init, __devinit, etc. (see the full list in include/linux/init.h), which results in the code/data being placed in specific sections. - The section mismatch analysis is always done after a full - kernel build but enabling this option will in addition - do the following: - - Add the option -fno-inline-functions-called-once to gcc - When inlining a function annotated __init in a non-init - function we would lose the section information and thus + The section mismatch analysis is always performed after a full + kernel build, and enabling this option causes the following + additional steps to occur: + - Add the option -fno-inline-functions-called-once to gcc commands. + When inlining a function annotated with __init in a non-init + function, we would lose the section information and thus the analysis would not catch the illegal reference. - This option tells gcc to inline less but will also - result in a larger kernel. - - Run the section mismatch analysis for each module/built-in.o - When we run the section mismatch analysis on vmlinux.o we + This option tells gcc to inline less (but it does result in + a larger kernel). + - Run the section mismatch analysis for each module/built-in.o file. + When we run the section mismatch analysis on vmlinux.o, we lose valueble information about where the mismatch was introduced. Running the analysis for each module/built-in.o file - will tell where the mismatch happens much closer to the - source. The drawback is that we will report the same - mismatch at least twice. - - Enable verbose reporting from modpost to help solving - the section mismatches reported. + tells where the mismatch happens much closer to the + source. The drawback is that the same mismatch is + reported at least twice. + - Enable verbose reporting from modpost in order to help resolve + the section mismatches that are reported. config DEBUG_KERNEL bool "Kernel debugging" -- cgit From c9bab38f70414918d414a1672d908f6447880075 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 1 Aug 2011 22:50:19 +0200 Subject: Remove unneeded version.h include from lib/ This patch removes an unneeded include of linux/version.h from lib/dynamic_debug.c - identified by 'make versioncheck'. This is the only file in lib/ with this issue. Signed-off-by: Jesper Juhl Signed-off-by: Jiri Kosina --- lib/dynamic_debug.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib') diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 75ca78f3a8c9..79fc20b65e74 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include -- cgit From 9c1f8594df4814ebfd6822ca3c9444fb3445888d Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Wed, 21 Sep 2011 17:30:50 +0300 Subject: XZ: Fix incorrect XZ_BUF_ERROR xz_dec_run() could incorrectly return XZ_BUF_ERROR if all of the following was true: - The caller knows how many bytes of output to expect and only provides that much output space. - When the last output bytes are decoded, the caller-provided input buffer ends right before the LZMA2 end of payload marker. So LZMA2 won't provide more output anymore, but it won't know it yet and thus won't return XZ_STREAM_END yet. - A BCJ filter is in use and it hasn't left any unfiltered bytes in the temp buffer. This can happen with any BCJ filter, but in practice it's more likely with filters other than the x86 BCJ. This fixes where Squashfs thinks that a valid file system is corrupt. This also fixes a similar bug in single-call mode where the uncompressed size of a block using BCJ + LZMA2 was 0 bytes and caller provided no output space. Many empty .xz files don't contain any blocks and thus don't trigger this bug. This also tweaks a closely related detail: xz_dec_bcj_run() could call xz_dec_lzma2_run() to decode into temp buffer when it was known to be useless. This was harmless although it wasted a minuscule number of CPU cycles. Signed-off-by: Lasse Collin Cc: stable Signed-off-by: Linus Torvalds --- lib/xz/xz_dec_bcj.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/xz/xz_dec_bcj.c b/lib/xz/xz_dec_bcj.c index e51e2558ca9d..a768e6d28bbb 100644 --- a/lib/xz/xz_dec_bcj.c +++ b/lib/xz/xz_dec_bcj.c @@ -441,8 +441,12 @@ XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s, * next filter in the chain. Apply the BCJ filter on the new data * in the output buffer. If everything cannot be filtered, copy it * to temp and rewind the output buffer position accordingly. + * + * This needs to be always run when temp.size == 0 to handle a special + * case where the output buffer is full and the next filter has no + * more output coming but hasn't returned XZ_STREAM_END yet. */ - if (s->temp.size < b->out_size - b->out_pos) { + if (s->temp.size < b->out_size - b->out_pos || s->temp.size == 0) { out_start = b->out_pos; memcpy(b->out + b->out_pos, s->temp.buf, s->temp.size); b->out_pos += s->temp.size; @@ -465,16 +469,25 @@ XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s, s->temp.size = b->out_pos - out_start; b->out_pos -= s->temp.size; memcpy(s->temp.buf, b->out + b->out_pos, s->temp.size); + + /* + * If there wasn't enough input to the next filter to fill + * the output buffer with unfiltered data, there's no point + * to try decoding more data to temp. + */ + if (b->out_pos + s->temp.size < b->out_size) + return XZ_OK; } /* - * If we have unfiltered data in temp, try to fill by decoding more - * data from the next filter. Apply the BCJ filter on temp. Then we - * hopefully can fill the actual output buffer by copying filtered - * data from temp. A mix of filtered and unfiltered data may be left - * in temp; it will be taken care on the next call to this function. + * We have unfiltered data in temp. If the output buffer isn't full + * yet, try to fill the temp buffer by decoding more data from the + * next filter. Apply the BCJ filter on temp. Then we hopefully can + * fill the actual output buffer by copying filtered data from temp. + * A mix of filtered and unfiltered data may be left in temp; it will + * be taken care on the next call to this function. */ - if (s->temp.size > 0) { + if (b->out_pos < b->out_size) { /* Make b->out{,_pos,_size} temporarily point to s->temp. */ s->out = b->out; s->out_pos = b->out_pos; -- cgit From 89bace652cbfb78a2fd830025f8ea048d6eb3657 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 10 Jun 2011 14:12:21 +0000 Subject: ARM: always use ARM_UNWIND for thumb2 kernels Thumb2 kernels cannot be built with frame pointers, but can use the ARM_UNWIND feature for unwinding instead. This makes sure that all features that rely on unwinding includeing CONFIG_LATENCYTOP and FAULT_INJECTION_STACKTRACE_FILTER do not enable frame pointers when the unwinder is already selected, and we always build with the unwinder when we want a thumb2 kernel, to make sure we do not get the frame pointers instead. A different option would be to redefine the CONFIG_FRAME_POINTERS option on ARM to mean builing with either frame pointers or the unwinder, and then select which one to use based on the CPU architecture or another user option. That would still allow building thumb2 kernels without the unwinder but would also be more confusing. Signed-off-by: Arnd Bergmann --- lib/Kconfig.debug | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index c0cb9c4bc46d..103c171ce605 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -1081,7 +1081,7 @@ config FAULT_INJECTION_STACKTRACE_FILTER depends on FAULT_INJECTION_DEBUG_FS && STACKTRACE_SUPPORT depends on !X86_64 select STACKTRACE - select FRAME_POINTER if !PPC && !S390 && !MICROBLAZE + select FRAME_POINTER if !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND help Provide stacktrace filter for fault-injection capabilities @@ -1091,7 +1091,7 @@ config LATENCYTOP depends on DEBUG_KERNEL depends on STACKTRACE_SUPPORT depends on PROC_FS - select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE + select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND select KALLSYMS select KALLSYMS_ALL select STACKTRACE -- cgit From 1230db8e1543c0471dd165727d34647ab098cc1e Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Thu, 8 Sep 2011 14:00:42 +0800 Subject: llist: Make some llist functions inline Because llist code will be used in performance critical scheduler code path, make llist_add() and llist_del_all() inline to avoid function calling overhead and related 'glue' overhead. Signed-off-by: Huang Ying Acked-by: Mathieu Desnoyers Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1315461646-1379-2-git-send-email-ying.huang@intel.com Signed-off-by: Ingo Molnar --- lib/Kconfig | 3 --- lib/Makefile | 4 +--- lib/llist.c | 40 ---------------------------------------- 3 files changed, 1 insertion(+), 46 deletions(-) (limited to 'lib') diff --git a/lib/Kconfig b/lib/Kconfig index 6c695ff9caba..32f3e5ae2be5 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -276,7 +276,4 @@ config CORDIC so its calculations are in fixed point. Modules can select this when they require this function. Module will be called cordic. -config LLIST - bool - endmenu diff --git a/lib/Makefile b/lib/Makefile index 3f5bc6d903e0..a4da283f5dc0 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -22,7 +22,7 @@ lib-y += kobject.o kref.o klist.o obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ string_helpers.o gcd.o lcm.o list_sort.o uuid.o flex_array.o \ - bsearch.o find_last_bit.o find_next_bit.o + bsearch.o find_last_bit.o find_next_bit.o llist.o obj-y += kstrtox.o obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o @@ -115,8 +115,6 @@ obj-$(CONFIG_CPU_RMAP) += cpu_rmap.o obj-$(CONFIG_CORDIC) += cordic.o -obj-$(CONFIG_LLIST) += llist.o - hostprogs-y := gen_crc32table clean-files := crc32table.h diff --git a/lib/llist.c b/lib/llist.c index da445724fa1f..3e3fa9139c41 100644 --- a/lib/llist.c +++ b/lib/llist.c @@ -29,28 +29,6 @@ #include -/** - * llist_add - add a new entry - * @new: new entry to be added - * @head: the head for your lock-less list - */ -void llist_add(struct llist_node *new, struct llist_head *head) -{ - struct llist_node *entry, *old_entry; - -#ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG - BUG_ON(in_nmi()); -#endif - - entry = head->first; - do { - old_entry = entry; - new->next = entry; - cpu_relax(); - } while ((entry = cmpxchg(&head->first, old_entry, new)) != old_entry); -} -EXPORT_SYMBOL_GPL(llist_add); - /** * llist_add_batch - add several linked entries in batch * @new_first: first entry in batch to be added @@ -109,21 +87,3 @@ struct llist_node *llist_del_first(struct llist_head *head) return entry; } EXPORT_SYMBOL_GPL(llist_del_first); - -/** - * llist_del_all - delete all entries from lock-less list - * @head: the head of lock-less list to delete all entries - * - * If list is empty, return NULL, otherwise, delete all entries and - * return the pointer to the first entry. The order of entries - * deleted is from the newest to the oldest added one. - */ -struct llist_node *llist_del_all(struct llist_head *head) -{ -#ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG - BUG_ON(in_nmi()); -#endif - - return xchg(&head->first, NULL); -} -EXPORT_SYMBOL_GPL(llist_del_all); -- cgit From 2c30245c65e8ebc3080b75ce65572ab8140bad0b Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 4 Oct 2011 12:43:11 +0200 Subject: llist: Remove the platform-dependent NMI checks Remove the nmi() checks spread around the code. in_nmi() is not available on every architecture and it's a pretty obscure and ugly check in any case. Cc: Huang Ying Cc: Mathieu Desnoyers Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1315461646-1379-3-git-send-email-ying.huang@intel.com Signed-off-by: Ingo Molnar --- lib/llist.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'lib') diff --git a/lib/llist.c b/lib/llist.c index 3e3fa9139c41..b445f2c8596a 100644 --- a/lib/llist.c +++ b/lib/llist.c @@ -3,8 +3,8 @@ * * The basic atomic operation of this list is cmpxchg on long. On * architectures that don't have NMI-safe cmpxchg implementation, the - * list can NOT be used in NMI handler. So code uses the list in NMI - * handler should depend on CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG. + * list can NOT be used in NMI handlers. So code that uses the list in + * an NMI handler should depend on CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG. * * Copyright 2010,2011 Intel Corp. * Author: Huang Ying @@ -40,10 +40,6 @@ void llist_add_batch(struct llist_node *new_first, struct llist_node *new_last, { struct llist_node *entry, *old_entry; -#ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG - BUG_ON(in_nmi()); -#endif - entry = head->first; do { old_entry = entry; @@ -71,10 +67,6 @@ struct llist_node *llist_del_first(struct llist_head *head) { struct llist_node *entry, *old_entry, *next; -#ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG - BUG_ON(in_nmi()); -#endif - entry = head->first; do { if (entry == NULL) -- cgit From a3127336b71f6833d1483c856dce91fe558dc3a9 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Thu, 8 Sep 2011 14:00:44 +0800 Subject: llist: Move cpu_relax() to after the cmpxchg() If in llist_add()/etc. functions the first cmpxchg() call succeeds, it is not necessary to use cpu_relax() before the cmpxchg(). So cpu_relax() in a busy loop involving cmpxchg() should go after cmpxchg() instead of before that. This patch fixes this for all involved llist functions. Signed-off-by: Huang Ying Acked-by: Mathieu Desnoyers Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1315461646-1379-4-git-send-email-ying.huang@intel.com Signed-off-by: Ingo Molnar --- lib/llist.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/llist.c b/lib/llist.c index b445f2c8596a..6c69f1d14c4b 100644 --- a/lib/llist.c +++ b/lib/llist.c @@ -41,11 +41,14 @@ void llist_add_batch(struct llist_node *new_first, struct llist_node *new_last, struct llist_node *entry, *old_entry; entry = head->first; - do { + for (;;) { old_entry = entry; new_last->next = entry; + entry = cmpxchg(&head->first, old_entry, new_first); + if (entry == old_entry) + break; cpu_relax(); - } while ((entry = cmpxchg(&head->first, old_entry, new_first)) != old_entry); + } } EXPORT_SYMBOL_GPL(llist_add_batch); @@ -68,13 +71,16 @@ struct llist_node *llist_del_first(struct llist_head *head) struct llist_node *entry, *old_entry, *next; entry = head->first; - do { + for (;;) { if (entry == NULL) return NULL; old_entry = entry; next = entry->next; + entry = cmpxchg(&head->first, old_entry, next); + if (entry == old_entry) + break; cpu_relax(); - } while ((entry = cmpxchg(&head->first, old_entry, next)) != old_entry); + } return entry; } -- cgit From 781f7fd916fc77a862e20063ed3aeedf173234f9 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Thu, 8 Sep 2011 14:00:45 +0800 Subject: llist: Return whether list is empty before adding in llist_add() Extend the llist_add*() functions to return a success indicator, this allows us in the scheduler code to send an IPI if the queue was empty. ( There's no effect on existing users, because the list_add_xxx() functions are inline, thus this will be optimized out by the compiler if not used by callers. ) Signed-off-by: Huang Ying Cc: Mathieu Desnoyers Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1315461646-1379-5-git-send-email-ying.huang@intel.com Signed-off-by: Ingo Molnar --- lib/llist.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/llist.c b/lib/llist.c index 6c69f1d14c4b..878985c4d19d 100644 --- a/lib/llist.c +++ b/lib/llist.c @@ -34,8 +34,10 @@ * @new_first: first entry in batch to be added * @new_last: last entry in batch to be added * @head: the head for your lock-less list + * + * Return whether list is empty before adding. */ -void llist_add_batch(struct llist_node *new_first, struct llist_node *new_last, +bool llist_add_batch(struct llist_node *new_first, struct llist_node *new_last, struct llist_head *head) { struct llist_node *entry, *old_entry; @@ -49,6 +51,8 @@ void llist_add_batch(struct llist_node *new_first, struct llist_node *new_last, break; cpu_relax(); } + + return old_entry == NULL; } EXPORT_SYMBOL_GPL(llist_add_batch); -- cgit From f0f1d32f931b705c4ee5dd374074d34edf3eae14 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 12 Sep 2011 15:50:49 +0200 Subject: llist: Remove cpu_relax() usage in cmpxchg loops Initial benchmarks show they're a net loss: $ for i in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor ; do echo performance > $i; done $ echo 4096 32000 64 128 > /proc/sys/kernel/sem $ ./sembench -t 2048 -w 1900 -o 0 Pre: run time 30 seconds 778936 worker burns per second run time 30 seconds 912190 worker burns per second run time 30 seconds 817506 worker burns per second run time 30 seconds 830870 worker burns per second run time 30 seconds 845056 worker burns per second Post: run time 30 seconds 905920 worker burns per second run time 30 seconds 849046 worker burns per second run time 30 seconds 886286 worker burns per second run time 30 seconds 822320 worker burns per second run time 30 seconds 900283 worker burns per second So about 4% faster. (!) cpu_relax() stalls the pipeline, therefore, when used in a tight loop it has the following benefits: - allows SMT siblings to have a go; - reduces pressure on the CPU interconnect. However, cmpxchg loops are unfair and thus have unbounded completion time, therefore we should avoid getting in such heavily contended situations where the above benefits make any difference. A typical cmpxchg loop should not go round more than a handfull of times at worst, therefore adding extra delays just slows things down. Since the llist primitives are new, there aren't any bad users yet, and we should avoid growing them. Heavily contended sites should generally be better off using the ticket locks for serialization since they provide bounded completion times (fifo-fair over the cpus). Signed-off-by: Peter Zijlstra Cc: Huang Ying Cc: Andrew Morton Link: http://lkml.kernel.org/r/1315836358.26517.43.camel@twins Signed-off-by: Ingo Molnar --- lib/llist.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'lib') diff --git a/lib/llist.c b/lib/llist.c index 878985c4d19d..700cff77a387 100644 --- a/lib/llist.c +++ b/lib/llist.c @@ -49,7 +49,6 @@ bool llist_add_batch(struct llist_node *new_first, struct llist_node *new_last, entry = cmpxchg(&head->first, old_entry, new_first); if (entry == old_entry) break; - cpu_relax(); } return old_entry == NULL; @@ -83,7 +82,6 @@ struct llist_node *llist_del_first(struct llist_head *head) entry = cmpxchg(&head->first, old_entry, next); if (entry == old_entry) break; - cpu_relax(); } return entry; -- cgit From fa17b507f142d37aeac322a95f6f7c6375f25601 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 16 Jun 2011 12:23:22 +0200 Subject: sched: Wrap scheduler p->cpus_allowed access This task is preparatory for the migrate_disable() implementation, but stands on its own and provides a cleanup. It currently only converts those sites required for task-placement. Kosaki-san once mentioned replacing cpus_allowed with a proper cpumask_t instead of the NR_CPUS sized array it currently is, that would also require something like this. Signed-off-by: Peter Zijlstra Acked-by: Thomas Gleixner Cc: KOSAKI Motohiro Link: http://lkml.kernel.org/n/tip-e42skvaddos99psip0vce41o@git.kernel.org Signed-off-by: Ingo Molnar --- lib/smp_processor_id.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c index 4689cb073da4..503f087382a4 100644 --- a/lib/smp_processor_id.c +++ b/lib/smp_processor_id.c @@ -22,7 +22,7 @@ notrace unsigned int debug_smp_processor_id(void) * Kernel threads bound to a single CPU can safely use * smp_processor_id(): */ - if (cpumask_equal(¤t->cpus_allowed, cpumask_of(this_cpu))) + if (cpumask_equal(tsk_cpus_allowed(current), cpumask_of(this_cpu))) goto out; /* -- cgit From bd22c01e845ad22a89ae25005b38d28e6690c27a Mon Sep 17 00:00:00 2001 From: Jason Baron Date: Tue, 4 Oct 2011 14:13:17 -0700 Subject: dynamic_debug: remove num_enabled accounting The num_enabled accounting isn't actually used anywhere - remove them. Signed-off-by: Jason Baron Cc: Arnd Bergmann Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- lib/dynamic_debug.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'lib') diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index ee3b9ba625c5..198d2afe18ed 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -42,7 +42,6 @@ struct ddebug_table { struct list_head link; char *mod_name; unsigned int num_ddebugs; - unsigned int num_enabled; struct _ddebug *ddebugs; }; @@ -152,11 +151,6 @@ static void ddebug_change(const struct ddebug_query *query, newflags = (dp->flags & mask) | flags; if (newflags == dp->flags) continue; - - if (!newflags) - dt->num_enabled--; - else if (!dp->flags) - dt->num_enabled++; dp->flags = newflags; if (newflags) dp->enabled = 1; @@ -764,7 +758,6 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n, } dt->mod_name = new_name; dt->num_ddebugs = n; - dt->num_enabled = 0; dt->ddebugs = tab; mutex_lock(&ddebug_lock); -- cgit From 431625dac14de7152235f2f9934d70a9b0f9df83 Mon Sep 17 00:00:00 2001 From: Jason Baron Date: Tue, 4 Oct 2011 14:13:19 -0700 Subject: dynamic_debug: use a single printk() to emit messages We were using KERN_CONT to combine messages with their prefix. However, KERN_CONT is not smp safe, in the sense that it can interleave messages. This interleaving can result in printks coming out at the wrong loglevel. With the high frequency of printks that dynamic debug can produce this is not desirable. So make dynamic_emit_prefix() fill a char buf[64] instead of doing a printk directly. If we enable printing out of function, module, line, or pid info, they are placed in this 64 byte buffer. In my testing 64 bytes was enough size to fulfill all requests. Even if it's not, we can match up the printk itself to see where it's from, so to me this is no big deal. [akpm@linux-foundation.org: convert dangerous macro to C] Signed-off-by: Jason Baron Cc: Arnd Bergmann Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- lib/dynamic_debug.c | 80 +++++++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 39 deletions(-) (limited to 'lib') diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 198d2afe18ed..edec78052333 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -422,52 +422,60 @@ static int ddebug_exec_query(char *query_string) return 0; } -static int dynamic_emit_prefix(const struct _ddebug *descriptor) +#define PREFIX_SIZE 64 + +static int remaining(int wrote) +{ + if (PREFIX_SIZE - wrote > 0) + return PREFIX_SIZE - wrote; + return 0; +} + +static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf) { - char tid[sizeof(int) + sizeof(int)/2 + 4]; - char lineno[sizeof(int) + sizeof(int)/2]; + int pos_after_tid; + int pos = 0; - if (descriptor->flags & _DPRINTK_FLAGS_INCL_TID) { + pos += snprintf(buf + pos, remaining(pos), "%s", KERN_DEBUG); + if (desc->flags & _DPRINTK_FLAGS_INCL_TID) { if (in_interrupt()) - snprintf(tid, sizeof(tid), "%s", " "); + pos += snprintf(buf + pos, remaining(pos), "%s ", + ""); else - snprintf(tid, sizeof(tid), "[%d] ", - task_pid_vnr(current)); - } else { - tid[0] = 0; + pos += snprintf(buf + pos, remaining(pos), "[%d] ", + task_pid_vnr(current)); } + pos_after_tid = pos; + if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME) + pos += snprintf(buf + pos, remaining(pos), "%s:", + desc->modname); + if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME) + pos += snprintf(buf + pos, remaining(pos), "%s:", + desc->function); + if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO) + pos += snprintf(buf + pos, remaining(pos), "%d:", desc->lineno); + if (pos - pos_after_tid) + pos += snprintf(buf + pos, remaining(pos), " "); + if (pos >= PREFIX_SIZE) + buf[PREFIX_SIZE - 1] = '\0'; - if (descriptor->flags & _DPRINTK_FLAGS_INCL_LINENO) - snprintf(lineno, sizeof(lineno), "%d", descriptor->lineno); - else - lineno[0] = 0; - - return printk(KERN_DEBUG "%s%s%s%s%s%s", - tid, - (descriptor->flags & _DPRINTK_FLAGS_INCL_MODNAME) ? - descriptor->modname : "", - (descriptor->flags & _DPRINTK_FLAGS_INCL_MODNAME) ? - ":" : "", - (descriptor->flags & _DPRINTK_FLAGS_INCL_FUNCNAME) ? - descriptor->function : "", - (descriptor->flags & _DPRINTK_FLAGS_INCL_FUNCNAME) ? - ":" : "", - lineno); + return buf; } int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...) { va_list args; int res; + struct va_format vaf; + char buf[PREFIX_SIZE]; BUG_ON(!descriptor); BUG_ON(!fmt); va_start(args, fmt); - - res = dynamic_emit_prefix(descriptor); - res += vprintk(fmt, args); - + vaf.fmt = fmt; + vaf.va = &args; + res = printk("%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf); va_end(args); return res; @@ -480,18 +488,15 @@ int __dynamic_dev_dbg(struct _ddebug *descriptor, struct va_format vaf; va_list args; int res; + char buf[PREFIX_SIZE]; BUG_ON(!descriptor); BUG_ON(!fmt); va_start(args, fmt); - vaf.fmt = fmt; vaf.va = &args; - - res = dynamic_emit_prefix(descriptor); - res += __dev_printk(KERN_CONT, dev, &vaf); - + res = __dev_printk(dynamic_emit_prefix(descriptor, buf), dev, &vaf); va_end(args); return res; @@ -504,18 +509,15 @@ int __dynamic_netdev_dbg(struct _ddebug *descriptor, struct va_format vaf; va_list args; int res; + char buf[PREFIX_SIZE]; BUG_ON(!descriptor); BUG_ON(!fmt); va_start(args, fmt); - vaf.fmt = fmt; vaf.va = &args; - - res = dynamic_emit_prefix(descriptor); - res += __netdev_printk(KERN_CONT, dev, &vaf); - + res = __netdev_printk(dynamic_emit_prefix(descriptor, buf), dev, &vaf); va_end(args); return res; -- cgit From 0feefd97861f9b38accf09a12f8d323f2705e917 Mon Sep 17 00:00:00 2001 From: Jason Baron Date: Tue, 4 Oct 2011 14:13:22 -0700 Subject: dynamic_debug: fix undefined reference to `__netdev_printk' Dynamic debug recently added support for netdev_printk. It uses __netdev_printk() to support this functionality. However, when CONFIG_NET is not set, we get the following error: lib/built-in.o: In function `__dynamic_netdev_dbg': (.text+0x9fda): undefined reference to `__netdev_printk' Fix this by making the call to netdev_printk() contingent upon CONFIG_NET. We could have fixed this by defining netdev_printk() to a 'no-op' in the !CONFIG_NET case. However, this is not consistent with how the networking layer uses netdev_printk. For example, CONFIG_NET is not set, netdev_printk() does not have a 'no-op' definition defined. Signed-off-by: Jason Baron Acked-by: Randy Dunlap Acked-by: Arnd Bergmann Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- lib/dynamic_debug.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib') diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index edec78052333..cb4b74548a3d 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -503,6 +503,8 @@ int __dynamic_dev_dbg(struct _ddebug *descriptor, } EXPORT_SYMBOL(__dynamic_dev_dbg); +#ifdef CONFIG_NET + int __dynamic_netdev_dbg(struct _ddebug *descriptor, const struct net_device *dev, const char *fmt, ...) { @@ -524,6 +526,8 @@ int __dynamic_netdev_dbg(struct _ddebug *descriptor, } EXPORT_SYMBOL(__dynamic_netdev_dbg); +#endif + static __initdata char ddebug_setup_string[1024]; static __init int ddebug_setup_query(char *str) { -- cgit From bd860c53d4f9cad520d233e1ba690aaacfb39e9b Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Mon, 17 Oct 2011 15:29:08 -0500 Subject: lib/raid6: Fix filename emitted in generated code The files were renamed in commit cc4589ebf; fix the name in the file itself. Signed-off-by: Dan McGee Signed-off-by: NeilBrown --- lib/raid6/int.uc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/raid6/int.uc b/lib/raid6/int.uc index d1e276a14fab..5b50f8dfc5d2 100644 --- a/lib/raid6/int.uc +++ b/lib/raid6/int.uc @@ -11,7 +11,7 @@ * ----------------------------------------------------------------------- */ /* - * raid6int$#.c + * int$#.c * * $#-way unrolled portable integer math RAID-6 instruction set * -- cgit From df87ecbf19109bab04a92df047a9949838206abc Mon Sep 17 00:00:00 2001 From: Per Forlin Date: Fri, 19 Aug 2011 14:52:36 +0200 Subject: fault-inject: export fault injection functions Export symbols should_fail() and fault_create_debugfs_attr() in order to let modules utilize the fault injection framework. Signed-off-by: Per Forlin Acked-by: Akinobu Mita Signed-off-by: Chris Ball --- lib/fault-inject.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib') diff --git a/lib/fault-inject.c b/lib/fault-inject.c index f193b7796449..328d43357ed2 100644 --- a/lib/fault-inject.c +++ b/lib/fault-inject.c @@ -130,6 +130,7 @@ bool should_fail(struct fault_attr *attr, ssize_t size) return true; } +EXPORT_SYMBOL_GPL(should_fail); #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS @@ -243,5 +244,6 @@ fail: return ERR_PTR(-ENOMEM); } +EXPORT_SYMBOL_GPL(fault_create_debugfs_attr); #endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */ -- cgit From 1b676f70c108cda90cf9d114d16c677584400efc Mon Sep 17 00:00:00 2001 From: Per Forlin Date: Fri, 19 Aug 2011 14:52:37 +0200 Subject: mmc: core: add random fault injection This adds support to inject data errors after a completed host transfer. The mmc core will return error even though the host transfer is successful. This simple fault injection proved to be very useful to test the non-blocking error handling in the mmc_blk_issue_rw_rq(). Random faults can also test how the host driver handles pre_req() and post_req() in case of errors. Signed-off-by: Per Forlin Acked-by: Akinobu Mita Reviewed-by: Linus Walleij Signed-off-by: Chris Ball --- lib/Kconfig.debug | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'lib') diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index c0cb9c4bc46d..1c7dbbf9e449 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -1070,6 +1070,17 @@ config FAIL_IO_TIMEOUT Only works with drivers that use the generic timeout handling, for others it wont do anything. +config FAIL_MMC_REQUEST + bool "Fault-injection capability for MMC IO" + select DEBUG_FS + depends on FAULT_INJECTION && MMC + help + Provide fault-injection capability for MMC IO. + This will make the mmc core return data errors. This is + useful to test the error handling in the mmc block device + and to test how the mmc host driver handles retries from + the block device. + config FAULT_INJECTION_DEBUG_FS bool "Debugfs entries for fault-injection capabilities" depends on FAULT_INJECTION && SYSFS && DEBUG_FS -- cgit From 6cba00eaa95c1ace1fb511f534b233ae302ccb2e Mon Sep 17 00:00:00 2001 From: Per Forlin Date: Tue, 13 Sep 2011 23:03:28 +0200 Subject: fault-inject: export setup_fault_attr() mmc_core module needs to use setup_fault_attr() in order to set fault injection attributes during module load time. Signed-off-by: Per Forlin Reviewed-by: Akinobu Mita Signed-off-by: Chris Ball --- lib/fault-inject.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/fault-inject.c b/lib/fault-inject.c index 328d43357ed2..4f7554025e30 100644 --- a/lib/fault-inject.c +++ b/lib/fault-inject.c @@ -14,7 +14,7 @@ * setup_fault_attr() is a helper function for various __setup handlers, so it * returns 0 on error, because that is what __setup handlers do. */ -int __init setup_fault_attr(struct fault_attr *attr, char *str) +int setup_fault_attr(struct fault_attr *attr, char *str) { unsigned long probability; unsigned long interval; @@ -36,6 +36,7 @@ int __init setup_fault_attr(struct fault_attr *attr, char *str) return 1; } +EXPORT_SYMBOL_GPL(setup_fault_attr); static void fail_dump(struct fault_attr *attr) { -- cgit From 056075c76417b112b4924e7b6386fdc6dfc9ac03 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 3 Jul 2011 13:58:33 -0400 Subject: md: Add module.h to all files using it implicitly A pending cleanup will mean that module.h won't be implicitly everywhere anymore. Make sure the modular drivers in md dir are actually calling out for explicitly in advance. Signed-off-by: Paul Gortmaker --- lib/raid6/algos.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/raid6/algos.c b/lib/raid6/algos.c index b595f560bee7..8b02f60ffc86 100644 --- a/lib/raid6/algos.c +++ b/lib/raid6/algos.c @@ -17,6 +17,7 @@ */ #include +#include #ifndef __KERNEL__ #include #include -- cgit From daaa5f7cbee37dfc8464d350f1eacd6e94b278cc Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Fri, 27 May 2011 15:50:58 -0400 Subject: md: Add in export.h for files using EXPORT_SYMBOL These files were getting the defines for EXPORT_SYMBOL because device.h was including module.h. But we are going to put an end to that. So add the proper export.h include now. Signed-off-by: Paul Gortmaker --- lib/raid6/mktables.c | 1 + lib/raid6/recov.c | 1 + 2 files changed, 2 insertions(+) (limited to 'lib') diff --git a/lib/raid6/mktables.c b/lib/raid6/mktables.c index 3b1500843bba..8a3780902cec 100644 --- a/lib/raid6/mktables.c +++ b/lib/raid6/mktables.c @@ -60,6 +60,7 @@ int main(int argc, char *argv[]) uint8_t exptbl[256], invtbl[256]; printf("#include \n"); + printf("#include \n"); /* Compute multiplication table */ printf("\nconst u8 __attribute__((aligned(256)))\n" diff --git a/lib/raid6/recov.c b/lib/raid6/recov.c index 8590d19cf522..fe275d7b6b36 100644 --- a/lib/raid6/recov.c +++ b/lib/raid6/recov.c @@ -18,6 +18,7 @@ * the syndrome.) */ +#include #include /* Recover two failed data blocks. */ -- cgit From 23a7bfae6e19cb428da75804e5c4dfd67cd9ae8f Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Fri, 1 Jul 2011 16:23:59 -0400 Subject: lib: dma-debug needs export.h for EXPORT_SYMBOL There are no modular calls here, so just the minimal header for the EXPORT_SYMBOL macro will suffice. Signed-off-by: Paul Gortmaker --- lib/dma-debug.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/dma-debug.c b/lib/dma-debug.c index 79700fa2dfc4..74c6c7fce749 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include -- cgit From 3fa36acbced23c563345de3179dfe1775f15be5e Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Mon, 31 Oct 2011 17:07:02 -0700 Subject: radix_tree: clean away saw_unset_tag leftovers radix_tree_tag_get()'s BUG (when it sees a tag after saw_unset_tag) was unsafe and removed in 2.6.34, but the pointless saw_unset_tag left behind. Remove it now, and return 0 as soon as we see unset tag - we already rely upon the root tag to be correct, returning 0 immediately if it's not set. Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/radix-tree.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/radix-tree.c b/lib/radix-tree.c index a2f9da59c197..d9df7454519c 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c @@ -576,7 +576,6 @@ int radix_tree_tag_get(struct radix_tree_root *root, { unsigned int height, shift; struct radix_tree_node *node; - int saw_unset_tag = 0; /* check the root's tag bit */ if (!root_tag_get(root, tag)) @@ -603,15 +602,10 @@ int radix_tree_tag_get(struct radix_tree_root *root, return 0; offset = (index >> shift) & RADIX_TREE_MAP_MASK; - - /* - * This is just a debug check. Later, we can bale as soon as - * we see an unset tag. - */ if (!tag_get(node, tag, offset)) - saw_unset_tag = 1; + return 0; if (height == 1) - return !!tag_get(node, tag, offset); + return 1; node = rcu_dereference_raw(node->slots[offset]); shift -= RADIX_TREE_MAP_SHIFT; height--; -- cgit From 798248206b59acc6e1238c778281419c041891a7 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Mon, 31 Oct 2011 17:08:07 -0700 Subject: lib/string.c: introduce memchr_inv() memchr_inv() is mainly used to check whether the whole buffer is filled with just a specified byte. The function name and prototype are stolen from logfs and the implementation is from SLUB. Signed-off-by: Akinobu Mita Acked-by: Christoph Lameter Acked-by: Pekka Enberg Cc: Matt Mackall Acked-by: Joern Engel Cc: Marcin Slusarz Cc: Eric Dumazet Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/string.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'lib') diff --git a/lib/string.c b/lib/string.c index 01fad9b203e1..11df54325fb8 100644 --- a/lib/string.c +++ b/lib/string.c @@ -756,3 +756,57 @@ void *memchr(const void *s, int c, size_t n) } EXPORT_SYMBOL(memchr); #endif + +static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes) +{ + while (bytes) { + if (*start != value) + return (void *)start; + start++; + bytes--; + } + return NULL; +} + +/** + * memchr_inv - Find an unmatching character in an area of memory. + * @start: The memory area + * @c: Find a character other than c + * @bytes: The size of the area. + * + * returns the address of the first character other than @c, or %NULL + * if the whole buffer contains just @c. + */ +void *memchr_inv(const void *start, int c, size_t bytes) +{ + u8 value = c; + u64 value64; + unsigned int words, prefix; + + if (bytes <= 16) + return check_bytes8(start, value, bytes); + + value64 = value | value << 8 | value << 16 | value << 24; + value64 = (value64 & 0xffffffff) | value64 << 32; + prefix = 8 - ((unsigned long)start) % 8; + + if (prefix) { + u8 *r = check_bytes8(start, value, prefix); + if (r) + return r; + start += prefix; + bytes -= prefix; + } + + words = bytes / 8; + + while (words) { + if (*(u64 *)start != value64) + return check_bytes8(start, value, 8); + start += 8; + words--; + } + + return check_bytes8(start, value, bytes % 8); +} +EXPORT_SYMBOL(memchr_inv); -- cgit From c51eaacce2ae6861e1ad8c80ade6102ad428dc93 Mon Sep 17 00:00:00 2001 From: Jiaju Zhang Date: Mon, 31 Oct 2011 17:10:07 -0700 Subject: lib/Kconfig.debug: fix help message for DEFAULT_HUNG_TASK_TIMEOUT Added missing _secs in the help message of config DEFAULT_HUNG_TASK_TIMEOUT. Signed-off-by: Jiaju Zhang Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/Kconfig.debug | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index c583a57cddfe..82928f5ea049 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -248,8 +248,9 @@ config DEFAULT_HUNG_TASK_TIMEOUT to determine when a task has become non-responsive and should be considered hung. - It can be adjusted at runtime via the kernel.hung_task_timeout - sysctl or by writing a value to /proc/sys/kernel/hung_task_timeout. + It can be adjusted at runtime via the kernel.hung_task_timeout_secs + sysctl or by writing a value to + /proc/sys/kernel/hung_task_timeout_secs. A timeout of 0 disables the check. The default is two minutes. Keeping the default should be fine in most cases. -- cgit From 1dff46d6987484eaa31f2fb1425216ba06418be3 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 31 Oct 2011 17:12:28 -0700 Subject: lib/kstrtox: common code between kstrto*() and simple_strto*() functions Currently termination logic (\0 or \n\0) is hardcoded in _kstrtoull(), avoid that for code reuse between kstrto*() and simple_strtoull(). Essentially, make them different only in termination logic. simple_strtoull() (and scanf(), BTW) ignores integer overflow, that's a bug we currently don't have guts to fix, making KSTRTOX_OVERFLOW hack necessary. Almost forgot: patch shrinks code size by about ~80 bytes on x86_64. Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/kstrtox.c | 75 +++++++++++++++++++++++++++++++++++++++++----------------- lib/kstrtox.h | 8 +++++++ lib/vsprintf.c | 33 ++++++-------------------- 3 files changed, 68 insertions(+), 48 deletions(-) create mode 100644 lib/kstrtox.h (limited to 'lib') diff --git a/lib/kstrtox.c b/lib/kstrtox.c index 5e066759f551..7a94c8f14e29 100644 --- a/lib/kstrtox.c +++ b/lib/kstrtox.c @@ -18,26 +18,40 @@ #include #include #include +#include "kstrtox.h" -static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res) +const char *_parse_integer_fixup_radix(const char *s, unsigned int *base) { - unsigned long long acc; - int ok; - - if (base == 0) { + if (*base == 0) { if (s[0] == '0') { if (_tolower(s[1]) == 'x' && isxdigit(s[2])) - base = 16; + *base = 16; else - base = 8; + *base = 8; } else - base = 10; + *base = 10; } - if (base == 16 && s[0] == '0' && _tolower(s[1]) == 'x') + if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x') s += 2; + return s; +} - acc = 0; - ok = 0; +/* + * Convert non-negative integer string representation in explicitly given radix + * to an integer. + * Return number of characters consumed maybe or-ed with overflow bit. + * If overflow occurs, result integer (incorrect) is still returned. + * + * Don't you dare use this function. + */ +unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *res) +{ + unsigned int rv; + int overflow; + + *res = 0; + rv = 0; + overflow = 0; while (*s) { unsigned int val; @@ -45,23 +59,40 @@ static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res) val = *s - '0'; else if ('a' <= _tolower(*s) && _tolower(*s) <= 'f') val = _tolower(*s) - 'a' + 10; - else if (*s == '\n' && *(s + 1) == '\0') - break; else - return -EINVAL; + break; if (val >= base) - return -EINVAL; - if (acc > div_u64(ULLONG_MAX - val, base)) - return -ERANGE; - acc = acc * base + val; - ok = 1; - + break; + if (*res > div_u64(ULLONG_MAX - val, base)) + overflow = 1; + *res = *res * base + val; + rv++; s++; } - if (!ok) + if (overflow) + rv |= KSTRTOX_OVERFLOW; + return rv; +} + +static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res) +{ + unsigned long long _res; + unsigned int rv; + + s = _parse_integer_fixup_radix(s, &base); + rv = _parse_integer(s, base, &_res); + if (rv & KSTRTOX_OVERFLOW) + return -ERANGE; + rv &= ~KSTRTOX_OVERFLOW; + if (rv == 0) + return -EINVAL; + s += rv; + if (*s == '\n') + s++; + if (*s) return -EINVAL; - *res = acc; + *res = _res; return 0; } diff --git a/lib/kstrtox.h b/lib/kstrtox.h new file mode 100644 index 000000000000..f13eeeaf441d --- /dev/null +++ b/lib/kstrtox.h @@ -0,0 +1,8 @@ +#ifndef _LIB_KSTRTOX_H +#define _LIB_KSTRTOX_H + +#define KSTRTOX_OVERFLOW (1U << 31) +const char *_parse_integer_fixup_radix(const char *s, unsigned int *base); +unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *res); + +#endif diff --git a/lib/vsprintf.c b/lib/vsprintf.c index d7222a9c8267..c1a3927326eb 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -31,17 +31,7 @@ #include #include /* for dereference_function_descriptor() */ -static unsigned int simple_guess_base(const char *cp) -{ - if (cp[0] == '0') { - if (_tolower(cp[1]) == 'x' && isxdigit(cp[2])) - return 16; - else - return 8; - } else { - return 10; - } -} +#include "kstrtox.h" /** * simple_strtoull - convert a string to an unsigned long long @@ -51,23 +41,14 @@ static unsigned int simple_guess_base(const char *cp) */ unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base) { - unsigned long long result = 0; + unsigned long long result; + unsigned int rv; - if (!base) - base = simple_guess_base(cp); + cp = _parse_integer_fixup_radix(cp, &base); + rv = _parse_integer(cp, base, &result); + /* FIXME */ + cp += (rv & ~KSTRTOX_OVERFLOW); - if (base == 16 && cp[0] == '0' && _tolower(cp[1]) == 'x') - cp += 2; - - while (isxdigit(*cp)) { - unsigned int value; - - value = isdigit(*cp) ? *cp - '0' : _tolower(*cp) - 'a' + 10; - if (value >= base) - break; - result = result * base + value; - cp++; - } if (endp) *endp = (char *)cp; -- cgit From 4e101b0e6aa885f5786a058eefc1ce4b7cc7c44e Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Mon, 31 Oct 2011 17:12:29 -0700 Subject: lib/spinlock_debug.c: print owner on spinlock lockup When SPIN_BUG_ON is triggered, the lock owner information is reported. But it is omitted when spinlock lockup is detected. This information is useful especially on the architectures which don't implement trigger_all_cpu_backtrace() that is called just after detecting lockup. So report it and also avoid message format duplication. Signed-off-by: Akinobu Mita Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/spinlock_debug.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c index 4755b98b6dfb..5f3eacdd6178 100644 --- a/lib/spinlock_debug.c +++ b/lib/spinlock_debug.c @@ -49,13 +49,10 @@ void __rwlock_init(rwlock_t *lock, const char *name, EXPORT_SYMBOL(__rwlock_init); -static void spin_bug(raw_spinlock_t *lock, const char *msg) +static void spin_dump(raw_spinlock_t *lock, const char *msg) { struct task_struct *owner = NULL; - if (!debug_locks_off()) - return; - if (lock->owner && lock->owner != SPINLOCK_OWNER_INIT) owner = lock->owner; printk(KERN_EMERG "BUG: spinlock %s on CPU#%d, %s/%d\n", @@ -70,6 +67,14 @@ static void spin_bug(raw_spinlock_t *lock, const char *msg) dump_stack(); } +static void spin_bug(raw_spinlock_t *lock, const char *msg) +{ + if (!debug_locks_off()) + return; + + spin_dump(lock, msg); +} + #define SPIN_BUG_ON(cond, lock, msg) if (unlikely(cond)) spin_bug(lock, msg) static inline void @@ -113,11 +118,7 @@ static void __spin_lock_debug(raw_spinlock_t *lock) /* lockup suspected: */ if (print_once) { print_once = 0; - printk(KERN_EMERG "BUG: spinlock lockup on CPU#%d, " - "%s/%d, %p\n", - raw_smp_processor_id(), current->comm, - task_pid_nr(current), lock); - dump_stack(); + spin_dump(lock, "lockup"); #ifdef CONFIG_SMP trigger_all_cpu_backtrace(); #endif -- cgit From b9c321fd87b61f70888511d286500519d8b34141 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 31 Oct 2011 17:12:32 -0700 Subject: lib/bitmap.c: quiet sparse noise about address space __bitmap_parse() and __bitmap_parselist() both take a pointer to a kernel buffer as a parameter and then cast it to a pointer to user buffer for use in cases when the parameter is_user indicates that the buffer is actually located in user space. This casting, and the casts in the callers, results in sparse noise like the following: warning: incorrect type in initializer (different address spaces) expected char const [noderef] *ubuf got char const *buf warning: cast removes address space of expression Since these casts are intentional, use __force to quiet the noise. Signed-off-by: H Hartley Sweeten Cc: Len Brown Cc: Huang Ying Cc: Andy Shevchenko Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/bitmap.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/bitmap.c b/lib/bitmap.c index 2f4412e4d071..0d4a127dd9b3 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -419,7 +419,7 @@ int __bitmap_parse(const char *buf, unsigned int buflen, { int c, old_c, totaldigits, ndigits, nchunks, nbits; u32 chunk; - const char __user *ubuf = buf; + const char __user __force *ubuf = (const char __user __force *)buf; bitmap_zero(maskp, nmaskbits); @@ -504,7 +504,9 @@ int bitmap_parse_user(const char __user *ubuf, { if (!access_ok(VERIFY_READ, ubuf, ulen)) return -EFAULT; - return __bitmap_parse((const char *)ubuf, ulen, 1, maskp, nmaskbits); + return __bitmap_parse((const char __force *)ubuf, + ulen, 1, maskp, nmaskbits); + } EXPORT_SYMBOL(bitmap_parse_user); @@ -594,7 +596,7 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen, { unsigned a, b; int c, old_c, totaldigits; - const char __user *ubuf = buf; + const char __user __force *ubuf = (const char __user __force *)buf; int exp_digit, in_range; totaldigits = c = 0; @@ -694,7 +696,7 @@ int bitmap_parselist_user(const char __user *ubuf, { if (!access_ok(VERIFY_READ, ubuf, ulen)) return -EFAULT; - return __bitmap_parselist((const char *)ubuf, + return __bitmap_parselist((const char __force *)ubuf, ulen, 1, maskp, nmaskbits); } EXPORT_SYMBOL(bitmap_parselist_user); -- cgit From 3a8495c739c1c773181a246dbb7c12b5b67a8325 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Mon, 31 Oct 2011 17:12:34 -0700 Subject: lib/percpu_counter.c: enclose hotplug only variables in hotplug ifdef These variables are only used when CONFIG_HOTPLUG_CPU is enabled, they are ifdef'ed everywhere else. So don't define them when CONFIG_HOTPLUG_CPU is not enabled. Signed-off-by: Glauber Costa Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/percpu_counter.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib') diff --git a/lib/percpu_counter.c b/lib/percpu_counter.c index f087105ed914..f8a3f1a829b8 100644 --- a/lib/percpu_counter.c +++ b/lib/percpu_counter.c @@ -10,8 +10,10 @@ #include #include +#ifdef CONFIG_HOTPLUG_CPU static LIST_HEAD(percpu_counters); static DEFINE_MUTEX(percpu_counters_lock); +#endif #ifdef CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER -- cgit From e3816c5407c800e4fb055d08f668286db6b7113f Mon Sep 17 00:00:00 2001 From: Wang Sheng-Hui Date: Mon, 31 Oct 2011 17:12:36 -0700 Subject: lib/idr.c: fix comment for ida_get_new_above() Signed-off-by: Wang Sheng-Hui Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/idr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/idr.c b/lib/idr.c index 5acf9bb10968..bbf211aea4eb 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -767,8 +767,8 @@ EXPORT_SYMBOL(ida_pre_get); * @starting_id: id to start search at * @p_id: pointer to the allocated handle * - * Allocate new ID above or equal to @ida. It should be called with - * any required locks. + * Allocate new ID above or equal to @starting_id. It should be called + * with any required locks. * * If memory is required, it will return %-EAGAIN, you should unlock * and go back to the ida_pre_get() call. If the ida is full, it will -- cgit From 66f6958e69d8055277356d3cc2e7a1d734db1755 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Mon, 31 Oct 2011 17:12:37 -0700 Subject: lib/string.c: fix strim() semantics for strings that have only blanks Commit 84c95c9acf0 ("string: on strstrip(), first remove leading spaces before running over str") improved the performance of the strim() function. Unfortunately this changed the semantics of strim() and broke my code. Before the patch it was possible to use strim() without using the return value for removing trailing spaces from strings that had either only blanks or only trailing blanks. Now this does not work any longer for strings that *only* have blanks. Before patch: " " -> "" (empty string) After patch: " " -> " " (no change) I think we should remove your patch to restore the old behavior. The description (lib/string.c): * Note that the first trailing whitespace is replaced with a %NUL-terminator => The first trailing whitespace of a string that only has whitespace characters is the first whitespace The patch restores the old strim() semantics. Signed-off-by: Michael Holzheu Cc: Andre Goddard Rosa Cc: Martin Schwidefsky Cc: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/string.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/string.c b/lib/string.c index 11df54325fb8..dc4a86341f91 100644 --- a/lib/string.c +++ b/lib/string.c @@ -360,7 +360,6 @@ char *strim(char *s) size_t size; char *end; - s = skip_spaces(s); size = strlen(s); if (!size) return s; @@ -370,7 +369,7 @@ char *strim(char *s) end--; *(end + 1) = '\0'; - return s; + return skip_spaces(s); } EXPORT_SYMBOL(strim); -- cgit From 55036ba76b2d2fd53b5c00993fcec5ed56e83922 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 31 Oct 2011 17:12:41 -0700 Subject: lib: rename pack_hex_byte() to hex_byte_pack() As suggested by Andrew Morton in [1] there is better to have most significant part first in the function name. [1] https://lkml.org/lkml/2011/9/20/22 There is no functional change. Signed-off-by: Andy Shevchenko Cc: Jesper Nilsson Cc: David Howells Cc: Koichi Yasutake Cc: Jason Wessel Cc: Mimi Zohar Cc: James Morris Cc: OGAWA Hirofumi Cc: "John W. Linville" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/vsprintf.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/vsprintf.c b/lib/vsprintf.c index c1a3927326eb..993599e66e5a 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -547,7 +547,7 @@ char *mac_address_string(char *buf, char *end, u8 *addr, } for (i = 0; i < 6; i++) { - p = pack_hex_byte(p, addr[i]); + p = hex_byte_pack(p, addr[i]); if (fmt[0] == 'M' && i != 5) *p++ = separator; } @@ -667,13 +667,13 @@ char *ip6_compressed_string(char *p, const char *addr) lo = word & 0xff; if (hi) { if (hi > 0x0f) - p = pack_hex_byte(p, hi); + p = hex_byte_pack(p, hi); else *p++ = hex_asc_lo(hi); - p = pack_hex_byte(p, lo); + p = hex_byte_pack(p, lo); } else if (lo > 0x0f) - p = pack_hex_byte(p, lo); + p = hex_byte_pack(p, lo); else *p++ = hex_asc_lo(lo); needcolon = true; @@ -695,8 +695,8 @@ char *ip6_string(char *p, const char *addr, const char *fmt) int i; for (i = 0; i < 8; i++) { - p = pack_hex_byte(p, *addr++); - p = pack_hex_byte(p, *addr++); + p = hex_byte_pack(p, *addr++); + p = hex_byte_pack(p, *addr++); if (fmt[0] == 'I' && i != 7) *p++ = ':'; } @@ -754,7 +754,7 @@ char *uuid_string(char *buf, char *end, const u8 *addr, } for (i = 0; i < 16; i++) { - p = pack_hex_byte(p, addr[index[i]]); + p = hex_byte_pack(p, addr[index[i]]); switch (i) { case 3: case 5: -- cgit From 46cbc1d3981ee753518fbf9198a14f71a9f6841e Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 2 Nov 2011 13:38:46 -0700 Subject: ida: make ida_simple_get/put() IRQ safe It's often convenient to be able to release resource from IRQ context. Make ida_simple_*() use irqsave/restore spin ops so that they are IRQ safe. Signed-off-by: Tejun Heo Acked-by: Rusty Russell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/idr.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/idr.c b/lib/idr.c index bbf211aea4eb..ed055b297c81 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -944,6 +944,7 @@ int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, { int ret, id; unsigned int max; + unsigned long flags; BUG_ON((int)start < 0); BUG_ON((int)end < 0); @@ -959,7 +960,7 @@ again: if (!ida_pre_get(ida, gfp_mask)) return -ENOMEM; - spin_lock(&simple_ida_lock); + spin_lock_irqsave(&simple_ida_lock, flags); ret = ida_get_new_above(ida, start, &id); if (!ret) { if (id > max) { @@ -969,7 +970,7 @@ again: ret = id; } } - spin_unlock(&simple_ida_lock); + spin_unlock_irqrestore(&simple_ida_lock, flags); if (unlikely(ret == -EAGAIN)) goto again; @@ -985,10 +986,12 @@ EXPORT_SYMBOL(ida_simple_get); */ void ida_simple_remove(struct ida *ida, unsigned int id) { + unsigned long flags; + BUG_ON((int)id < 0); - spin_lock(&simple_ida_lock); + spin_lock_irqsave(&simple_ida_lock, flags); ida_remove(ida, id); - spin_unlock(&simple_ida_lock); + spin_unlock_irqrestore(&simple_ida_lock, flags); } EXPORT_SYMBOL(ida_simple_remove); -- cgit From c30bc94758ae2a38a5eb31767c1985c0aae0950b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 3 Nov 2011 00:07:32 +0000 Subject: netlink: validate NLA_MSECS length L2TP for example uses NLA_MSECS like this: policy: [L2TP_ATTR_RECV_TIMEOUT] = { .type = NLA_MSECS, }, code: if (info->attrs[L2TP_ATTR_RECV_TIMEOUT]) cfg.reorder_timeout = nla_get_msecs(info->attrs[L2TP_ATTR_RECV_TIMEOUT]); As nla_get_msecs() is essentially nla_get_u64() plus the conversion to a HZ-based value, this will not properly reject attributes from userspace that aren't long enough and might overrun the message. Add NLA_MSECS to the attribute minlen array to check the size properly. Cc: Thomas Graf Cc: stable@vger.kernel.org Signed-off-by: Johannes Berg Signed-off-by: David S. Miller --- lib/nlattr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/nlattr.c b/lib/nlattr.c index ac09f2226dc7..a8408b6cacdf 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c @@ -20,6 +20,7 @@ static const u16 nla_attr_minlen[NLA_TYPE_MAX+1] = { [NLA_U16] = sizeof(u16), [NLA_U32] = sizeof(u32), [NLA_U64] = sizeof(u64), + [NLA_MSECS] = sizeof(u64), [NLA_NESTED] = NLA_HDRLEN, }; -- cgit