From bd33d12fba60dea3b8f944478c54ac3ba18d2c4d Mon Sep 17 00:00:00 2001 From: Harry Wei Date: Sat, 16 Jul 2011 16:45:13 +0800 Subject: debugfs: Fix a comment mistake The file is fs/debugfs/inode.c but the comment says it is file.c. This patch can fix this little mistake. Signed-off-by: Harry Wei Signed-off-by: Greg Kroah-Hartman --- fs/debugfs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index e7a7a2f07324..f3a257d7a985 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -1,5 +1,5 @@ /* - * file.c - part of debugfs, a tiny little debug file system + * inode.c - part of debugfs, a tiny little debug file system * * Copyright (C) 2004 Greg Kroah-Hartman * Copyright (C) 2004 IBM Inc. -- cgit v1.2.3-55-g7522 From 86028619b9f653a30f5aa0d331fdedd899a1eea5 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 16 Aug 2011 18:42:22 +0200 Subject: docs/sysfs: Specify ABI documentation requirements Although it is expected nowadays that every new sysfs attribute is documented under Documentation/ABI, this is not yet mentioned in the kernel documentation. This patch adds a note in the sysfs documentation about that requirement. Signed-off-by: Bart Van Assche Cc: Andrew Morton Cc: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- Documentation/filesystems/sysfs.txt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt index 597f728e7b4e..07235caec22c 100644 --- a/Documentation/filesystems/sysfs.txt +++ b/Documentation/filesystems/sysfs.txt @@ -4,7 +4,7 @@ sysfs - _The_ filesystem for exporting kernel objects. Patrick Mochel Mike Murphy -Revised: 15 July 2010 +Revised: 16 August 2011 Original: 10 January 2003 @@ -370,3 +370,11 @@ int driver_create_file(struct device_driver *, const struct driver_attribute *); void driver_remove_file(struct device_driver *, const struct driver_attribute *); +Documentation +~~~~~~~~~~~~~ + +The sysfs directory structure and the attributes in each directory define an +ABI between the kernel and user space. As for any ABI, it is important that +this ABI is stable and properly documented. All new sysfs attributes must be +documented in Documentation/ABI. See also Documentation/ABI/README for more +information. -- cgit v1.2.3-55-g7522 From 7f9838fd01833ffb30177d964983076924344c9e Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 21 Jul 2011 19:59:22 -0400 Subject: sysfs: count subdirectories sysfs: count subdirectories This patch introduces a subdirectory counter for each sysfs directory. Without the patch, sysfs_refresh_inode would walk all entries of the directory to calculate the number of subdirectories. This patch improves time of "ls -la /sys/block" when there are 10000 block devices from 9 seconds to 0.19 seconds. Signed-off-by: Mikulas Patocka Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/dir.c | 6 ++++++ fs/sysfs/inode.c | 14 +------------- fs/sysfs/sysfs.h | 2 ++ 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index ea9120a830d8..7d240e6b7176 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -47,6 +47,9 @@ static void sysfs_link_sibling(struct sysfs_dirent *sd) BUG_ON(sd->s_sibling); + if (sysfs_type(sd) == SYSFS_DIR) + parent_sd->s_dir.subdirs++; + /* Store directory entries in order by ino. This allows * readdir to properly restart without having to add a * cursor into the s_dir.children list. @@ -73,6 +76,9 @@ static void sysfs_unlink_sibling(struct sysfs_dirent *sd) { struct sysfs_dirent **pos; + if (sysfs_type(sd) == SYSFS_DIR) + sd->s_parent->s_dir.subdirs--; + for (pos = &sd->s_parent->s_dir.children; *pos; pos = &(*pos)->s_sibling) { if (*pos == sd) { diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index e3f091a81c72..1ee18c81df78 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c @@ -202,18 +202,6 @@ static inline void set_inode_attr(struct inode * inode, struct iattr * iattr) inode->i_ctime = iattr->ia_ctime; } -static int sysfs_count_nlink(struct sysfs_dirent *sd) -{ - struct sysfs_dirent *child; - int nr = 0; - - for (child = sd->s_dir.children; child; child = child->s_sibling) - if (sysfs_type(child) == SYSFS_DIR) - nr++; - - return nr + 2; -} - static void sysfs_refresh_inode(struct sysfs_dirent *sd, struct inode *inode) { struct sysfs_inode_attrs *iattrs = sd->s_iattr; @@ -230,7 +218,7 @@ static void sysfs_refresh_inode(struct sysfs_dirent *sd, struct inode *inode) } if (sysfs_type(sd) == SYSFS_DIR) - inode->i_nlink = sysfs_count_nlink(sd); + inode->i_nlink = sd->s_dir.subdirs + 2; } int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index 845ab3ad229d..6348e2c753f6 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h @@ -19,6 +19,8 @@ struct sysfs_elem_dir { struct kobject *kobj; /* children list starts here and goes through sd->s_sibling */ struct sysfs_dirent *children; + + unsigned long subdirs; }; struct sysfs_elem_symlink { -- cgit v1.2.3-55-g7522 From 4f72c0cab40536a0be501d85ea4918467ab82ad5 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Mon, 25 Jul 2011 17:55:57 -0400 Subject: sysfs: use rb-tree for name lookups sysfs: use rb-tree for name lookups Use red-black tree for name lookups. Signed-off-by: Mikulas Patocka Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/dir.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++------- fs/sysfs/sysfs.h | 5 +++++ 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 7d240e6b7176..3e937da224d4 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -45,6 +45,9 @@ static void sysfs_link_sibling(struct sysfs_dirent *sd) struct sysfs_dirent *parent_sd = sd->s_parent; struct sysfs_dirent **pos; + struct rb_node **p; + struct rb_node *parent; + BUG_ON(sd->s_sibling); if (sysfs_type(sd) == SYSFS_DIR) @@ -60,6 +63,23 @@ static void sysfs_link_sibling(struct sysfs_dirent *sd) } sd->s_sibling = *pos; *pos = sd; + + p = &parent_sd->s_dir.name_tree.rb_node; + parent = NULL; + while (*p) { + int c; + parent = *p; +#define node rb_entry(parent, struct sysfs_dirent, name_node) + c = strcmp(sd->s_name, node->s_name); + if (c < 0) { + p = &node->name_node.rb_left; + } else { + p = &node->name_node.rb_right; + } +#undef node + } + rb_link_node(&sd->name_node, parent, p); + rb_insert_color(&sd->name_node, &parent_sd->s_dir.name_tree); } /** @@ -87,6 +107,8 @@ static void sysfs_unlink_sibling(struct sysfs_dirent *sd) break; } } + + rb_erase(&sd->name_node, &sd->s_parent->s_dir.name_tree); } /** @@ -546,15 +568,36 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd, const void *ns, const unsigned char *name) { - struct sysfs_dirent *sd; + struct rb_node *p = parent_sd->s_dir.name_tree.rb_node; + struct sysfs_dirent *found = NULL; + + while (p) { + int c; +#define node rb_entry(p, struct sysfs_dirent, name_node) + c = strcmp(name, node->s_name); + if (c < 0) { + p = node->name_node.rb_left; + } else if (c > 0) { + p = node->name_node.rb_right; + } else { + found = node; + p = node->name_node.rb_left; + } +#undef node + } - for (sd = parent_sd->s_dir.children; sd; sd = sd->s_sibling) { - if (ns && sd->s_ns && (sd->s_ns != ns)) - continue; - if (!strcmp(sd->s_name, name)) - return sd; + if (found && ns) { + while (found->s_ns && found->s_ns != ns) { + p = rb_next(&found->name_node); + if (!p) + return NULL; + found = rb_entry(p, struct sysfs_dirent, name_node); + if (strcmp(name, found->s_name)) + return NULL; + } } - return NULL; + + return found; } /** diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index 6348e2c753f6..fe1a9e8650bf 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h @@ -11,6 +11,7 @@ #include #include #include +#include struct sysfs_open_dirent; @@ -21,6 +22,8 @@ struct sysfs_elem_dir { struct sysfs_dirent *children; unsigned long subdirs; + + struct rb_root name_tree; }; struct sysfs_elem_symlink { @@ -61,6 +64,8 @@ struct sysfs_dirent { struct sysfs_dirent *s_sibling; const char *s_name; + struct rb_node name_node; + const void *s_ns; /* namespace tag */ union { struct sysfs_elem_dir s_dir; -- cgit v1.2.3-55-g7522 From 58f2a4c7932d8bec866d0394f806004146cde827 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 21 Jul 2011 20:01:12 -0400 Subject: sysfs: remove s_sibling hacks sysfs: remove s_sibling hacks s_sibling was used for three different purposes: 1) as a linked list of entries in the directory 2) as a linked list of entries to be deleted 3) as a pointer to "struct completion" This patch removes the hack and introduces new union u which holds pointers for cases 2) and 3). This change is needed for the following patch that removes s_sibling at all and replaces it with a rb tree. Signed-off-by: Mikulas Patocka Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/dir.c | 19 +++++++------------ fs/sysfs/sysfs.h | 5 +++++ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 3e937da224d4..a4846979d4e8 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -154,7 +154,6 @@ struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd) */ void sysfs_put_active(struct sysfs_dirent *sd) { - struct completion *cmpl; int v; if (unlikely(!sd)) @@ -166,10 +165,9 @@ void sysfs_put_active(struct sysfs_dirent *sd) return; /* atomic_dec_return() is a mb(), we'll always see the updated - * sd->s_sibling. + * sd->u.completion. */ - cmpl = (void *)sd->s_sibling; - complete(cmpl); + complete(sd->u.completion); } /** @@ -183,16 +181,16 @@ static void sysfs_deactivate(struct sysfs_dirent *sd) DECLARE_COMPLETION_ONSTACK(wait); int v; - BUG_ON(sd->s_sibling || !(sd->s_flags & SYSFS_FLAG_REMOVED)); + BUG_ON(!(sd->s_flags & SYSFS_FLAG_REMOVED)); if (!(sysfs_type(sd) & SYSFS_ACTIVE_REF)) return; - sd->s_sibling = (void *)&wait; + sd->u.completion = (void *)&wait; rwsem_acquire(&sd->dep_map, 0, 0, _RET_IP_); /* atomic_add_return() is a mb(), put_active() will always see - * the updated sd->s_sibling. + * the updated sd->u.completion. */ v = atomic_add_return(SD_DEACTIVATED_BIAS, &sd->s_active); @@ -201,8 +199,6 @@ static void sysfs_deactivate(struct sysfs_dirent *sd) wait_for_completion(&wait); } - sd->s_sibling = NULL; - lock_acquired(&sd->dep_map, _RET_IP_); rwsem_release(&sd->dep_map, 1, _RET_IP_); } @@ -518,7 +514,7 @@ void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) } sd->s_flags |= SYSFS_FLAG_REMOVED; - sd->s_sibling = acxt->removed; + sd->u.removed_list = acxt->removed; acxt->removed = sd; } @@ -542,8 +538,7 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt) while (acxt->removed) { struct sysfs_dirent *sd = acxt->removed; - acxt->removed = sd->s_sibling; - sd->s_sibling = NULL; + acxt->removed = sd->u.removed_list; sysfs_deactivate(sd); unmap_bin_file(sd); diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index fe1a9e8650bf..3c261681713b 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h @@ -66,6 +66,11 @@ struct sysfs_dirent { struct rb_node name_node; + union { + struct completion *completion; + struct sysfs_dirent *removed_list; + } u; + const void *s_ns; /* namespace tag */ union { struct sysfs_elem_dir s_dir; -- cgit v1.2.3-55-g7522 From a406f75840e15afbabd98cb64ae36b51424a8033 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Mon, 25 Jul 2011 17:57:03 -0400 Subject: sysfs: use rb-tree for inode number lookup sysfs: use rb-tree for inode number lookup This patch makes sysfs use red-black tree for inode number lookup. Together with a previous patch to use red-black tree for name lookup, this patch makes all sysfs lookups to have O(log n) complexity. Signed-off-by: Mikulas Patocka Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/dir.c | 89 +++++++++++++++++++++++++++++++------------------------- fs/sysfs/sysfs.h | 5 ++-- 2 files changed, 52 insertions(+), 42 deletions(-) diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index a4846979d4e8..c3646d93a032 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -43,26 +43,30 @@ static DEFINE_IDA(sysfs_ino_ida); static void sysfs_link_sibling(struct sysfs_dirent *sd) { struct sysfs_dirent *parent_sd = sd->s_parent; - struct sysfs_dirent **pos; struct rb_node **p; struct rb_node *parent; - BUG_ON(sd->s_sibling); - if (sysfs_type(sd) == SYSFS_DIR) parent_sd->s_dir.subdirs++; - /* Store directory entries in order by ino. This allows - * readdir to properly restart without having to add a - * cursor into the s_dir.children list. - */ - for (pos = &parent_sd->s_dir.children; *pos; pos = &(*pos)->s_sibling) { - if (sd->s_ino < (*pos)->s_ino) - break; + p = &parent_sd->s_dir.inode_tree.rb_node; + parent = NULL; + while (*p) { + parent = *p; +#define node rb_entry(parent, struct sysfs_dirent, inode_node) + if (sd->s_ino < node->s_ino) { + p = &node->inode_node.rb_left; + } else if (sd->s_ino > node->s_ino) { + p = &node->inode_node.rb_right; + } else { + printk(KERN_CRIT "sysfs: inserting duplicate inode '%lx'\n", sd->s_ino); + BUG(); + } +#undef node } - sd->s_sibling = *pos; - *pos = sd; + rb_link_node(&sd->inode_node, parent, p); + rb_insert_color(&sd->inode_node, &parent_sd->s_dir.inode_tree); p = &parent_sd->s_dir.name_tree.rb_node; parent = NULL; @@ -94,20 +98,10 @@ static void sysfs_link_sibling(struct sysfs_dirent *sd) */ static void sysfs_unlink_sibling(struct sysfs_dirent *sd) { - struct sysfs_dirent **pos; - if (sysfs_type(sd) == SYSFS_DIR) sd->s_parent->s_dir.subdirs--; - for (pos = &sd->s_parent->s_dir.children; *pos; - pos = &(*pos)->s_sibling) { - if (*pos == sd) { - *pos = sd->s_sibling; - sd->s_sibling = NULL; - break; - } - } - + rb_erase(&sd->inode_node, &sd->s_parent->s_dir.inode_tree); rb_erase(&sd->name_node, &sd->s_parent->s_dir.name_tree); } @@ -788,21 +782,19 @@ void sysfs_remove_subdir(struct sysfs_dirent *sd) static void __sysfs_remove_dir(struct sysfs_dirent *dir_sd) { struct sysfs_addrm_cxt acxt; - struct sysfs_dirent **pos; + struct rb_node *pos; if (!dir_sd) return; pr_debug("sysfs %s: removing dir\n", dir_sd->s_name); sysfs_addrm_start(&acxt, dir_sd); - pos = &dir_sd->s_dir.children; - while (*pos) { - struct sysfs_dirent *sd = *pos; - + pos = rb_first(&dir_sd->s_dir.inode_tree); + while (pos) { + struct sysfs_dirent *sd = rb_entry(pos, struct sysfs_dirent, inode_node); + pos = rb_next(pos); if (sysfs_type(sd) != SYSFS_DIR) sysfs_remove_one(&acxt, sd); - else - pos = &(*pos)->s_sibling; } sysfs_addrm_finish(&acxt); @@ -925,12 +917,28 @@ static struct sysfs_dirent *sysfs_dir_pos(const void *ns, pos = NULL; } if (!pos && (ino > 1) && (ino < INT_MAX)) { - pos = parent_sd->s_dir.children; - while (pos && (ino > pos->s_ino)) - pos = pos->s_sibling; + struct rb_node *p = parent_sd->s_dir.inode_tree.rb_node; + while (p) { +#define node rb_entry(p, struct sysfs_dirent, inode_node) + if (ino < node->s_ino) { + pos = node; + p = node->inode_node.rb_left; + } else if (ino > node->s_ino) { + p = node->inode_node.rb_right; + } else { + pos = node; + break; + } +#undef node + } + } + while (pos && pos->s_ns && pos->s_ns != ns) { + struct rb_node *p = rb_next(&pos->inode_node); + if (!p) + pos = NULL; + else + pos = rb_entry(p, struct sysfs_dirent, inode_node); } - while (pos && pos->s_ns && pos->s_ns != ns) - pos = pos->s_sibling; return pos; } @@ -938,10 +946,13 @@ static struct sysfs_dirent *sysfs_dir_next_pos(const void *ns, struct sysfs_dirent *parent_sd, ino_t ino, struct sysfs_dirent *pos) { pos = sysfs_dir_pos(ns, parent_sd, ino, pos); - if (pos) - pos = pos->s_sibling; - while (pos && pos->s_ns && pos->s_ns != ns) - pos = pos->s_sibling; + if (pos) do { + struct rb_node *p = rb_next(&pos->inode_node); + if (!p) + pos = NULL; + else + pos = rb_entry(p, struct sysfs_dirent, inode_node); + } while (pos && pos->s_ns && pos->s_ns != ns); return pos; } diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index 3c261681713b..ce29e28b766d 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h @@ -18,11 +18,10 @@ struct sysfs_open_dirent; /* type-specific structures for sysfs_dirent->s_* union members */ struct sysfs_elem_dir { struct kobject *kobj; - /* children list starts here and goes through sd->s_sibling */ - struct sysfs_dirent *children; unsigned long subdirs; + struct rb_root inode_tree; struct rb_root name_tree; }; @@ -61,9 +60,9 @@ struct sysfs_dirent { struct lockdep_map dep_map; #endif struct sysfs_dirent *s_parent; - struct sysfs_dirent *s_sibling; const char *s_name; + struct rb_node inode_node; struct rb_node name_node; union { -- cgit v1.2.3-55-g7522 From 4e0b72fd7444e07e2870d193ce8fb6b0b00f5a89 Mon Sep 17 00:00:00 2001 From: Hans J. Koch Date: Tue, 9 Aug 2011 20:53:41 +0200 Subject: uio: uio_pci_generic: Remove useless spin_lock The spin_lock in uio_pci_generic.c is only used in the interrupt handler, which cannot be executed twice at the same time. That makes the lock rather pointless. This patch removes it. Cc: "Michael S. Tsirkin" Cc: Chris Wright Cc: Jesse Barnes Cc: Sebastian Andrzej Siewior Cc: Anthony Foiani Reported-by: Anthony Foiani Reported-by: Sebastian Andrzej Siewior Signed-off-by: Hans J. Koch Acked-by: Michael S. Tsirkin Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio_pci_generic.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/uio/uio_pci_generic.c b/drivers/uio/uio_pci_generic.c index fc22e1e6f215..02bd47bdee1c 100644 --- a/drivers/uio/uio_pci_generic.c +++ b/drivers/uio/uio_pci_generic.c @@ -24,7 +24,6 @@ #include #include #include -#include #define DRIVER_VERSION "0.01.0" #define DRIVER_AUTHOR "Michael S. Tsirkin " @@ -33,7 +32,6 @@ struct uio_pci_generic_dev { struct uio_info info; struct pci_dev *pdev; - spinlock_t lock; /* guards command register accesses */ }; static inline struct uio_pci_generic_dev * @@ -57,7 +55,6 @@ static irqreturn_t irqhandler(int irq, struct uio_info *info) BUILD_BUG_ON(PCI_COMMAND % 4); BUILD_BUG_ON(PCI_COMMAND + 2 != PCI_STATUS); - spin_lock_irq(&gdev->lock); pci_block_user_cfg_access(pdev); /* Read both command and status registers in a single 32-bit operation. @@ -83,7 +80,6 @@ static irqreturn_t irqhandler(int irq, struct uio_info *info) done: pci_unblock_user_cfg_access(pdev); - spin_unlock_irq(&gdev->lock); return ret; } @@ -158,7 +154,6 @@ static int __devinit probe(struct pci_dev *pdev, gdev->info.irq_flags = IRQF_SHARED; gdev->info.handler = irqhandler; gdev->pdev = pdev; - spin_lock_init(&gdev->lock); if (uio_register_device(&pdev->dev, &gdev->info)) goto err_register; -- cgit v1.2.3-55-g7522 From d80df1cea036ce8b6064b3b08dd58ad3eb55a6e9 Mon Sep 17 00:00:00 2001 From: Wanlong Gao Date: Sat, 20 Aug 2011 12:12:08 +0800 Subject: drivers:uio:change the goto label to consistent with others Remove one *goto* label in uio.c. Signed-off-by: Wanlong Gao Signed-off-by: "Hans J. Koch" Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index d2efe823c20d..c89f12a8b116 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c @@ -750,14 +750,13 @@ static int uio_major_init(void) uio_major = MAJOR(uio_dev); uio_cdev = cdev; - result = 0; -out: - return result; + return 0; out_put: kobject_put(&cdev->kobj); out_unregister: unregister_chrdev_region(uio_dev, UIO_MAX_DEVICES); - goto out; +out: + return result; } static void uio_major_cleanup(void) -- cgit v1.2.3-55-g7522 From 9245acd20d58d5a9a3ed5ebf8c486e0609027817 Mon Sep 17 00:00:00 2001 From: Wanlong Gao Date: Sat, 20 Aug 2011 12:12:07 +0800 Subject: drivers:uio:fix section mismatch in uio_pdrv_genirq.c Remove the __devinitconst to fix the section mismatch. WARNING: drivers/uio/built-in.o(.data+0x2e8): Section mismatch in reference from the variable uio_pdrv_genirq to the variable .devinit.rodata:uio_of_genirq_match The variable uio_pdrv_genirq references the variable __devinitconst uio_of_genirq_match If the reference is valid then annotate the variable with __init* or __refdata (see linux/init.h) or name the variable: *driver, *_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console Signed-off-by: Wanlong Gao Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio_pdrv_genirq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c index bae96d246760..0b2ed71e3bfa 100644 --- a/drivers/uio/uio_pdrv_genirq.c +++ b/drivers/uio/uio_pdrv_genirq.c @@ -253,7 +253,7 @@ static const struct dev_pm_ops uio_pdrv_genirq_dev_pm_ops = { }; #ifdef CONFIG_OF -static const struct of_device_id __devinitconst uio_of_genirq_match[] = { +static const struct of_device_id uio_of_genirq_match[] = { { /* empty for now */ }, }; MODULE_DEVICE_TABLE(of, uio_of_genirq_match); -- cgit v1.2.3-55-g7522 From 0a26813c9f528f17901b2f2394fba8557d2c9485 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 15 Aug 2011 16:51:22 +0200 Subject: drivers_base: platform: use always ->name for uevent If id_entry is available then it is used. However if we remove first the driver followed by the device, then the id_entry is pointing to driver's memory which is long gone. Since id->name and plat->name are equal there is no point in distinguishing them. Cc: Grant Likely Cc: linux-kernel@vger.kernel.org Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Greg Kroah-Hartman --- drivers/base/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 0cad9c7f6bb5..cd7157575e58 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -614,7 +614,7 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) return rc; add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, - (pdev->id_entry) ? pdev->id_entry->name : pdev->name); + pdev->name); return 0; } -- cgit v1.2.3-55-g7522 From dd7d7fea29c18b818e94f252a76f495490d399c3 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Thu, 21 Jul 2011 17:07:08 +0900 Subject: pch_phub: Care FUNCSEL register in PM Only ML7213/ML7223(Bus-n) has this register. Currently,this driver doesn't care register "FUNCSEL" in suspend/resume. This patch saves/restores FUNCSEL register only when the device is ML7213 or ML7223(Bus-n). Signed-off-by: Tomoya MORINAGA Signed-off-by: Greg Kroah-Hartman --- drivers/misc/pch_phub.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c index 0fd7e77bee29..61ece53f2f41 100644 --- a/drivers/misc/pch_phub.c +++ b/drivers/misc/pch_phub.c @@ -90,6 +90,7 @@ #define PCH_PHUB_INTPIN_REG_WPERMIT_REG3 0x002C #define PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE 0x0040 #define CLKCFG_REG_OFFSET 0x500 +#define FUNCSEL_REG_OFFSET 0x508 #define PCH_PHUB_OROM_SIZE 15360 @@ -108,6 +109,7 @@ * @intpin_reg_wpermit_reg3: INTPIN_REG_WPERMIT register 3 val * @int_reduce_control_reg: INT_REDUCE_CONTROL registers val * @clkcfg_reg: CLK CFG register val + * @funcsel_reg: Function select register value * @pch_phub_base_address: Register base address * @pch_phub_extrom_base_address: external rom base address * @pch_mac_start_address: MAC address area start address @@ -128,6 +130,7 @@ struct pch_phub_reg { u32 intpin_reg_wpermit_reg3; u32 int_reduce_control_reg[MAX_NUM_INT_REDUCE_CONTROL_REG]; u32 clkcfg_reg; + u32 funcsel_reg; void __iomem *pch_phub_base_address; void __iomem *pch_phub_extrom_base_address; u32 pch_mac_start_address; @@ -211,6 +214,8 @@ static void pch_phub_save_reg_conf(struct pci_dev *pdev) __func__, i, chip->int_reduce_control_reg[i]); } chip->clkcfg_reg = ioread32(p + CLKCFG_REG_OFFSET); + if ((chip->ioh_type == 2) || (chip->ioh_type == 4)) + chip->funcsel_reg = ioread32(p + FUNCSEL_REG_OFFSET); } /* pch_phub_restore_reg_conf - restore register configuration */ @@ -271,6 +276,8 @@ static void pch_phub_restore_reg_conf(struct pci_dev *pdev) } iowrite32(chip->clkcfg_reg, p + CLKCFG_REG_OFFSET); + if ((chip->ioh_type == 2) || (chip->ioh_type == 4)) + iowrite32(chip->funcsel_reg, p + FUNCSEL_REG_OFFSET); } /** -- cgit v1.2.3-55-g7522 From 25b8a88c10770e8c3f14bf2e222691dc6e79de78 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 18 Jul 2011 11:22:06 +0300 Subject: pch_phub: use kernel's '%pM' format option to print MAC Signed-off-by: Andy Shevchenko Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/misc/pch_phub.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c index 61ece53f2f41..dee33addcaeb 100644 --- a/drivers/misc/pch_phub.c +++ b/drivers/misc/pch_phub.c @@ -601,8 +601,7 @@ static ssize_t show_pch_mac(struct device *dev, struct device_attribute *attr, pch_phub_read_gbe_mac_addr(chip, mac); - return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return sprintf(buf, "%pM\n", mac); } static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr, -- cgit v1.2.3-55-g7522 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 --- drivers/base/core.c | 5 +++-- include/linux/device.h | 5 +++++ include/linux/dynamic_debug.h | 10 ++++++++-- lib/dynamic_debug.c | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 4 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index bc8729d603a7..82c865452c70 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1764,8 +1764,8 @@ void device_shutdown(void) #ifdef CONFIG_PRINTK -static int __dev_printk(const char *level, const struct device *dev, - struct va_format *vaf) +int __dev_printk(const char *level, const struct device *dev, + struct va_format *vaf) { if (!dev) return printk("%s(NULL device *): %pV", level, vaf); @@ -1773,6 +1773,7 @@ static int __dev_printk(const char *level, const struct device *dev, return printk("%s%s %s: %pV", level, dev_driver_string(dev), dev_name(dev), vaf); } +EXPORT_SYMBOL(__dev_printk); int dev_printk(const char *level, const struct device *dev, const char *fmt, ...) diff --git a/include/linux/device.h b/include/linux/device.h index c20dfbfc49b4..4639419522da 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -785,6 +785,8 @@ extern const char *dev_driver_string(const struct device *dev); #ifdef CONFIG_PRINTK +extern int __dev_printk(const char *level, const struct device *dev, + struct va_format *vaf); extern int dev_printk(const char *level, const struct device *dev, const char *fmt, ...) __attribute__ ((format (printf, 3, 4))); @@ -805,6 +807,9 @@ extern int _dev_info(const struct device *dev, const char *fmt, ...) #else +static inline int __dev_printk(const char *level, const struct device *dev, + struct va_format *vaf) + { return 0; } static inline int dev_printk(const char *level, const struct device *dev, const char *fmt, ...) __attribute__ ((format (printf, 3, 4))); diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index e747ecd48e1c..bdf15319944e 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h @@ -47,6 +47,13 @@ extern int ddebug_remove_module(const char *mod_name); extern int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); +struct device; + +extern int __dynamic_dev_dbg(struct _ddebug *descriptor, + const struct device *dev, + const char *fmt, ...) + __attribute__ ((format (printf, 3, 4))); + #define dynamic_pr_debug(fmt, ...) do { \ static struct _ddebug descriptor \ __used \ @@ -57,7 +64,6 @@ extern int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...) __dynamic_pr_debug(&descriptor, pr_fmt(fmt), ##__VA_ARGS__); \ } while (0) - #define dynamic_dev_dbg(dev, fmt, ...) do { \ static struct _ddebug descriptor \ __used \ @@ -65,7 +71,7 @@ extern int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...) { KBUILD_MODNAME, __func__, __FILE__, fmt, __LINE__, \ _DPRINTK_FLAGS_DEFAULT }; \ if (unlikely(descriptor.enabled)) \ - dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); \ + __dynamic_dev_dbg(&descriptor, dev, fmt, ##__VA_ARGS__); \ } while (0) #else 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 v1.2.3-55-g7522 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(-) 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 v1.2.3-55-g7522 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(-) 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 v1.2.3-55-g7522 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(-) 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 v1.2.3-55-g7522 From fae8d206a188080d3d23b621fc2652f15f3457b6 Mon Sep 17 00:00:00 2001 From: Jason Baron Date: Thu, 11 Aug 2011 14:36:38 -0400 Subject: dynamic_debug: remove unused control variables Remove no longer used dynamic debug control variables. The definitions were removed a while ago, but we forgot to clean up the extern references. Signed-off-by: Jason Baron Signed-off-by: Greg Kroah-Hartman --- include/linux/dynamic_debug.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index bdf15319944e..843cb9eb4226 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h @@ -1,13 +1,6 @@ #ifndef _DYNAMIC_DEBUG_H #define _DYNAMIC_DEBUG_H -/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which - * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They - * use independent hash functions, to reduce the chance of false positives. - */ -extern long long dynamic_debug_enabled; -extern long long dynamic_debug_enabled2; - /* * An instance of this structure is created in a special * ELF section at every dynamic debug callsite. At runtime, -- cgit v1.2.3-55-g7522 From ac0ac38f68be73b92dc390ceace50a0d143d76ae Mon Sep 17 00:00:00 2001 From: Jason Baron Date: Thu, 11 Aug 2011 14:36:43 -0400 Subject: dynamic_debug: add Jason Baron as maintainer Add a maintainers entry for dynamic debug. Hopefully nobody will object to me as maintainer... Signed-off-by: Jason Baron Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 069ee3b5c651..476209c40395 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2297,6 +2297,12 @@ L: netdev@vger.kernel.org S: Maintained F: drivers/net/wan/dscc4.c +DYNAMIC DEBUG +M: Jason Baron +S: Maintained +F: lib/dynamic_debug.c +F: include/linux/dynamic_debug.h + DZ DECSTATION DZ11 SERIAL DRIVER M: "Maciej W. Rozycki" S: Maintained -- cgit v1.2.3-55-g7522 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 --- include/linux/dynamic_debug.h | 17 +++++++++++++++++ include/linux/netdevice.h | 6 ++++-- lib/dynamic_debug.c | 25 +++++++++++++++++++++++++ net/core/dev.c | 3 ++- 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index 843cb9eb4226..feaac1ee3001 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h @@ -47,6 +47,13 @@ extern int __dynamic_dev_dbg(struct _ddebug *descriptor, const char *fmt, ...) __attribute__ ((format (printf, 3, 4))); +struct net_device; + +extern int __dynamic_netdev_dbg(struct _ddebug *descriptor, + const struct net_device *dev, + const char *fmt, ...) + __attribute__ ((format (printf, 3, 4))); + #define dynamic_pr_debug(fmt, ...) do { \ static struct _ddebug descriptor \ __used \ @@ -67,6 +74,16 @@ extern int __dynamic_dev_dbg(struct _ddebug *descriptor, __dynamic_dev_dbg(&descriptor, dev, fmt, ##__VA_ARGS__); \ } while (0) +#define dynamic_netdev_dbg(dev, fmt, ...) do { \ + static struct _ddebug descriptor \ + __used \ + __attribute__((section("__verbose"), aligned(8))) = \ + { KBUILD_MODNAME, __func__, __FILE__, fmt, __LINE__, \ + _DPRINTK_FLAGS_DEFAULT }; \ + if (unlikely(descriptor.enabled)) \ + __dynamic_netdev_dbg(&descriptor, dev, fmt, ##__VA_ARGS__);\ + } while (0) + #else static inline int ddebug_remove_module(const char *mod) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index ddee79bb8f15..9333a0300c5e 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2617,6 +2617,9 @@ static inline const char *netdev_name(const struct net_device *dev) return dev->name; } +extern int __netdev_printk(const char *level, const struct net_device *dev, + struct va_format *vaf); + extern int netdev_printk(const char *level, const struct net_device *dev, const char *format, ...) __attribute__ ((format (printf, 3, 4))); @@ -2644,8 +2647,7 @@ extern int netdev_info(const struct net_device *dev, const char *format, ...) #elif defined(CONFIG_DYNAMIC_DEBUG) #define netdev_dbg(__dev, format, args...) \ do { \ - dynamic_dev_dbg((__dev)->dev.parent, "%s: " format, \ - netdev_name(__dev), ##args); \ + dynamic_netdev_dbg(__dev, format, ##args); \ } while (0) #else #define netdev_dbg(__dev, format, args...) \ 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) { diff --git a/net/core/dev.c b/net/core/dev.c index 17d67b579beb..c47a7bcf3c64 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -6290,7 +6290,7 @@ const char *netdev_drivername(const struct net_device *dev) return empty; } -static int __netdev_printk(const char *level, const struct net_device *dev, +int __netdev_printk(const char *level, const struct net_device *dev, struct va_format *vaf) { int r; @@ -6305,6 +6305,7 @@ static int __netdev_printk(const char *level, const struct net_device *dev, return r; } +EXPORT_SYMBOL(__netdev_printk); int netdev_printk(const char *level, const struct net_device *dev, const char *format, ...) -- cgit v1.2.3-55-g7522 From b5fb0a03214dfd02bc34bda659d5b89ef12741b2 Mon Sep 17 00:00:00 2001 From: Jason Baron Date: Thu, 11 Aug 2011 14:36:53 -0400 Subject: dynamic_debug: make netif_dbg() call __netdev_printk() Previously, netif_dbg() was using dynamic_dev_dbg() to perform the underlying printk. Fix it to use __netdev_printk(), instead. Cc: David S. Miller Signed-off-by: Jason Baron Signed-off-by: Greg Kroah-Hartman --- include/linux/netdevice.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 9333a0300c5e..279726039f00 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2714,9 +2714,7 @@ do { \ #define netif_dbg(priv, type, netdev, format, args...) \ do { \ if (netif_msg_##type(priv)) \ - dynamic_dev_dbg((netdev)->dev.parent, \ - "%s: " format, \ - netdev_name(netdev), ##args); \ + dynamic_netdev_dbg(netdev, format, ##args); \ } while (0) #else #define netif_dbg(priv, type, dev, format, args...) \ -- cgit v1.2.3-55-g7522 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(-) 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 v1.2.3-55-g7522 From d58cb9cc8a46c9e539cbf8007cd5ede3c09c3524 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 23 Aug 2011 19:27:27 +0200 Subject: docs/driver-model: Document device.groups Several drivers use device_create_file() where device.groups should be used instead. This patch documents that and also removes the comments about device classes since these should not be used in new code in the way documented until now in Documentation/driver-model/device.txt. Signed-off-by: Bart Van Assche Cc: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- Documentation/driver-model/device.txt | 65 +++++++++++++++++------------------ 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/Documentation/driver-model/device.txt b/Documentation/driver-model/device.txt index bdefe728a737..1e70220d20f4 100644 --- a/Documentation/driver-model/device.txt +++ b/Documentation/driver-model/device.txt @@ -45,33 +45,52 @@ struct device_attribute { const char *buf, size_t count); }; -Attributes of devices can be exported via drivers using a simple -procfs-like interface. +Attributes of devices can be exported by a device driver through sysfs. Please see Documentation/filesystems/sysfs.txt for more information on how sysfs works. +As explained in Documentation/kobject.txt, device attributes must be be +created before the KOBJ_ADD uevent is generated. The only way to realize +that is by defining an attribute group. + Attributes are declared using a macro called DEVICE_ATTR: #define DEVICE_ATTR(name,mode,show,store) Example: -DEVICE_ATTR(power,0644,show_power,store_power); +static DEVICE_ATTR(type, 0444, show_type, NULL); +static DEVICE_ATTR(power, 0644, show_power, store_power); -This declares a structure of type struct device_attribute named -'dev_attr_power'. This can then be added and removed to the device's -directory using: +This declares two structures of type struct device_attribute with respective +names 'dev_attr_type' and 'dev_attr_power'. These two attributes can be +organized as follows into a group: -int device_create_file(struct device *device, struct device_attribute * entry); -void device_remove_file(struct device * dev, struct device_attribute * attr); +static struct attribute *dev_attrs[] = { + &dev_attr_type.attr, + &dev_attr_power.attr, + NULL, +}; -Example: +static struct attribute_group dev_attr_group = { + .attrs = dev_attrs, +}; + +static const struct attribute_group *dev_attr_groups[] = { + &dev_attr_group, + NULL, +}; + +This array of groups can then be associated with a device by setting the +group pointer in struct device before device_register() is invoked: -device_create_file(dev,&dev_attr_power); -device_remove_file(dev,&dev_attr_power); + dev->groups = dev_attr_groups; + device_register(dev); -The file name will be 'power' with a mode of 0644 (-rw-r--r--). +The device_register() function will use the 'groups' pointer to create the +device attributes and the device_unregister() function will use this pointer +to remove the device attributes. Word of warning: While the kernel allows device_create_file() and device_remove_file() to be called on a device at any time, userspace has @@ -84,24 +103,4 @@ not know about the new attributes. This is important for device driver that need to publish additional attributes for a device at driver probe time. If the device driver simply calls device_create_file() on the device structure passed to it, then -userspace will never be notified of the new attributes. Instead, it should -probably use class_create() and class->dev_attrs to set up a list of -desired attributes in the modules_init function, and then in the .probe() -hook, and then use device_create() to create a new device as a child -of the probed device. The new device will generate a new uevent and -properly advertise the new attributes to userspace. - -For example, if a driver wanted to add the following attributes: -struct device_attribute mydriver_attribs[] = { - __ATTR(port_count, 0444, port_count_show), - __ATTR(serial_number, 0444, serial_number_show), - NULL -}; - -Then in the module init function is would do: - mydriver_class = class_create(THIS_MODULE, "my_attrs"); - mydriver_class.dev_attr = mydriver_attribs; - -And assuming 'dev' is the struct device passed into the probe hook, the driver -probe function would do something like: - device_create(&mydriver_class, dev, chrdev, &private_data, "my_name"); +userspace will never be notified of the new attributes. -- cgit v1.2.3-55-g7522 From b7565fa3a4b84460ce1765cc468700a6bfd82746 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 23 Aug 2011 19:28:43 +0200 Subject: docs/driver-model: Update device class docs The driver model documentation was added to the kernel tree before struct class was added to . Hence this patch that updates the paragraph about struct class in Documentation/driver-model/binding.txt. Signed-off-by: Bart Van Assche Cc: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- Documentation/driver-model/binding.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Documentation/driver-model/binding.txt b/Documentation/driver-model/binding.txt index f7ec9d625bfc..abfc8e290d53 100644 --- a/Documentation/driver-model/binding.txt +++ b/Documentation/driver-model/binding.txt @@ -48,10 +48,6 @@ devclass_add_device is called to enumerate the device within the class and actually register it with the class, which happens with the class's register_dev callback. -NOTE: The device class structures and core routines to manipulate them -are not in the mainline kernel, so the discussion is still a bit -speculative. - Driver ~~~~~~ -- cgit v1.2.3-55-g7522 From 01dcc60a7cb8cd5193676554b94a90d349bdfd15 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-K枚nig Date: Thu, 25 Aug 2011 11:16:00 +0200 Subject: new helper to create platform devices with dma mask compared to the most powerful and already existing helper (namely platform_device_register_resndata) this allows to specify a dma_mask. To make eventual extensions later more easy, a struct holding the used information is created instead of passing the information by function parameters. Signed-off-by: Uwe Kleine-K枚nig Signed-off-by: Greg Kroah-Hartman --- drivers/base/platform.c | 52 +++++++++++++++++++++++++---------------- include/linux/platform_device.h | 48 +++++++++++++++++++++++++++++++++++-- 2 files changed, 78 insertions(+), 22 deletions(-) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index cd7157575e58..4573f5ec9367 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -375,52 +375,64 @@ void platform_device_unregister(struct platform_device *pdev) EXPORT_SYMBOL_GPL(platform_device_unregister); /** - * platform_device_register_resndata - add a platform-level device with + * platform_device_register_full - add a platform-level device with * resources and platform-specific data * - * @parent: parent device for the device we're adding - * @name: base name of the device we're adding - * @id: instance id - * @res: set of resources that needs to be allocated for the device - * @num: number of resources - * @data: platform specific data for this platform device - * @size: size of platform specific data + * @pdevinfo: data used to create device * * Returns &struct platform_device pointer on success, or ERR_PTR() on error. */ -struct platform_device *platform_device_register_resndata( - struct device *parent, - const char *name, int id, - const struct resource *res, unsigned int num, - const void *data, size_t size) +struct platform_device *platform_device_register_full( + struct platform_device_info *pdevinfo) { int ret = -ENOMEM; struct platform_device *pdev; - pdev = platform_device_alloc(name, id); + pdev = platform_device_alloc(pdevinfo->name, pdevinfo->id); if (!pdev) - goto err; - - pdev->dev.parent = parent; + goto err_alloc; + + pdev->dev.parent = pdevinfo->parent; + + if (pdevinfo->dma_mask) { + /* + * This memory isn't freed when the device is put, + * I don't have a nice idea for that though. Conceptually + * dma_mask in struct device should not be a pointer. + * See http://thread.gmane.org/gmane.linux.kernel.pci/9081 + */ + pdev->dev.dma_mask = + kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL); + if (!pdev->dev.dma_mask) + goto err; + + *pdev->dev.dma_mask = pdevinfo->dma_mask; + pdev->dev.coherent_dma_mask = pdevinfo->dma_mask; + } - ret = platform_device_add_resources(pdev, res, num); + ret = platform_device_add_resources(pdev, + pdevinfo->res, pdevinfo->num_res); if (ret) goto err; - ret = platform_device_add_data(pdev, data, size); + ret = platform_device_add_data(pdev, + pdevinfo->data, pdevinfo->size_data); if (ret) goto err; ret = platform_device_add(pdev); if (ret) { err: + kfree(pdev->dev.dma_mask); + +err_alloc: platform_device_put(pdev); return ERR_PTR(ret); } return pdev; } -EXPORT_SYMBOL_GPL(platform_device_register_resndata); +EXPORT_SYMBOL_GPL(platform_device_register_full); static int platform_drv_probe(struct device *_dev) { diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 27bb05aae70d..651a066686ac 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -49,10 +49,54 @@ extern struct resource *platform_get_resource_byname(struct platform_device *, u extern int platform_get_irq_byname(struct platform_device *, const char *); extern int platform_add_devices(struct platform_device **, int); -extern struct platform_device *platform_device_register_resndata( +struct platform_device_info { + struct device *parent; + + const char *name; + int id; + + const struct resource *res; + unsigned int num_res; + + const void *data; + size_t size_data; + u64 dma_mask; +}; +extern struct platform_device *platform_device_register_full( + struct platform_device_info *pdevinfo); + +/** + * platform_device_register_resndata - add a platform-level device with + * resources and platform-specific data + * + * @parent: parent device for the device we're adding + * @name: base name of the device we're adding + * @id: instance id + * @res: set of resources that needs to be allocated for the device + * @num: number of resources + * @data: platform specific data for this platform device + * @size: size of platform specific data + * + * Returns &struct platform_device pointer on success, or ERR_PTR() on error. + */ +static inline struct platform_device *platform_device_register_resndata( struct device *parent, const char *name, int id, const struct resource *res, unsigned int num, - const void *data, size_t size); + const void *data, size_t size) { + + struct platform_device_info pdevinfo = { + .parent = parent, + .name = name, + .id = id, + .res = res, + .num_res = num, + .data = data, + .size_data = size, + .dma_mask = 0, + }; + + return platform_device_register_full(&pdevinfo); +} /** * platform_device_register_simple - add a platform-level device and its resources -- cgit v1.2.3-55-g7522 From 0e392412f334c80baedb30a29796a256b0d5e629 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-K枚nig Date: Thu, 25 Aug 2011 11:16:01 +0200 Subject: ARM: mxc: convert device creation to use platform_device_register_full Signed-off-by: Uwe Kleine-K枚nig Signed-off-by: Greg Kroah-Hartman --- arch/arm/plat-mxc/devices.c | 53 ------------------------- arch/arm/plat-mxc/include/mach/devices-common.h | 16 +++++++- 2 files changed, 14 insertions(+), 55 deletions(-) diff --git a/arch/arm/plat-mxc/devices.c b/arch/arm/plat-mxc/devices.c index 0d6ed31bdbf2..a34b2ae895f2 100644 --- a/arch/arm/plat-mxc/devices.c +++ b/arch/arm/plat-mxc/devices.c @@ -37,59 +37,6 @@ int __init mxc_register_device(struct platform_device *pdev, void *data) return ret; } -struct platform_device *__init imx_add_platform_device_dmamask( - const char *name, int id, - const struct resource *res, unsigned int num_resources, - const void *data, size_t size_data, u64 dmamask) -{ - int ret = -ENOMEM; - struct platform_device *pdev; - - pdev = platform_device_alloc(name, id); - if (!pdev) - goto err; - - if (dmamask) { - /* - * This memory isn't freed when the device is put, - * I don't have a nice idea for that though. Conceptually - * dma_mask in struct device should not be a pointer. - * See http://thread.gmane.org/gmane.linux.kernel.pci/9081 - */ - pdev->dev.dma_mask = - kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL); - if (!pdev->dev.dma_mask) - /* ret is still -ENOMEM; */ - goto err; - - *pdev->dev.dma_mask = dmamask; - pdev->dev.coherent_dma_mask = dmamask; - } - - if (res) { - ret = platform_device_add_resources(pdev, res, num_resources); - if (ret) - goto err; - } - - if (data) { - ret = platform_device_add_data(pdev, data, size_data); - if (ret) - goto err; - } - - ret = platform_device_add(pdev); - if (ret) { -err: - if (dmamask) - kfree(pdev->dev.dma_mask); - platform_device_put(pdev); - return ERR_PTR(ret); - } - - return pdev; -} - struct device mxc_aips_bus = { .init_name = "mxc_aips", .parent = &platform_bus, diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h index 524538aabc4b..543525d76a60 100644 --- a/arch/arm/plat-mxc/include/mach/devices-common.h +++ b/arch/arm/plat-mxc/include/mach/devices-common.h @@ -14,10 +14,22 @@ extern struct device mxc_aips_bus; extern struct device mxc_ahb_bus; -struct platform_device *imx_add_platform_device_dmamask( +static inline struct platform_device *imx_add_platform_device_dmamask( const char *name, int id, const struct resource *res, unsigned int num_resources, - const void *data, size_t size_data, u64 dmamask); + const void *data, size_t size_data, u64 dmamask) +{ + struct platform_device_info pdevinfo = { + .name = name, + .id = id, + .res = res, + .num_res = num_resources, + .data = data, + .size_data = size_data, + .dma_mask = dmamask, + }; + return platform_device_register_full(&pdevinfo); +} static inline struct platform_device *imx_add_platform_device( const char *name, int id, -- cgit v1.2.3-55-g7522 From 220c1ed1bd64b26a2edcd59ca9ff031e1b880727 Mon Sep 17 00:00:00 2001 From: Harry Wei Date: Sat, 24 Sep 2011 15:52:18 +0800 Subject: remove the messy code file Documentation/zh_CN/SubmitChecklist This patch can remove the messy code file Documentation/zh_CN/SumitChecklist. Of course, i will also fix this matter and proofread it again and then submit it again. Signed-off-by: Harry Wei Signed-off-by: Greg Kroah-Hartman --- Documentation/zh_CN/SubmitChecklist | 109 ------------------------------------ 1 file changed, 109 deletions(-) delete mode 100644 Documentation/zh_CN/SubmitChecklist diff --git a/Documentation/zh_CN/SubmitChecklist b/Documentation/zh_CN/SubmitChecklist deleted file mode 100644 index 4c741d6bc048..000000000000 --- a/Documentation/zh_CN/SubmitChecklist +++ /dev/null @@ -1,109 +0,0 @@ -Chinese translated version of Documentation/SubmitChecklist - -If you have any comment or update to the content, please contact the -original document maintainer directly. However, if you have a problem -communicating in English you can also ask the Chinese maintainer for -help. Contact the Chinese maintainer if this translation is outdated -or if there is a problem with the translation. - -Chinese maintainer: Harry Wei ---------------------------------------------------------------------- -Documentation/SubmitChecklist 的中文翻译 - -如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文 -交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻 -译存在问题,请联系中文版维护者。 - -中文版维护者: 贾威威 Harry Wei -中文版翻译者: 贾威威 Harry Wei -中文版校译者: 贾威威 Harry Wei - - -以下为正文 ---------------------------------------------------------------------- -Linux内核提交清单 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -这里有一些内核开发者应该做的基本事情,如果他们想看到自己的内核补丁提交 -被接受的更快。 - -这些都是超出Documentation/SubmittingPatches文档里所提供的以及其他 -关于提交Linux内核补丁的说明。 - -1:如果你使用了一个功能那么就#include定义/声明那个功能的那个文件。 - 不要依靠其他间接引入定义/声明那个功能的头文件。 - -2:构建简洁适用或者更改CONFIG选项 =y,=m,或者=n。 - 不要有编译警告/错误, 不要有链接警告/错误。 - -2b:通过 allnoconfig, allmodconfig - -2c:当使用 0=builddir 成功地构建 - -3:通过使用本地交叉编译工具或者其他一些构建产所,在多CPU框架上构建。 - -4:ppc64 是一个很好的检查交叉编译的框架,因为它往往把‘unsigned long’ - 当64位值来使用。 - -5:按照Documentation/CodingStyle文件里的详细描述,检查你补丁的整体风格。 - 使用补丁风格检查琐碎的违规(scripts/checkpatch.pl),审核员优先提交。 - 你应该调整遗留在你补丁中的所有违规。 - -6:任何更新或者改动CONFIG选项都不能打乱配置菜单。 - -7:所有的Kconfig选项更新都要有说明文字。 - -8:已经认真地总结了相关的Kconfig组合。这是很难通过测试做好的--脑力在这里下降。 - -9:检查具有简洁性。 - -10:使用'make checkstack'和'make namespacecheck'检查,然后修改所找到的问题。 - 注意:堆栈检查不会明确地出现问题,但是任何的一个函数在堆栈上使用多于512字节 - 都要准备修改。 - -11:包含kernel-doc到全局内核APIs文件。(不要求静态的函数,但是包含也无所谓。) - 使用'make htmldocs'或者'make mandocs'来检查kernel-doc,然后修改任何 - 发现的问题。 - -12:已经通过CONFIG_PREEMPT, CONFIG_DEBUG_PREEMPT, - CONFIG_DEBUG_SLAB, CONFIG_DEBUG_PAGEALLOC, CONFIG_DEBUG_MUTEXES, - CONFIG_DEBUG_SPINLOCK, CONFIG_DEBUG_ATOMIC_SLEEP测试,并且同时都 - 使能。 - -13:已经都构建并且使用或者不使用 CONFIG_SMP 和 CONFIG_PREEMPT测试执行时间。 - -14:如果补丁影响IO/Disk,等等:已经通过使用或者不使用 CONFIG_LBDAF 测试。 - -15:所有的codepaths已经行使所有lockdep启用功能。 - -16:所有的/proc记录更新都要作成文件放在Documentation/目录下。 - -17:所有的内核启动参数更新都被记录到Documentation/kernel-parameters.txt文件中。 - -18:所有的模块参数更新都用MODULE_PARM_DESC()记录。 - -19:所有的用户空间接口更新都被记录到Documentation/ABI/。查看Documentation/ABI/README - 可以获得更多的信息。改变用户空间接口的补丁应该被邮件抄送给linux-api@vger.kernel.org。 - -20:检查它是不是都通过`make headers_check'。 - -21:已经通过至少引入slab和page-allocation失败检查。查看Documentation/fault-injection/。 - -22:新加入的源码已经通过`gcc -W'(使用"make EXTRA_CFLAGS=-W")编译。这样将产生很多烦恼, - 但是对于寻找漏洞很有益处,例如:"warning: comparison between signed and unsigned"。 - -23:当它被合并到-mm补丁集后再测试,用来确定它是否还和补丁队列中的其他补丁一起工作以及在VM,VFS - 和其他子系统中各个变化。 - -24:所有的内存屏障{e.g., barrier(), rmb(), wmb()}需要在源代码中的一个注释来解释他们都是干什么的 - 以及原因。 - -25:如果有任何输入输出控制的补丁被添加,也要更新Documentation/ioctl/ioctl-number.txt。 - -26:如果你的更改代码依靠或者使用任何的内核APIs或者与下面的kconfig符号有关系的功能,你就要 - 使用相关的kconfig符号关闭, and/or =m(如果选项提供)[在同一时间不是所用的都启用,仅仅各个或者自由 - 组合他们]: - - CONFIG_SMP, CONFIG_SYSFS, CONFIG_PROC_FS, CONFIG_INPUT, CONFIG_PCI, - CONFIG_BLOCK, CONFIG_PM, CONFIG_HOTPLUG, CONFIG_MAGIC_SYSRQ, - CONFIG_NET, CONFIG_INET=n (后一个使用 CONFIG_NET=y) -- cgit v1.2.3-55-g7522 From 61b94feafa1c59a1de2719d23294dea6fd4ca362 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 15 Sep 2011 06:26:15 +1000 Subject: memory hotplug: Refuse to add unaligned memory regions The sysfs memory probe interface allows unaligned regions to be added: # echo 0xffffff > /sys/devices/system/memory/probe # cat /proc/iomem 00ffffff-01fffffe : System RAM 01ffffff-02fffffe : System RAM 02ffffff-03fffffe : System RAM 03ffffff-04fffffe : System RAM 04ffffff-05fffffe : System RAM Return -EINVAL instead of creating these bad regions. Signed-off-by: Anton Blanchard Signed-off-by: Greg Kroah-Hartman --- drivers/base/memory.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 2840ed4668c1..2a0b5f1020ed 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -380,9 +380,13 @@ memory_probe_store(struct class *class, struct class_attribute *attr, u64 phys_addr; int nid; int i, ret; + unsigned long pages_per_block = PAGES_PER_SECTION * sections_per_block; phys_addr = simple_strtoull(buf, NULL, 0); + if (phys_addr & ((pages_per_block << PAGE_SHIFT) - 1)) + return -EINVAL; + for (i = 0; i < sections_per_block; i++) { nid = memory_add_physaddr_to_nid(phys_addr); ret = add_memory(nid, phys_addr, -- cgit v1.2.3-55-g7522 From 54f23eb7ba7619de85d8edca6e5336bc33072dbd Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Mon, 26 Sep 2011 10:22:33 -0500 Subject: memory hotplug: Correct page reservation checking The check to ensure that pages of recently added memory sections are correctly marked as reserved before trying to online the memory is broken. The request to online the memory fails with the following: kernel: section number XXX page number 256 not reserved, was it already online? This updates the page reservation checking to check the pages of each memory section of the memory block being onlined individually. Signed-off-by: Nathan Fontenot Signed-off-by: Greg Kroah-Hartman --- drivers/base/memory.c | 60 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 2a0b5f1020ed..ca8bfe59ae32 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -227,41 +227,42 @@ int memory_isolate_notify(unsigned long val, void *v) * MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is * OK to have direct references to sparsemem variables in here. */ +static int check_page_reservations(unsigned long phys_index) +{ + int i; + struct page *page; + + page = pfn_to_page(phys_index << PFN_SECTION_SHIFT); + + for (i = 0; i < PAGES_PER_SECTION; i++) { + if (PageReserved(page + i)) + continue; + + printk(KERN_WARNING "section number %ld page number %d " + "not reserved, was it already online?\n", phys_index, i); + return -EBUSY; + } + + return 0; +} + static int memory_block_action(unsigned long phys_index, unsigned long action) { - int i; unsigned long start_pfn, start_paddr; unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block; - struct page *first_page; + struct page *page; int ret; - first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT); - - /* - * The probe routines leave the pages reserved, just - * as the bootmem code does. Make sure they're still - * that way. - */ - if (action == MEM_ONLINE) { - for (i = 0; i < nr_pages; i++) { - if (PageReserved(first_page+i)) - continue; - - printk(KERN_WARNING "section number %ld page number %d " - "not reserved, was it already online?\n", - phys_index, i); - return -EBUSY; - } - } + page = pfn_to_page(phys_index << PFN_SECTION_SHIFT); switch (action) { case MEM_ONLINE: - start_pfn = page_to_pfn(first_page); + start_pfn = page_to_pfn(page); ret = online_pages(start_pfn, nr_pages); break; case MEM_OFFLINE: - start_paddr = page_to_pfn(first_page) << PAGE_SHIFT; + start_paddr = page_to_pfn(page) << PAGE_SHIFT; ret = remove_memory(start_paddr, nr_pages << PAGE_SHIFT); break; @@ -277,7 +278,7 @@ memory_block_action(unsigned long phys_index, unsigned long action) static int memory_block_change_state(struct memory_block *mem, unsigned long to_state, unsigned long from_state_req) { - int ret = 0; + int i, ret = 0; mutex_lock(&mem->state_mutex); @@ -289,6 +290,19 @@ static int memory_block_change_state(struct memory_block *mem, if (to_state == MEM_OFFLINE) mem->state = MEM_GOING_OFFLINE; + if (to_state == MEM_ONLINE) { + /* + * The probe routines leave the pages reserved, just + * as the bootmem code does. Make sure they're still + * that way. + */ + for (i = 0; i < sections_per_block; i++) { + ret = check_page_reservations(mem->start_section_nr + i); + if (ret) + return ret; + } + } + ret = memory_block_action(mem->start_section_nr, to_state); if (ret) -- cgit v1.2.3-55-g7522 From bcbe4f94d15ae1c985336bb3c35605e595fdde0d Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 20 Sep 2011 19:41:17 +0200 Subject: drivers: base: print rejected matches with DEBUG_DRIVER When DEBUG_DRIVER is activated, be verbose and explicitly state when a device<->driver match was rejected by the probe-function of the driver. Now all code-paths report what is currently happening which helps debugging, because you don't have to remember that no printout means the match is rejected (and then you still don't know if it was because of ENODEV or ENXIO). Signed-off-by: Wolfram Sang Signed-off-by: Greg Kroah-Hartman --- drivers/base/dd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 6658da743c3a..142e3d600f14 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -147,6 +147,9 @@ probe_failed: printk(KERN_WARNING "%s: probe of %s failed with error %d\n", drv->name, dev_name(dev), ret); + } else { + pr_debug("%s: probe of %s rejects match %d\n", + drv->name, dev_name(dev), ret); } /* * Ignore errors returned by ->probe so that the next driver can try -- cgit v1.2.3-55-g7522 From c4253cb0748cd50060d04d838c38b07f1ad0e6e5 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 22 Sep 2011 19:34:33 +0200 Subject: sysfs: add unsigned long cast to prevent compile warning "sysfs: use rb-tree for inode number lookup" added a new printk which causes a new compile warning on s390 (and few other architectures): fs/sysfs/dir.c: In function 'sysfs_link_sibling': fs/sysfs/dir.c:63:4: warning: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'ino_t' [-Wform Add an explicit unsigned long cast since ino_t is an unsigned long on most architectures. Cc: Mikulas Patocka Signed-off-by: Heiko Carstens Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/dir.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index c3646d93a032..83bb9d1f30aa 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -60,7 +60,8 @@ static void sysfs_link_sibling(struct sysfs_dirent *sd) } else if (sd->s_ino > node->s_ino) { p = &node->inode_node.rb_right; } else { - printk(KERN_CRIT "sysfs: inserting duplicate inode '%lx'\n", sd->s_ino); + printk(KERN_CRIT "sysfs: inserting duplicate inode '%lx'\n", + (unsigned long) sd->s_ino); BUG(); } #undef node -- cgit v1.2.3-55-g7522 From 27a90700a4275c5178b883b65927affdafa5185c Mon Sep 17 00:00:00 2001 From: Kai Jiang Date: Mon, 17 Oct 2011 20:50:20 +0200 Subject: uio: Support physical addresses >32 bits on 32-bit systems To support >32-bit physical addresses for UIO_MEM_PHYS type we need to extend the width of 'addr' in struct uio_mem. Numerous platforms like embedded PPC, ARM, and X86 have support for systems with larger physical address than logical. Since 'addr' may contain a physical, logical, or virtual address the easiest solution is to just change the type to 'phys_addr_t' which should always be greater than or equal to the sizeof(void *) such that it can properly hold any of the address types. For physical address we can support up to a 44-bit physical address on a typical 32-bit system as we utilize remap_pfn_range() for the mapping of the memory region and pfn's are represnted by shifting the address by the page size (typically 4k). Signed-off-by: Kai Jiang Signed-off-by: Minghuan Lian Signed-off-by: Kumar Gala Signed-off-by: Hans J. Koch Signed-off-by: Greg Kroah-Hartman --- Documentation/DocBook/uio-howto.tmpl | 2 +- drivers/uio/uio.c | 7 +++---- include/linux/uio_driver.h | 7 +++++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl index 7c4b514d62b1..54883de5d5f9 100644 --- a/Documentation/DocBook/uio-howto.tmpl +++ b/Documentation/DocBook/uio-howto.tmpl @@ -529,7 +529,7 @@ memory (e.g. allocated with kmalloc()). There's also -unsigned long addr: Required if the mapping is used. +phys_addr_t addr: Required if the mapping is used. Fill in the address of your memory block. This address is the one that appears in sysfs. diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index c89f12a8b116..a783d533a1a6 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c @@ -69,7 +69,7 @@ static ssize_t map_name_show(struct uio_mem *mem, char *buf) static ssize_t map_addr_show(struct uio_mem *mem, char *buf) { - return sprintf(buf, "0x%lx\n", mem->addr); + return sprintf(buf, "0x%llx\n", (unsigned long long)mem->addr); } static ssize_t map_size_show(struct uio_mem *mem, char *buf) @@ -79,7 +79,7 @@ static ssize_t map_size_show(struct uio_mem *mem, char *buf) static ssize_t map_offset_show(struct uio_mem *mem, char *buf) { - return sprintf(buf, "0x%lx\n", mem->addr & ~PAGE_MASK); + return sprintf(buf, "0x%llx\n", (unsigned long long)mem->addr & ~PAGE_MASK); } struct map_sysfs_entry { @@ -634,8 +634,7 @@ static int uio_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) if (idev->info->mem[mi].memtype == UIO_MEM_LOGICAL) page = virt_to_page(idev->info->mem[mi].addr + offset); else - page = vmalloc_to_page((void *)idev->info->mem[mi].addr - + offset); + page = vmalloc_to_page((void *)(unsigned long)idev->info->mem[mi].addr + offset); get_page(page); vmf->page = page; return 0; diff --git a/include/linux/uio_driver.h b/include/linux/uio_driver.h index 665517c05eaf..fd99ff9298c6 100644 --- a/include/linux/uio_driver.h +++ b/include/linux/uio_driver.h @@ -23,7 +23,10 @@ struct uio_map; /** * struct uio_mem - description of a UIO memory region * @name: name of the memory region for identification - * @addr: address of the device's memory + * @addr: address of the device's memory (phys_addr is used since + * addr can be logical, virtual, or physical & phys_addr_t + * should always be large enough to handle any of the + * address types) * @size: size of IO * @memtype: type of memory addr points to * @internal_addr: ioremap-ped version of addr, for driver internal use @@ -31,7 +34,7 @@ struct uio_map; */ struct uio_mem { const char *name; - unsigned long addr; + phys_addr_t addr; unsigned long size; int memtype; void __iomem *internal_addr; -- cgit v1.2.3-55-g7522 From 07613b0b5ef8570033aa806d1731dce599862223 Mon Sep 17 00:00:00 2001 From: Jason Baron Date: Tue, 4 Oct 2011 14:13:15 -0700 Subject: dynamic_debug: consolidate repetitive struct _ddebug descriptor definitions Replace the repetitive struct _ddebug descriptor definitions with a new DECLARE_DYNAMIC_DEBUG_META_DATA(name, fmt) macro. [akpm@linux-foundation.org: s/DECLARE/DEFINE/] Signed-off-by: Jason Baron Cc: Arnd Bergmann Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- include/linux/dynamic_debug.h | 64 +++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index feaac1ee3001..13aae8087b56 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h @@ -54,35 +54,41 @@ extern int __dynamic_netdev_dbg(struct _ddebug *descriptor, const char *fmt, ...) __attribute__ ((format (printf, 3, 4))); -#define dynamic_pr_debug(fmt, ...) do { \ - static struct _ddebug descriptor \ - __used \ - __attribute__((section("__verbose"), aligned(8))) = \ - { KBUILD_MODNAME, __func__, __FILE__, fmt, __LINE__, \ - _DPRINTK_FLAGS_DEFAULT }; \ - if (unlikely(descriptor.enabled)) \ - __dynamic_pr_debug(&descriptor, pr_fmt(fmt), ##__VA_ARGS__); \ - } while (0) - -#define dynamic_dev_dbg(dev, fmt, ...) do { \ - static struct _ddebug descriptor \ - __used \ - __attribute__((section("__verbose"), aligned(8))) = \ - { KBUILD_MODNAME, __func__, __FILE__, fmt, __LINE__, \ - _DPRINTK_FLAGS_DEFAULT }; \ - if (unlikely(descriptor.enabled)) \ - __dynamic_dev_dbg(&descriptor, dev, fmt, ##__VA_ARGS__); \ - } while (0) - -#define dynamic_netdev_dbg(dev, fmt, ...) do { \ - static struct _ddebug descriptor \ - __used \ - __attribute__((section("__verbose"), aligned(8))) = \ - { KBUILD_MODNAME, __func__, __FILE__, fmt, __LINE__, \ - _DPRINTK_FLAGS_DEFAULT }; \ - if (unlikely(descriptor.enabled)) \ - __dynamic_netdev_dbg(&descriptor, dev, fmt, ##__VA_ARGS__);\ - } while (0) +#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \ + static struct _ddebug __used __aligned(8) \ + __attribute__((section("__verbose"))) name = { \ + .modname = KBUILD_MODNAME, \ + .function = __func__, \ + .filename = __FILE__, \ + .format = (fmt), \ + .lineno = __LINE__, \ + .flags = _DPRINTK_FLAGS_DEFAULT, \ + .enabled = false, \ + } + +#define dynamic_pr_debug(fmt, ...) \ +do { \ + DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ + if (unlikely(descriptor.enabled)) \ + __dynamic_pr_debug(&descriptor, pr_fmt(fmt), \ + ##__VA_ARGS__); \ +} while (0) + +#define dynamic_dev_dbg(dev, fmt, ...) \ +do { \ + DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ + if (unlikely(descriptor.enabled)) \ + __dynamic_dev_dbg(&descriptor, dev, fmt, \ + ##__VA_ARGS__); \ +} while (0) + +#define dynamic_netdev_dbg(dev, fmt, ...) \ +do { \ + DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ + if (unlikely(descriptor.enabled)) \ + __dynamic_netdev_dbg(&descriptor, dev, fmt, \ + ##__VA_ARGS__); \ +} while (0) #else -- cgit v1.2.3-55-g7522 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(-) 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 v1.2.3-55-g7522 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(-) 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 v1.2.3-55-g7522 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(+) 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 v1.2.3-55-g7522 From 5fa224295f0e0358c8bc0e5390702338df889def Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Mon, 17 Oct 2011 21:16:39 -0400 Subject: Update email address for stable patch submission The stable@kernel.org email address has been replaced with the stable@vger.kernel.org mailing list. Change the stable kernel rules to reference the new list instead of the semi-defunct email alias. CC: CC: Signed-off-by: Josh Boyer Signed-off-by: Greg Kroah-Hartman --- Documentation/stable_kernel_rules.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Documentation/stable_kernel_rules.txt b/Documentation/stable_kernel_rules.txt index e213f45cf9d7..21fd05c28e73 100644 --- a/Documentation/stable_kernel_rules.txt +++ b/Documentation/stable_kernel_rules.txt @@ -24,10 +24,10 @@ Rules on what kind of patches are accepted, and which ones are not, into the Procedure for submitting patches to the -stable tree: - Send the patch, after verifying that it follows the above rules, to - stable@kernel.org. You must note the upstream commit ID in the changelog - of your submission. + stable@vger.kernel.org. You must note the upstream commit ID in the + changelog of your submission. - To have the patch automatically included in the stable tree, add the tag - Cc: stable@kernel.org + Cc: stable@vger.kernel.org in the sign-off area. Once the patch is merged it will be applied to the stable tree without anything else needing to be done by the author or subsystem maintainer. @@ -35,10 +35,10 @@ Procedure for submitting patches to the -stable tree: cherry-picked than this can be specified in the following format in the sign-off area: - Cc: # .32.x: a1f84a3: sched: Check for idle - Cc: # .32.x: 1b9508f: sched: Rate-limit newidle - Cc: # .32.x: fd21073: sched: Fix affinity logic - Cc: # .32.x + Cc: # .32.x: a1f84a3: sched: Check for idle + Cc: # .32.x: 1b9508f: sched: Rate-limit newidle + Cc: # .32.x: fd21073: sched: Fix affinity logic + Cc: # .32.x Signed-off-by: Ingo Molnar The tag sequence has the meaning of: -- cgit v1.2.3-55-g7522 From de0ed36a3ecc0b51da4f16fa0af47ba6b7ffad22 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 18 Oct 2011 14:00:57 -0700 Subject: Revert "memory hotplug: Correct page reservation checking" This reverts commit 54f23eb7ba7619de85d8edca6e5336bc33072dbd. Turns out this patch is wrong, another correct one will follow it. Signed-off-by: Greg Kroah-Hartman --- drivers/base/memory.c | 60 ++++++++++++++++++++------------------------------- 1 file changed, 23 insertions(+), 37 deletions(-) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index ca8bfe59ae32..2a0b5f1020ed 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -227,42 +227,41 @@ int memory_isolate_notify(unsigned long val, void *v) * MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is * OK to have direct references to sparsemem variables in here. */ -static int check_page_reservations(unsigned long phys_index) -{ - int i; - struct page *page; - - page = pfn_to_page(phys_index << PFN_SECTION_SHIFT); - - for (i = 0; i < PAGES_PER_SECTION; i++) { - if (PageReserved(page + i)) - continue; - - printk(KERN_WARNING "section number %ld page number %d " - "not reserved, was it already online?\n", phys_index, i); - return -EBUSY; - } - - return 0; -} - static int memory_block_action(unsigned long phys_index, unsigned long action) { + int i; unsigned long start_pfn, start_paddr; unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block; - struct page *page; + struct page *first_page; int ret; - page = pfn_to_page(phys_index << PFN_SECTION_SHIFT); + first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT); + + /* + * The probe routines leave the pages reserved, just + * as the bootmem code does. Make sure they're still + * that way. + */ + if (action == MEM_ONLINE) { + for (i = 0; i < nr_pages; i++) { + if (PageReserved(first_page+i)) + continue; + + printk(KERN_WARNING "section number %ld page number %d " + "not reserved, was it already online?\n", + phys_index, i); + return -EBUSY; + } + } switch (action) { case MEM_ONLINE: - start_pfn = page_to_pfn(page); + start_pfn = page_to_pfn(first_page); ret = online_pages(start_pfn, nr_pages); break; case MEM_OFFLINE: - start_paddr = page_to_pfn(page) << PAGE_SHIFT; + start_paddr = page_to_pfn(first_page) << PAGE_SHIFT; ret = remove_memory(start_paddr, nr_pages << PAGE_SHIFT); break; @@ -278,7 +277,7 @@ memory_block_action(unsigned long phys_index, unsigned long action) static int memory_block_change_state(struct memory_block *mem, unsigned long to_state, unsigned long from_state_req) { - int i, ret = 0; + int ret = 0; mutex_lock(&mem->state_mutex); @@ -290,19 +289,6 @@ static int memory_block_change_state(struct memory_block *mem, if (to_state == MEM_OFFLINE) mem->state = MEM_GOING_OFFLINE; - if (to_state == MEM_ONLINE) { - /* - * The probe routines leave the pages reserved, just - * as the bootmem code does. Make sure they're still - * that way. - */ - for (i = 0; i < sections_per_block; i++) { - ret = check_page_reservations(mem->start_section_nr + i); - if (ret) - return ret; - } - } - ret = memory_block_action(mem->start_section_nr, to_state); if (ret) -- cgit v1.2.3-55-g7522 From 2bbcb8788311a40714b585fc11b51da6ffa2ab92 Mon Sep 17 00:00:00 2001 From: Mel Gorman Date: Mon, 17 Oct 2011 16:38:20 +0200 Subject: mm: memory hotplug: Check if pages are correctly reserved on a per-section basis (Resending as I am not seeing it in -next so maybe it got lost) mm: memory hotplug: Check if pages are correctly reserved on a per-section basis It is expected that memory being brought online is PageReserved similar to what happens when the page allocator is being brought up. Memory is onlined in "memory blocks" which consist of one or more sections. Unfortunately, the code that verifies PageReserved is currently assuming that the memmap backing all these pages is virtually contiguous which is only the case when CONFIG_SPARSEMEM_VMEMMAP is set. As a result, memory hot-add is failing on those configurations with the message; kernel: section number XXX page number 256 not reserved, was it already online? This patch updates the PageReserved check to lookup struct page once per section to guarantee the correct struct page is being checked. [Check pages within sections properly: rientjes@google.com] [original patch by: nfont@linux.vnet.ibm.com] Signed-off-by: Mel Gorman Acked-by: KAMEZAWA Hiroyuki Tested-by: Nathan Fontenot Signed-off-by: Greg Kroah-Hartman --- drivers/base/memory.c | 58 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 2a0b5f1020ed..8272d92d22c0 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -223,6 +223,42 @@ int memory_isolate_notify(unsigned long val, void *v) return atomic_notifier_call_chain(&memory_isolate_chain, val, v); } +/* + * The probe routines leave the pages reserved, just as the bootmem code does. + * Make sure they're still that way. + */ +static bool pages_correctly_reserved(unsigned long start_pfn, + unsigned long nr_pages) +{ + int i, j; + struct page *page; + unsigned long pfn = start_pfn; + + /* + * memmap between sections is not contiguous except with + * SPARSEMEM_VMEMMAP. We lookup the page once per section + * and assume memmap is contiguous within each section + */ + for (i = 0; i < sections_per_block; i++, pfn += PAGES_PER_SECTION) { + if (WARN_ON_ONCE(!pfn_valid(pfn))) + return false; + page = pfn_to_page(pfn); + + for (j = 0; j < PAGES_PER_SECTION; j++) { + if (PageReserved(page + j)) + continue; + + printk(KERN_WARNING "section number %ld page number %d " + "not reserved, was it already online?\n", + pfn_to_section_nr(pfn), j); + + return false; + } + } + + return true; +} + /* * MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is * OK to have direct references to sparsemem variables in here. @@ -230,7 +266,6 @@ int memory_isolate_notify(unsigned long val, void *v) static int memory_block_action(unsigned long phys_index, unsigned long action) { - int i; unsigned long start_pfn, start_paddr; unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block; struct page *first_page; @@ -238,26 +273,13 @@ memory_block_action(unsigned long phys_index, unsigned long action) first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT); - /* - * The probe routines leave the pages reserved, just - * as the bootmem code does. Make sure they're still - * that way. - */ - if (action == MEM_ONLINE) { - for (i = 0; i < nr_pages; i++) { - if (PageReserved(first_page+i)) - continue; - - printk(KERN_WARNING "section number %ld page number %d " - "not reserved, was it already online?\n", - phys_index, i); - return -EBUSY; - } - } - switch (action) { case MEM_ONLINE: start_pfn = page_to_pfn(first_page); + + if (!pages_correctly_reserved(start_pfn, nr_pages)) + return -EBUSY; + ret = online_pages(start_pfn, nr_pages); break; case MEM_OFFLINE: -- cgit v1.2.3-55-g7522