lkml.org 
[lkml]   [2009]   [Dec]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
SubjectRe: [PATCH 04/27] Driver core: devtmpfs: prevent concurrent subdirectory creation and removal
From
v2.6.33-rc1-96-gdd59f6c:

...
[ 0.868406] sched: BUG: sleeping function called from invalid
context at kernel/mutex.c:94
[ 0.868635] sched: in_atomic(): 1, irqs_disabled(): 0, pid: 642,
name: modprobe
[ 0.868858] Pid: 642, comm: modprobe Not tainted 2.6.33-rc1 #39
[ 0.868998] Call Trace:
[ 0.869157] [<c1024f88>] __might_sleep+0xef/0xf7
[ 0.869313] [<c129b6a3>] mutex_lock+0x1f/0x39
[ 0.869469] [<c10ca984>] do_lookup+0x87/0x139
[ 0.869615] [<c10cb02f>] link_path_walk+0x22b/0x520
[ 0.869755] [<c10cb435>] path_walk+0x3f/0x89
[ 0.869895] [<c10cb608>] vfs_path_lookup+0x53/0x99
[ 0.870038] [<c11e6a9b>] dev_mkdir.clone.0+0x23/0x8d
[ 0.870195] [<c10ca6ef>] ? mntput+0x18/0x1a
[ 0.870371] [<c10ca7d3>] ? path_put+0x1a/0x1d
[ 0.870522] [<c10cb63f>] ? vfs_path_lookup+0x8a/0x99
[ 0.870668] [<c129ee99>] ? add_preempt_count+0x8/0x75
[ 0.870808] [<c11e6bbc>] devtmpfs_create_node+0xb7/0x1f3
[ 0.870950] [<c10ffc78>] ? sysfs_find_dirent+0x1b/0x2c
[ 0.871091] [<c10fff50>] ? __sysfs_add_one+0x2a/0x78
[ 0.871249] [<c1100313>] ? sysfs_addrm_finish+0x1e/0x93
[ 0.871402] [<c11004d0>] ? sysfs_add_one+0x18/0xe1
[ 0.871542] [<c1100886>] ? sysfs_do_create_link+0xbc/0x109
[ 0.871683] [<c11008f3>] ? sysfs_create_link+0xf/0x14
[ 0.871823] [<c11e1e69>] device_add+0x141/0x44d
[ 0.871963] [<c1003935>] ? arch_irq_stat_cpu+0x5d/0xc8
[ 0.872137] [<c11e218c>] device_register+0x17/0x1a
[ 0.872290] [<c11e2206>] device_create_vargs+0x77/0x98
[ 0.872435] [<f8045000>] ? dm_init+0x0/0x3b [dm_mod]
[ 0.872574] [<c11e2247>] device_create+0x20/0x22
[ 0.872715] [<c11c96dc>] misc_register+0x9d/0xf1
[ 0.872859] [<f804521a>] dm_interface_init+0x36/0x74 [dm_mod]
[ 0.873003] [<f8045011>] dm_init+0x11/0x3b [dm_mod]
[ 0.873144] [<c1001143>] do_one_initcall+0x51/0x13f
[ 0.873311] [<c105c0db>] sys_init_module+0xac/0x1e0
[ 0.873456] [<c129c820>] syscall_call+0x7/0xb
....
[ 13.438106] sched: BUG: sleeping function called from invalid
context at kernel/mutex.c:94
[ 13.438110] sched: in_atomic(): 1, irqs_disabled(): 0, pid: 18387,
name: modprobe
[ 13.438114] Pid: 18387, comm: modprobe Not tainted 2.6.33-rc1 #39
[ 13.438116] Call Trace:
[ 13.438124] [<c1024f88>] __might_sleep+0xef/0xf7
[ 13.438129] [<c129b6a3>] mutex_lock+0x1f/0x39
[ 13.438133] [<c10ca984>] do_lookup+0x87/0x139
[ 13.438136] [<c10cb02f>] link_path_walk+0x22b/0x520
[ 13.438140] [<c10cb435>] path_walk+0x3f/0x89
[ 13.438143] [<c10cb608>] vfs_path_lookup+0x53/0x99
[ 13.438147] [<c11e6a9b>] dev_mkdir.clone.0+0x23/0x8d
[ 13.438150] [<c10ca6ef>] ? mntput+0x18/0x1a
[ 13.438153] [<c10ca7d3>] ? path_put+0x1a/0x1d
[ 13.438156] [<c10cb63f>] ? vfs_path_lookup+0x8a/0x99
[ 13.438159] [<c129ee99>] ? add_preempt_count+0x8/0x75
[ 13.438162] [<c11e6bbc>] devtmpfs_create_node+0xb7/0x1f3
[ 13.438166] [<c10ffc78>] ? sysfs_find_dirent+0x1b/0x2c
[ 13.438168] [<c10fff50>] ? __sysfs_add_one+0x2a/0x78
[ 13.438171] [<c1100313>] ? sysfs_addrm_finish+0x1e/0x93
[ 13.438173] [<c11004d0>] ? sysfs_add_one+0x18/0xe1
[ 13.438176] [<c1100886>] ? sysfs_do_create_link+0xbc/0x109
[ 13.438179] [<c11008f3>] ? sysfs_create_link+0xf/0x14
[ 13.438183] [<c11e1e69>] device_add+0x141/0x44d
[ 13.438187] [<c100323a>] ? do_stack_segment+0x33/0x5c
[ 13.438190] [<c11e218c>] device_register+0x17/0x1a
[ 13.438193] [<c11e2206>] device_create_vargs+0x77/0x98
[ 13.438196] [<c11e2247>] device_create+0x20/0x22
[ 13.438203] [<f9ea153a>] snd_register_device_for_dev+0xfa/0x158 [snd]
[ 13.438208] [<fa2150d5>] alsa_timer_init+0xd5/0x129 [snd_timer]
[ 13.438213] [<fa215000>] ? alsa_timer_init+0x0/0x129 [snd_timer]
[ 13.438216] [<c1001143>] do_one_initcall+0x51/0x13f
[ 13.438220] [<c105c0db>] sys_init_module+0xac/0x1e0
[ 13.438223] [<c129c820>] syscall_call+0x7/0xb
....
[ 56.108746] Call Trace:
[ 56.108754] [<c1024f88>] __might_sleep+0xef/0xf7
[ 56.108758] [<c129b6a3>] mutex_lock+0x1f/0x39
[ 56.108762] [<c10ca984>] do_lookup+0x87/0x139
[ 56.108765] [<c10cb02f>] link_path_walk+0x22b/0x520
[ 56.108768] [<c10cb435>] path_walk+0x3f/0x89
[ 56.108771] [<c10cb608>] vfs_path_lookup+0x53/0x99
[ 56.108775] [<c11e6a9b>] dev_mkdir.clone.0+0x23/0x8d
[ 56.108778] [<c10ca6ef>] ? mntput+0x18/0x1a
[ 56.108780] [<c10ca7d3>] ? path_put+0x1a/0x1d
[ 56.108783] [<c10cb63f>] ? vfs_path_lookup+0x8a/0x99
[ 56.108786] [<c129ee99>] ? add_preempt_count+0x8/0x75
[ 56.108789] [<c11e6bbc>] devtmpfs_create_node+0xb7/0x1f3
[ 56.108792] [<c10ffc78>] ? sysfs_find_dirent+0x1b/0x2c
[ 56.108795] [<c10fff50>] ? __sysfs_add_one+0x2a/0x78
[ 56.108797] [<c1100313>] ? sysfs_addrm_finish+0x1e/0x93
[ 56.108800] [<c11004d0>] ? sysfs_add_one+0x18/0xe1
[ 56.108803] [<c1100886>] ? sysfs_do_create_link+0xbc/0x109
[ 56.108805] [<c11008f3>] ? sysfs_create_link+0xf/0x14
[ 56.108809] [<c11e1e69>] device_add+0x141/0x44d
[ 56.108813] [<c100303a>] ? do_spurious_interrupt_bug+0xa/0x2a
[ 56.108816] [<c11e218c>] device_register+0x17/0x1a
[ 56.108827] [<f818d4e9>] drm_sysfs_device_add+0x71/0x94 [drm]
[ 56.108837] [<f818b6eb>] drm_get_minor+0x1a5/0x216 [drm]
[ 56.108846] [<f818ba1b>] drm_get_dev+0x2bf/0x3bc [drm]
[ 56.108850] [<c11721b8>] ? kobject_get+0x12/0x17
[ 56.108858] [<f81874ea>] drm_init+0x81/0xba [drm]
[ 56.108875] [<f81b9000>] ? radeon_init+0x0/0xae [radeon]
[ 56.108891] [<f81b90ac>] radeon_init+0xac/0xae [radeon]
[ 56.108893] [<c1001143>] do_one_initcall+0x51/0x13f
[ 56.108898] [<c105c0db>] sys_init_module+0xac/0x1e0
[ 56.108900] [<c129c820>] syscall_call+0x7/0xb


I guess it can be related to this commit.

Config attached.


On Sat, Dec 12, 2009 at 12:24 AM, Greg Kroah-Hartman <gregkh@suse.de> wrote:
> From: Kay Sievers <kay.sievers@vrfy.org>
>
> Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
> ---
>  drivers/base/devtmpfs.c |   26 ++++++++++++++++----------
>  1 files changed, 16 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
> index 48526b9..1cf498f 100644
> --- a/drivers/base/devtmpfs.c
> +++ b/drivers/base/devtmpfs.c
> @@ -32,6 +32,8 @@ static int dev_mount = 1;
>  static int dev_mount;
>  #endif
>
> +static rwlock_t dirlock;
> +
>  static int __init mount_param(char *str)
>  {
>        dev_mount = simple_strtoul(str, NULL, 0);
> @@ -86,16 +88,12 @@ static int dev_mkdir(const char *name, mode_t mode)
>
>  static int create_path(const char *nodepath)
>  {
> -       char *path;
>        struct nameidata nd;
>        int err = 0;
>
> -       path = kstrdup(nodepath, GFP_KERNEL);
> -       if (!path)
> -               return -ENOMEM;
> -
> +       read_lock(&dirlock);
>        err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
> -                             path, LOOKUP_PARENT, &nd);
> +                             nodepath, LOOKUP_PARENT, &nd);
>        if (err == 0) {
>                struct dentry *dentry;
>
> @@ -107,14 +105,17 @@ static int create_path(const char *nodepath)
>                        dput(dentry);
>                }
>                mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
> -
>                path_put(&nd.path);
>        } else if (err == -ENOENT) {
> +               char *path;
>                char *s;
>
>                /* parent directories do not exist, create them */
> +               path = kstrdup(nodepath, GFP_KERNEL);
> +               if (!path)
> +                       return -ENOMEM;
>                s = path;
> -               while (1) {
> +               for (;;) {
>                        s = strchr(s, '/');
>                        if (!s)
>                                break;
> @@ -125,9 +126,10 @@ static int create_path(const char *nodepath)
>                        s[0] = '/';
>                        s++;
>                }
> +               kfree(path);
>        }
> +       read_unlock(&dirlock);
>
> -       kfree(path);
>        return err;
>  }
>
> @@ -234,7 +236,8 @@ static int delete_path(const char *nodepath)
>        if (!path)
>                return -ENOMEM;
>
> -       while (1) {
> +       write_lock(&dirlock);
> +       for (;;) {
>                char *base;
>
>                base = strrchr(path, '/');
> @@ -245,6 +248,7 @@ static int delete_path(const char *nodepath)
>                if (err)
>                        break;
>        }
> +       write_unlock(&dirlock);
>
>        kfree(path);
>        return err;
> @@ -360,6 +364,8 @@ int __init devtmpfs_init(void)
>        int err;
>        struct vfsmount *mnt;
>
> +       rwlock_init(&dirlock);
> +
>        err = register_filesystem(&dev_fs_type);
>        if (err) {
>                printk(KERN_ERR "devtmpfs: unable to register devtmpfs "
> --
> 1.6.5.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>
[unhandled content-type:application/octet-stream]
\
 
 \ /
  Last update: 2009-12-21 14:41    [W:0.160 / U:0.320 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site