* Subject: [PATCH] net/ipv6: Use GFP_ATOMIC when a lock is held
@ 2010-05-30 19:48 Julia Lawall
2010-05-30 20:11 ` Eric Dumazet
0 siblings, 1 reply; 8+ messages in thread
From: Julia Lawall @ 2010-05-30 19:48 UTC (permalink / raw)
To: David S. Miller, Alexey Kuznetsov, Pekka Savola (ipv6),
James Morris, Hideaki YOSHIFUJI <yosh
From: Julia Lawall <julia@diku.dk>
A spin lock is taken near the beginning of the enclosing function.
The semantic patch that makes this change is as follows:
(http://coccinelle.lip6.fr/)
// <smpl>
@@
@@
spin_lock(...)
... when != spin_unlock(...)
-GFP_KERNEL
+GFP_ATOMIC
// </smpl>
Signed-off-by: Julia Lawall <julia@diku.dk>
---
net/ipv6/sit.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff -u -p a/net/ipv6/sit.c b/net/ipv6/sit.c
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -358,7 +358,7 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t
goto out;
}
- p = kzalloc(sizeof(struct ip_tunnel_prl_entry), GFP_KERNEL);
+ p = kzalloc(sizeof(struct ip_tunnel_prl_entry), GFP_ATOMIC);
if (!p) {
err = -ENOBUFS;
goto out;
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: Subject: [PATCH] net/ipv6: Use GFP_ATOMIC when a lock is held 2010-05-30 19:48 Subject: [PATCH] net/ipv6: Use GFP_ATOMIC when a lock is held Julia Lawall @ 2010-05-30 20:11 ` Eric Dumazet 2010-05-30 20:50 ` Julia Lawall 0 siblings, 1 reply; 8+ messages in thread From: Eric Dumazet @ 2010-05-30 20:11 UTC (permalink / raw) To: Julia Lawall Cc: David S. Miller, Alexey Kuznetsov, Pekka Savola (ipv6), James Morris, Hideaki YOSHIFUJI, Patrick McHardy, netdev, linux-kernel, kernel-janitors Le dimanche 30 mai 2010 à 21:48 +0200, Julia Lawall a écrit : > From: Julia Lawall <julia@diku.dk> > > A spin lock is taken near the beginning of the enclosing function. > > The semantic patch that makes this change is as follows: > (http://coccinelle.lip6.fr/) > > // <smpl> > @@ > @@ > > spin_lock(...) > ... when != spin_unlock(...) > -GFP_KERNEL > +GFP_ATOMIC > // </smpl> > > Signed-off-by: Julia Lawall <julia@diku.dk> > > --- > net/ipv6/sit.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff -u -p a/net/ipv6/sit.c b/net/ipv6/sit.c > --- a/net/ipv6/sit.c > +++ b/net/ipv6/sit.c > @@ -358,7 +358,7 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t > goto out; > } > > - p = kzalloc(sizeof(struct ip_tunnel_prl_entry), GFP_KERNEL); > + p = kzalloc(sizeof(struct ip_tunnel_prl_entry), GFP_ATOMIC); > if (!p) { > err = -ENOBUFS; > goto out; Nice catch, but what about allocating this outside of the locked section ? diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index e51e650..ff3dd84 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -340,6 +340,10 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg) if (a->addr == htonl(INADDR_ANY)) return -EINVAL; + p = kzalloc(sizeof(struct ip_tunnel_prl_entry), GFP_KERNEL); + if (!p) + return -ENOBUFS; + spin_lock(&ipip6_prl_lock); for (p = t->prl; p; p = p->next) { @@ -358,19 +362,16 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg) goto out; } - p = kzalloc(sizeof(struct ip_tunnel_prl_entry), GFP_KERNEL); - if (!p) { - err = -ENOBUFS; - goto out; - } p->next = t->prl; p->addr = a->addr; p->flags = a->flags; t->prl_count++; rcu_assign_pointer(t->prl, p); + p = NULL; out: spin_unlock(&ipip6_prl_lock); + kfree(p); return err; } ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: Subject: [PATCH] net/ipv6: Use GFP_ATOMIC when a lock is held 2010-05-30 20:11 ` Eric Dumazet @ 2010-05-30 20:50 ` Julia Lawall 2010-05-30 20:55 ` Eric Dumazet 0 siblings, 1 reply; 8+ messages in thread From: Julia Lawall @ 2010-05-30 20:50 UTC (permalink / raw) To: Eric Dumazet Cc: David S. Miller, Alexey Kuznetsov, Pekka Savola (ipv6), James Morris, Hideaki YOSHIFUJI, Patrick McHardy, netdev, linux-kernel, kernel-janitors [-- Attachment #1: Type: TEXT/PLAIN, Size: 2442 bytes --] On Sun, 30 May 2010, Eric Dumazet wrote: > Le dimanche 30 mai 2010 à 21:48 +0200, Julia Lawall a écrit : > > From: Julia Lawall <julia@diku.dk> > > > > A spin lock is taken near the beginning of the enclosing function. > > > > The semantic patch that makes this change is as follows: > > (http://coccinelle.lip6.fr/) > > > > // <smpl> > > @@ > > @@ > > > > spin_lock(...) > > ... when != spin_unlock(...) > > -GFP_KERNEL > > +GFP_ATOMIC > > // </smpl> > > > > Signed-off-by: Julia Lawall <julia@diku.dk> > > > > --- > > net/ipv6/sit.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff -u -p a/net/ipv6/sit.c b/net/ipv6/sit.c > > --- a/net/ipv6/sit.c > > +++ b/net/ipv6/sit.c > > @@ -358,7 +358,7 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t > > goto out; > > } > > > > - p = kzalloc(sizeof(struct ip_tunnel_prl_entry), GFP_KERNEL); > > + p = kzalloc(sizeof(struct ip_tunnel_prl_entry), GFP_ATOMIC); > > if (!p) { > > err = -ENOBUFS; > > goto out; > > Nice catch, but what about allocating this outside of the locked > section ? I think the proposed patch does not work, because the for loop overwrites p. That use of p looks like it is completely local to the for loop, so perhaps a new variable p1 could be added to be used there? julia > diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c > index e51e650..ff3dd84 100644 > --- a/net/ipv6/sit.c > +++ b/net/ipv6/sit.c > @@ -340,6 +340,10 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg) > if (a->addr == htonl(INADDR_ANY)) > return -EINVAL; > > + p = kzalloc(sizeof(struct ip_tunnel_prl_entry), GFP_KERNEL); > + if (!p) > + return -ENOBUFS; > + > spin_lock(&ipip6_prl_lock); > > for (p = t->prl; p; p = p->next) { > @@ -358,19 +362,16 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg) > goto out; > } > > - p = kzalloc(sizeof(struct ip_tunnel_prl_entry), GFP_KERNEL); > - if (!p) { > - err = -ENOBUFS; > - goto out; > - } > > p->next = t->prl; > p->addr = a->addr; > p->flags = a->flags; > t->prl_count++; > rcu_assign_pointer(t->prl, p); > + p = NULL; > out: > spin_unlock(&ipip6_prl_lock); > + kfree(p); > return err; > } > > > > -- > To unsubscribe from this list: send the line "unsubscribe kernel-janitors" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Subject: [PATCH] net/ipv6: Use GFP_ATOMIC when a lock is held 2010-05-30 20:50 ` Julia Lawall @ 2010-05-30 20:55 ` Eric Dumazet 2010-05-30 21:09 ` Julia Lawall 0 siblings, 1 reply; 8+ messages in thread From: Eric Dumazet @ 2010-05-30 20:55 UTC (permalink / raw) To: Julia Lawall Cc: David S. Miller, Alexey Kuznetsov, Pekka Savola (ipv6), James Morris, Hideaki YOSHIFUJI, Patrick McHardy, netdev, linux-kernel, kernel-janitors Le dimanche 30 mai 2010 à 22:50 +0200, Julia Lawall a écrit : > I think the proposed patch does not work, because the for loop overwrites > p. That use of p looks like it is completely local to the for loop, so > perhaps a new variable p1 could be added to be used there? Please do so. I just wanted to tell you changing GFP_KERNEL to GFP_ATOMIC is not an appropriate way to solve this kind of problems. My patch was to get an idea, not a full and tested patch :) ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Subject: [PATCH] net/ipv6: Use GFP_ATOMIC when a lock is held 2010-05-30 20:55 ` Eric Dumazet @ 2010-05-30 21:09 ` Julia Lawall 2010-05-30 21:18 ` Eric Dumazet 2010-05-31 5:04 ` [PATCH] ipv6: get rid of ipip6_prl_lock Eric Dumazet 0 siblings, 2 replies; 8+ messages in thread From: Julia Lawall @ 2010-05-30 21:09 UTC (permalink / raw) To: Eric Dumazet Cc: David S. Miller, Alexey Kuznetsov, Pekka Savola (ipv6), James Morris, Hideaki YOSHIFUJI, Patrick McHardy, netdev, linux-kernel, kernel-janitors [-- Attachment #1: Type: TEXT/PLAIN, Size: 1286 bytes --] On Sun, 30 May 2010, Eric Dumazet wrote: > Le dimanche 30 mai 2010 à 22:50 +0200, Julia Lawall a écrit : > > > I think the proposed patch does not work, because the for loop overwrites > > p. That use of p looks like it is completely local to the for loop, so > > perhaps a new variable p1 could be added to be used there? > > Please do so. > > I just wanted to tell you changing GFP_KERNEL to GFP_ATOMIC is not an > appropriate way to solve this kind of problems. My patch was to get an > idea, not a full and tested patch :) Looking at it again, there is still a problem, because in the original code, the loop: for (p = t->prl; p; p = p->next) { if (p->addr == a->addr) { if (chg) { p->flags = a->flags; goto out; } err = -EEXIST; goto out; } } could exit with success without the kzalloc ever being called. If the kzalloc is moved up, it could fail and then it returns immediately without executing the loop. A solution could be to leave the NULL test on p where it is, and only move up the kzalloc. Or perhaps the change in behavior doesn't matter? julia ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Subject: [PATCH] net/ipv6: Use GFP_ATOMIC when a lock is held 2010-05-30 21:09 ` Julia Lawall @ 2010-05-30 21:18 ` Eric Dumazet 2010-05-31 5:04 ` [PATCH] ipv6: get rid of ipip6_prl_lock Eric Dumazet 1 sibling, 0 replies; 8+ messages in thread From: Eric Dumazet @ 2010-05-30 21:18 UTC (permalink / raw) To: Julia Lawall Cc: David S. Miller, Alexey Kuznetsov, Pekka Savola (ipv6), James Morris, Hideaki YOSHIFUJI, Patrick McHardy, netdev, linux-kernel, kernel-janitors Le dimanche 30 mai 2010 à 23:09 +0200, Julia Lawall a écrit : > could exit with success without the kzalloc ever being called. If the > kzalloc is moved up, it could fail and then it returns immediately without > executing the loop. A solution could be to leave the NULL test on p where > it is, and only move up the kzalloc. Or perhaps the change in behavior > doesn't matter? If a GFP_KERNEL allocation fails, we are in a big trouble anyway :) GFP_ATOMIC are more problematic in this area :) ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] ipv6: get rid of ipip6_prl_lock 2010-05-30 21:09 ` Julia Lawall 2010-05-30 21:18 ` Eric Dumazet @ 2010-05-31 5:04 ` Eric Dumazet 2010-06-01 7:27 ` David Miller 1 sibling, 1 reply; 8+ messages in thread From: Eric Dumazet @ 2010-05-31 5:04 UTC (permalink / raw) To: Julia Lawall Cc: David S. Miller, Alexey Kuznetsov, Pekka Savola (ipv6), James Morris, Hideaki YOSHIFUJI, Patrick McHardy, netdev, linux-kernel, kernel-janitors Le dimanche 30 mai 2010 à 23:09 +0200, Julia Lawall a écrit : > On Sun, 30 May 2010, Eric Dumazet wrote: > > > Le dimanche 30 mai 2010 à 22:50 +0200, Julia Lawall a écrit : > > > > > I think the proposed patch does not work, because the for loop overwrites > > > p. That use of p looks like it is completely local to the for loop, so > > > perhaps a new variable p1 could be added to be used there? > > > > Please do so. > > > > I just wanted to tell you changing GFP_KERNEL to GFP_ATOMIC is not an > > appropriate way to solve this kind of problems. My patch was to get an > > idea, not a full and tested patch :) > > Looking at it again, there is still a problem, because in the original > code, the loop: > ... > > could exit with success without the kzalloc ever being called. If the > kzalloc is moved up, it could fail and then it returns immediately without > executing the loop. A solution could be to leave the NULL test on p where > it is, and only move up the kzalloc. Or perhaps the change in behavior > doesn't matter? > [PATCH] ipv6: get rid of ipip6_prl_lock As noticed by Julia Lawall, ipip6_tunnel_add_prl() incorrectly calls kzallloc(..., GFP_KERNEL) while a spinlock is held. He provided a patch to use GFP_ATOMIC instead. One possibility would be to convert this spinlock to a mutex, or preallocate the thing before taking the lock. After RCU conversion, it appears we dont need this lock, since caller already holds RTNL Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> --- net/ipv6/sit.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index e51e650..702c532 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -249,8 +249,6 @@ failed: return NULL; } -static DEFINE_SPINLOCK(ipip6_prl_lock); - #define for_each_prl_rcu(start) \ for (prl = rcu_dereference(start); \ prl; \ @@ -340,7 +338,7 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg) if (a->addr == htonl(INADDR_ANY)) return -EINVAL; - spin_lock(&ipip6_prl_lock); + ASSERT_RTNL(); for (p = t->prl; p; p = p->next) { if (p->addr == a->addr) { @@ -370,7 +368,6 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg) t->prl_count++; rcu_assign_pointer(t->prl, p); out: - spin_unlock(&ipip6_prl_lock); return err; } @@ -397,7 +394,7 @@ ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a) struct ip_tunnel_prl_entry *x, **p; int err = 0; - spin_lock(&ipip6_prl_lock); + ASSERT_RTNL(); if (a && a->addr != htonl(INADDR_ANY)) { for (p = &t->prl; *p; p = &(*p)->next) { @@ -419,7 +416,6 @@ ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a) } } out: - spin_unlock(&ipip6_prl_lock); return err; } ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] ipv6: get rid of ipip6_prl_lock 2010-05-31 5:04 ` [PATCH] ipv6: get rid of ipip6_prl_lock Eric Dumazet @ 2010-06-01 7:27 ` David Miller 0 siblings, 0 replies; 8+ messages in thread From: David Miller @ 2010-06-01 7:27 UTC (permalink / raw) To: eric.dumazet Cc: julia, kuznet, pekkas, jmorris, yoshfuji, kaber, netdev, linux-kernel, kernel-janitors From: Eric Dumazet <eric.dumazet@gmail.com> Date: Mon, 31 May 2010 07:04:55 +0200 > [PATCH] ipv6: get rid of ipip6_prl_lock > > As noticed by Julia Lawall, ipip6_tunnel_add_prl() incorrectly calls > kzallloc(..., GFP_KERNEL) while a spinlock is held. She provided > a patch to use GFP_ATOMIC instead. > > One possibility would be to convert this spinlock to a mutex, or > preallocate the thing before taking the lock. > > After RCU conversion, it appears we dont need this lock, since > caller already holds RTNL > > Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Applied, thanks everyone. ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-06-01 7:27 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-05-30 19:48 Subject: [PATCH] net/ipv6: Use GFP_ATOMIC when a lock is held Julia Lawall 2010-05-30 20:11 ` Eric Dumazet 2010-05-30 20:50 ` Julia Lawall 2010-05-30 20:55 ` Eric Dumazet 2010-05-30 21:09 ` Julia Lawall 2010-05-30 21:18 ` Eric Dumazet 2010-05-31 5:04 ` [PATCH] ipv6: get rid of ipip6_prl_lock Eric Dumazet 2010-06-01 7:27 ` David Miller
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox