netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] rtnl_unlock/lock in sch_api.c
@ 2005-03-28 14:25 Catalin(ux aka Dino) BOIE
  2005-03-28 14:47 ` Thomas Graf
  2005-03-28 14:50 ` Patrick McHardy
  0 siblings, 2 replies; 7+ messages in thread
From: Catalin(ux aka Dino) BOIE @ 2005-03-28 14:25 UTC (permalink / raw)
  To: netdev; +Cc: davem

[-- Attachment #1: Type: TEXT/PLAIN, Size: 499 bytes --]

Hello!

Trying to load a custom module (same for teql but I didn't tried it)
whan the qdisc module is not loaded, makes tc hang.
This is because qdisc_create aquires rtnl_sem and then tries to load a 
module that tries to register_netdev (that tries to aquire the same 
rtnl_sem).
Applying this patch makes the problem go away.

Signed-off-by: Catalin(ux aka Dino) BOIE <catab at umbrella.ro>

Please apply.

Thanks!

---
Catalin(ux aka Dino) BOIE
catab at deuroconsult.ro
http://kernel.umbrella.ro/

[-- Attachment #2: Type: TEXT/PLAIN, Size: 885 bytes --]

--- linux/net/sched/sch_api.c.orig	2005-03-28 16:32:57.000000000 +0300
+++ linux/net/sched/sch_api.c	2005-03-28 16:38:17.000000000 +0300
@@ -404,18 +404,28 @@ qdisc_create(struct net_device *dev, u32
 	struct Qdisc_ops *ops;
 	int size;
 
+	err = -EINVAL;
 	ops = qdisc_lookup_ops(kind);
 #ifdef CONFIG_KMOD
-	if (ops==NULL && tca[TCA_KIND-1] != NULL) {
+	if (ops == NULL && kind != NULL) {
 		char name[IFNAMSIZ];
 		if (rtattr_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) {
+			/* Must drop rtnl sem because request_module
+			 * can try to aquire rtnl sem (see teql for
+			 * example)
+			 */
+			rtnl_unlock();
 			request_module("sch_%s", name);
+			rtnl_lock();
 			ops = qdisc_lookup_ops(kind);
+			if (ops != NULL) {
+				module_put(ops->owner);
+				err = -EAGAIN;
+			}
 		}
 	}
 #endif
 
-	err = -EINVAL;
 	if (ops == NULL)
 		goto err_out;
 

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

* Re: [PATCH] rtnl_unlock/lock in sch_api.c
  2005-03-28 14:25 [PATCH] rtnl_unlock/lock in sch_api.c Catalin(ux aka Dino) BOIE
@ 2005-03-28 14:47 ` Thomas Graf
  2005-03-28 22:27   ` Catalin(ux aka Dino) BOIE
  2005-03-28 14:50 ` Patrick McHardy
  1 sibling, 1 reply; 7+ messages in thread
From: Thomas Graf @ 2005-03-28 14:47 UTC (permalink / raw)
  To: Catalin(ux aka Dino) BOIE; +Cc: netdev, davem

Looks good, except...

> --- linux/net/sched/sch_api.c.orig	2005-03-28 16:32:57.000000000 +0300
> +++ linux/net/sched/sch_api.c	2005-03-28 16:38:17.000000000 +0300
> @@ -404,18 +404,28 @@ qdisc_create(struct net_device *dev, u32
>  	struct Qdisc_ops *ops;
>  	int size;
>  
> +	err = -EINVAL;
>  	ops = qdisc_lookup_ops(kind);
>  #ifdef CONFIG_KMOD
> -	if (ops==NULL && tca[TCA_KIND-1] != NULL) {
> +	if (ops == NULL && kind != NULL) {
>  		char name[IFNAMSIZ];
>  		if (rtattr_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) {
> +			/* Must drop rtnl sem because request_module
> +			 * can try to aquire rtnl sem (see teql for
> +			 * example)
> +			 */
> +			rtnl_unlock();
>  			request_module("sch_%s", name);
> +			rtnl_lock();
>  			ops = qdisc_lookup_ops(kind);
> +			if (ops != NULL) {
> +				module_put(ops->owner);
> +				err = -EAGAIN;

You're missing a goto err_out here, the ops == NULL won't catch it.

> +			}
>  		}
>  	}
>  #endif
>  
> -	err = -EINVAL;
>  	if (ops == NULL)
>  		goto err_out;

With the above goto inserted there is no need to move the err = -EINVAL.

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

* Re: [PATCH] rtnl_unlock/lock in sch_api.c
  2005-03-28 14:25 [PATCH] rtnl_unlock/lock in sch_api.c Catalin(ux aka Dino) BOIE
  2005-03-28 14:47 ` Thomas Graf
@ 2005-03-28 14:50 ` Patrick McHardy
  2005-03-28 22:16   ` Catalin(ux aka Dino) BOIE
  1 sibling, 1 reply; 7+ messages in thread
From: Patrick McHardy @ 2005-03-28 14:50 UTC (permalink / raw)
  To: Catalin(ux aka Dino) BOIE; +Cc: netdev, davem

[-- Attachment #1: Type: text/plain, Size: 570 bytes --]

Catalin(ux aka Dino) BOIE wrote:
> Hello!
> 
> Trying to load a custom module (same for teql but I didn't tried it)
> whan the qdisc module is not loaded, makes tc hang.
> This is because qdisc_create aquires rtnl_sem and then tries to load a 
> module that tries to register_netdev (that tries to aquire the same 
> rtnl_sem).
> Applying this patch makes the problem go away.

You open a race by dropping the lock and not replaying the request
after acquiring it again. This is Dave's original patch, please
simply fix this one up so it applies again.

Regards
Patrick

[-- Attachment #2: x --]
[-- Type: text/plain, Size: 1750 bytes --]

===== net/sched/sch_api.c 1.41 vs edited =====
--- 1.41/net/sched/sch_api.c	2004-11-05 16:34:45 -08:00
+++ edited/net/sched/sch_api.c	2004-11-09 15:57:19 -08:00
@@ -396,17 +396,30 @@
 	struct Qdisc_ops *ops;
 	int size;
 
+	err = -EINVAL;
 	ops = qdisc_lookup_ops(kind);
 #ifdef CONFIG_KMOD
 	if (ops==NULL && tca[TCA_KIND-1] != NULL) {
 		if (RTA_PAYLOAD(kind) <= IFNAMSIZ) {
+			rtnl_unlock();
 			request_module("sch_%s", (char*)RTA_DATA(kind));
+			rtnl_lock();
+
 			ops = qdisc_lookup_ops(kind);
+
+			/* We dropped the RTNL semaphore in order to
+			 * perform the module load.  So, even if we
+			 * succeeded in loading the module we have to
+			 * tell the caller to replay the request.  We
+			 * indicate this using -EAGAIN.
+			 */
+			if (ops != NULL)
+				err = -EAGAIN;
+			goto err_out;
 		}
 	}
 #endif
 
-	err = -EINVAL;
 	if (ops == NULL)
 		goto err_out;
 	err = -EBUSY;
@@ -600,14 +613,19 @@
 
 static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
 {
-	struct tcmsg *tcm = NLMSG_DATA(n);
-	struct rtattr **tca = arg;
+	struct tcmsg *tcm;
+	struct rtattr **tca;
 	struct net_device *dev;
-	u32 clid = tcm->tcm_parent;
-	struct Qdisc *q = NULL;
-	struct Qdisc *p = NULL;
+	u32 clid;
+	struct Qdisc *q, *p;
 	int err;
 
+replay:
+	tcm = NLMSG_DATA(n);
+	tca = arg;
+	clid = tcm->tcm_parent;
+	q = p = NULL;
+
 	if ((dev = __dev_get_by_index(tcm->tcm_ifindex)) == NULL)
 		return -ENODEV;
 
@@ -701,8 +719,14 @@
 		q = qdisc_create(dev, tcm->tcm_parent, tca, &err);
         else
 		q = qdisc_create(dev, tcm->tcm_handle, tca, &err);
-	if (q == NULL)
+	if (q == NULL) {
+		if (err == -EAGAIN) {
+			/* Replay the request. */
+			dev_put(dev);
+			goto replay;
+		}
 		return err;
+	}
 
 graft:
 	if (1) {


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

* Re: [PATCH] rtnl_unlock/lock in sch_api.c
  2005-03-28 14:50 ` Patrick McHardy
@ 2005-03-28 22:16   ` Catalin(ux aka Dino) BOIE
  2005-03-28 22:20     ` Patrick McHardy
  0 siblings, 1 reply; 7+ messages in thread
From: Catalin(ux aka Dino) BOIE @ 2005-03-28 22:16 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netdev, davem

On Mon, 28 Mar 2005, Patrick McHardy wrote:

> Catalin(ux aka Dino) BOIE wrote:
>> Hello!
>> 
>> Trying to load a custom module (same for teql but I didn't tried it)
>> whan the qdisc module is not loaded, makes tc hang.
>> This is because qdisc_create aquires rtnl_sem and then tries to load a 
>> module that tries to register_netdev (that tries to aquire the same 
>> rtnl_sem).
>> Applying this patch makes the problem go away.
>
> You open a race by dropping the lock and not replaying the request
> after acquiring it again. This is Dave's original patch, please
> simply fix this one up so it applies again.
>
> Regards
> Patrick

Patrick,
What to fix in Dave's patch? Seems ok to me.

Thanks!

---
Catalin(ux aka Dino) BOIE
catab at deuroconsult.ro
http://kernel.umbrella.ro/

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

* Re: [PATCH] rtnl_unlock/lock in sch_api.c
  2005-03-28 22:16   ` Catalin(ux aka Dino) BOIE
@ 2005-03-28 22:20     ` Patrick McHardy
  2005-03-28 22:21       ` Catalin(ux aka Dino) BOIE
  0 siblings, 1 reply; 7+ messages in thread
From: Patrick McHardy @ 2005-03-28 22:20 UTC (permalink / raw)
  To: Catalin(ux aka Dino) BOIE; +Cc: netdev, davem

Catalin(ux aka Dino) BOIE wrote:
> What to fix in Dave's patch? Seems ok to me.

It didn't apply cleanly when I tried to apply it. Did
you try with latest -bk?

Regards
Patrick

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

* Re: [PATCH] rtnl_unlock/lock in sch_api.c
  2005-03-28 22:20     ` Patrick McHardy
@ 2005-03-28 22:21       ` Catalin(ux aka Dino) BOIE
  0 siblings, 0 replies; 7+ messages in thread
From: Catalin(ux aka Dino) BOIE @ 2005-03-28 22:21 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netdev, davem

On Tue, 29 Mar 2005, Patrick McHardy wrote:

> Catalin(ux aka Dino) BOIE wrote:
>> What to fix in Dave's patch? Seems ok to me.
>
> It didn't apply cleanly when I tried to apply it. Did
> you try with latest -bk?
>
> Regards
> Patrick

OK. I will fix it and I'll post again.
Thank you!

---
Catalin(ux aka Dino) BOIE
catab at deuroconsult.ro
http://kernel.umbrella.ro/

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

* Re: [PATCH] rtnl_unlock/lock in sch_api.c
  2005-03-28 14:47 ` Thomas Graf
@ 2005-03-28 22:27   ` Catalin(ux aka Dino) BOIE
  0 siblings, 0 replies; 7+ messages in thread
From: Catalin(ux aka Dino) BOIE @ 2005-03-28 22:27 UTC (permalink / raw)
  To: Thomas Graf; +Cc: netdev, davem

On Mon, 28 Mar 2005, Thomas Graf wrote:

> Looks good, except...
>> +				err = -EAGAIN;
>
> You're missing a goto err_out here, the ops == NULL won't catch it.
>
>> +			}
>>  		}
>>  	}
>>  #endif
>>
>> -	err = -EINVAL;
>>  	if (ops == NULL)
>>  		goto err_out;
>
> With the above goto inserted there is no need to move the err = -EINVAL.

Thanks, Thomas.

You are right.

I'm redoind the patch right now.

---
Catalin(ux aka Dino) BOIE
catab at deuroconsult.ro
http://kernel.umbrella.ro/

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

end of thread, other threads:[~2005-03-28 22:27 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-28 14:25 [PATCH] rtnl_unlock/lock in sch_api.c Catalin(ux aka Dino) BOIE
2005-03-28 14:47 ` Thomas Graf
2005-03-28 22:27   ` Catalin(ux aka Dino) BOIE
2005-03-28 14:50 ` Patrick McHardy
2005-03-28 22:16   ` Catalin(ux aka Dino) BOIE
2005-03-28 22:20     ` Patrick McHardy
2005-03-28 22:21       ` Catalin(ux aka Dino) BOIE

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).