public inbox for linux-nfs@vger.kernel.org
 help / color / mirror / Atom feed
* allocation under spinlock
@ 2010-02-24 21:23 J. Bruce Fields
  2010-02-25  2:31 ` Trond Myklebust
  0 siblings, 1 reply; 3+ messages in thread
From: J. Bruce Fields @ 2010-02-24 21:23 UTC (permalink / raw)
  To: Trond Myklebust; +Cc: linux-nfs

nfs_dns_ent_init() is trying to kstrndup() something, but it's called under a
spinlock.

Could refernce count that string instead, but other code I believe actually
just does something like:

	new->hostname = key->hostname;
	key->hostname = NULL;

--b.

BUG: sleeping function called from invalid context at mm/slab.c:3034
in_atomic(): 1, irqs_disabled(): 0, pid: 3300, name: nfs_cache_geten
2 locks held by nfs_cache_geten/3300:
 #0:  (&sb->s_type->i_mutex_key#4){+.+.+.}, at: [<c1795506>] cache_write+0x46/0x100
 #1:  (&cd->hash_lock){+++++.}, at: [<c17964a5>] sunrpc_cache_update+0x25/0x170
Pid: 3300, comm: nfs_cache_geten Not tainted 2.6.33-rc8-13669-g724e6d3 #156
Call Trace:
 [<c17db62e>] ? printk+0x1d/0x1f
 [<c1022c70>] __might_sleep+0x100/0x130
 [<c10bf849>] __kmalloc_track_caller+0x189/0x230
 [<c10be6d4>] ? kfree+0xd4/0x180
 [<c11f2796>] ? nfs_dns_ent_init+0x26/0x70
 [<c10a7f04>] kstrndup+0x34/0x60
 [<c11f2796>] nfs_dns_ent_init+0x26/0x70
 [<c17965b8>] sunrpc_cache_update+0x138/0x170
 [<c11f2a03>] ? nfs_dns_lookup+0x53/0x70
 [<c11f2bb4>] nfs_dns_parse+0x194/0x1e0
 [<c1058e90>] ? add_lock_to_list+0x40/0xc0
 [<c105bd7a>] ? __lock_acquire+0x109a/0x1890
 [<c1095375>] ? add_to_page_cache_locked+0x65/0x140
 [<c105c7f9>] ? lock_release_non_nested+0x59/0x2f0
 [<c1059dc2>] ? mark_held_locks+0x62/0x90
 [<c10ab662>] ? might_fault+0x62/0xb0
 [<c10ab662>] ? might_fault+0x62/0xb0
 [<c10ab6a8>] ? might_fault+0xa8/0xb0
 [<c10ab662>] ? might_fault+0x62/0xb0
 [<c17946ba>] cache_do_downcall+0x3a/0x50
 [<c1795560>] cache_write+0xa0/0x100
 [<c10c2fb2>] ? rw_verify_area+0x62/0xd0
 [<c17955e7>] cache_write_pipefs+0x27/0x30
 [<c10c3842>] vfs_write+0xa2/0x170
 [<c104e94b>] ? up_read+0x1b/0x30
 [<c17955c0>] ? cache_write_pipefs+0x0/0x30
 [<c17e1400>] ? do_page_fault+0x160/0x3f0
 [<c10c39d2>] sys_write+0x42/0x70
 [<c17df155>] syscall_call+0x7/0xb


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: allocation under spinlock
  2010-02-24 21:23 allocation under spinlock J. Bruce Fields
@ 2010-02-25  2:31 ` Trond Myklebust
       [not found]   ` <1267065109.19857.10.camel-UuHi6rWCfGWzdaK+V31Xzzg6DN0g1aqAy1WmG7uI1WA@public.gmane.org>
  0 siblings, 1 reply; 3+ messages in thread
From: Trond Myklebust @ 2010-02-25  2:31 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: linux-nfs

On Wed, 2010-02-24 at 16:23 -0500, J. Bruce Fields wrote: 
> nfs_dns_ent_init() is trying to kstrndup() something, but it's called under a
> spinlock.
> 
> Could refernce count that string instead, but other code I believe actually
> just does something like:
> 
> 	new->hostname = key->hostname;
> 	key->hostname = NULL;
> 
> --b.
> 
> BUG: sleeping function called from invalid context at mm/slab.c:3034
> in_atomic(): 1, irqs_disabled(): 0, pid: 3300, name: nfs_cache_geten
> 2 locks held by nfs_cache_geten/3300:
>  #0:  (&sb->s_type->i_mutex_key#4){+.+.+.}, at: [<c1795506>] cache_write+0x46/0x100
>  #1:  (&cd->hash_lock){+++++.}, at: [<c17964a5>] sunrpc_cache_update+0x25/0x170
> Pid: 3300, comm: nfs_cache_geten Not tainted 2.6.33-rc8-13669-g724e6d3 #156

Does the following fix it for you?

Cheers
  Trond
---------------------------------------------------------------------------- 
NFS: Fix an allocation-under-spinlock bug

From: Trond Myklebust <Trond.Myklebust@netapp.com>

sunrpc_cache_update() will always call detail->update() from inside the
detail->hash_lock, so it cannot allocate memory.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: stable@kernel.org
---

 fs/nfs/dns_resolve.c |   18 +++++++++++++++---
 1 files changed, 15 insertions(+), 3 deletions(-)


diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c
index 95e1ca7..3f0cd4d 100644
--- a/fs/nfs/dns_resolve.c
+++ b/fs/nfs/dns_resolve.c
@@ -36,6 +36,19 @@ struct nfs_dns_ent {
 };
 

+static void nfs_dns_ent_update(struct cache_head *cnew,
+		struct cache_head *ckey)
+{
+	struct nfs_dns_ent *new;
+	struct nfs_dns_ent *key;
+
+	new = container_of(cnew, struct nfs_dns_ent, h);
+	key = container_of(ckey, struct nfs_dns_ent, h);
+
+	memcpy(&new->addr, &key->addr, key->addrlen);
+	new->addrlen = key->addrlen;
+}
+
 static void nfs_dns_ent_init(struct cache_head *cnew,
 		struct cache_head *ckey)
 {
@@ -49,8 +62,7 @@ static void nfs_dns_ent_init(struct cache_head *cnew,
 	new->hostname = kstrndup(key->hostname, key->namelen, GFP_KERNEL);
 	if (new->hostname) {
 		new->namelen = key->namelen;
-		memcpy(&new->addr, &key->addr, key->addrlen);
-		new->addrlen = key->addrlen;
+		nfs_dns_ent_update(cnew, ckey);
 	} else {
 		new->namelen = 0;
 		new->addrlen = 0;
@@ -234,7 +246,7 @@ static struct cache_detail nfs_dns_resolve = {
 	.cache_show = nfs_dns_show,
 	.match = nfs_dns_match,
 	.init = nfs_dns_ent_init,
-	.update = nfs_dns_ent_init,
+	.update = nfs_dns_ent_update,
 	.alloc = nfs_dns_ent_alloc,
 };
 


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: allocation under spinlock
       [not found]   ` <1267065109.19857.10.camel-UuHi6rWCfGWzdaK+V31Xzzg6DN0g1aqAy1WmG7uI1WA@public.gmane.org>
@ 2010-02-25  2:49     ` J. Bruce Fields
  0 siblings, 0 replies; 3+ messages in thread
From: J. Bruce Fields @ 2010-02-25  2:49 UTC (permalink / raw)
  To: Trond Myklebust; +Cc: linux-nfs

On Wed, Feb 24, 2010 at 06:31:49PM -0800, Trond Myklebust wrote:
> On Wed, 2010-02-24 at 16:23 -0500, J. Bruce Fields wrote: 
> > nfs_dns_ent_init() is trying to kstrndup() something, but it's called under a
> > spinlock.
> > 
> > Could refernce count that string instead, but other code I believe actually
> > just does something like:
> > 
> > 	new->hostname = key->hostname;
> > 	key->hostname = NULL;
> > 
> > --b.
> > 
> > BUG: sleeping function called from invalid context at mm/slab.c:3034
> > in_atomic(): 1, irqs_disabled(): 0, pid: 3300, name: nfs_cache_geten
> > 2 locks held by nfs_cache_geten/3300:
> >  #0:  (&sb->s_type->i_mutex_key#4){+.+.+.}, at: [<c1795506>] cache_write+0x46/0x100
> >  #1:  (&cd->hash_lock){+++++.}, at: [<c17964a5>] sunrpc_cache_update+0x25/0x170
> > Pid: 3300, comm: nfs_cache_geten Not tainted 2.6.33-rc8-13669-g724e6d3 #156
> 
> Does the following fix it for you?

No more warning; thanks!

--b.

> 
> Cheers
>   Trond
> ---------------------------------------------------------------------------- 
> NFS: Fix an allocation-under-spinlock bug
> 
> From: Trond Myklebust <Trond.Myklebust@netapp.com>
> 
> sunrpc_cache_update() will always call detail->update() from inside the
> detail->hash_lock, so it cannot allocate memory.
> 
> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
> Cc: stable@kernel.org
> ---
> 
>  fs/nfs/dns_resolve.c |   18 +++++++++++++++---
>  1 files changed, 15 insertions(+), 3 deletions(-)
> 
> 
> diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c
> index 95e1ca7..3f0cd4d 100644
> --- a/fs/nfs/dns_resolve.c
> +++ b/fs/nfs/dns_resolve.c
> @@ -36,6 +36,19 @@ struct nfs_dns_ent {
>  };
>  
> 
> +static void nfs_dns_ent_update(struct cache_head *cnew,
> +		struct cache_head *ckey)
> +{
> +	struct nfs_dns_ent *new;
> +	struct nfs_dns_ent *key;
> +
> +	new = container_of(cnew, struct nfs_dns_ent, h);
> +	key = container_of(ckey, struct nfs_dns_ent, h);
> +
> +	memcpy(&new->addr, &key->addr, key->addrlen);
> +	new->addrlen = key->addrlen;
> +}
> +
>  static void nfs_dns_ent_init(struct cache_head *cnew,
>  		struct cache_head *ckey)
>  {
> @@ -49,8 +62,7 @@ static void nfs_dns_ent_init(struct cache_head *cnew,
>  	new->hostname = kstrndup(key->hostname, key->namelen, GFP_KERNEL);
>  	if (new->hostname) {
>  		new->namelen = key->namelen;
> -		memcpy(&new->addr, &key->addr, key->addrlen);
> -		new->addrlen = key->addrlen;
> +		nfs_dns_ent_update(cnew, ckey);
>  	} else {
>  		new->namelen = 0;
>  		new->addrlen = 0;
> @@ -234,7 +246,7 @@ static struct cache_detail nfs_dns_resolve = {
>  	.cache_show = nfs_dns_show,
>  	.match = nfs_dns_match,
>  	.init = nfs_dns_ent_init,
> -	.update = nfs_dns_ent_init,
> +	.update = nfs_dns_ent_update,
>  	.alloc = nfs_dns_ent_alloc,
>  };
>  
> 

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2010-02-25  2:48 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-24 21:23 allocation under spinlock J. Bruce Fields
2010-02-25  2:31 ` Trond Myklebust
     [not found]   ` <1267065109.19857.10.camel-UuHi6rWCfGWzdaK+V31Xzzg6DN0g1aqAy1WmG7uI1WA@public.gmane.org>
2010-02-25  2:49     ` J. Bruce Fields

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox