All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next-2.6] can: convert protocol handling to RCU
@ 2011-04-04 20:21 Oliver Hartkopp
  2011-04-04 20:26 ` Eric Dumazet
  2011-04-05 17:52 ` Oliver Hartkopp
  0 siblings, 2 replies; 3+ messages in thread
From: Oliver Hartkopp @ 2011-04-04 20:21 UTC (permalink / raw)
  To: David Miller
  Cc: Linux Netdev List, Kurt Van Dijck, Eric Dumazet, Urs Thuermann

This patch removes spin_locks at CAN socket creation time by using RCU.

Inspired by the discussion with Kurt van Dijck and Eric Dumazet the RCU code
was partly derived from af_phonet.c

Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>

---

diff --git a/net/can/af_can.c b/net/can/af_can.c
index 733d66f..551ebc1 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -85,7 +85,7 @@ static struct kmem_cache *rcv_cache __read_mostly;
 
 /* table of registered CAN protocols */
 static struct can_proto *proto_tab[CAN_NPROTO] __read_mostly;
-static DEFINE_SPINLOCK(proto_tab_lock);
+static DEFINE_MUTEX(proto_tab_lock);
 
 struct timer_list can_stattimer;   /* timer for statistics update */
 struct s_stats    can_stats;       /* packet statistics */
@@ -115,6 +115,19 @@ static void can_sock_destruct(struct sock *sk)
 	skb_queue_purge(&sk->sk_receive_queue);
 }
 
+static struct can_proto *can_try_module_get(int protocol)
+{
+	struct can_proto *cp;
+
+	rcu_read_lock();
+	cp = rcu_dereference(proto_tab[protocol]);
+	if (cp && !try_module_get(cp->prot->owner))
+		cp = NULL;
+	rcu_read_unlock();
+
+	return cp;
+}
+
 static int can_create(struct net *net, struct socket *sock, int protocol,
 		      int kern)
 {
@@ -130,9 +143,12 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
 	if (!net_eq(net, &init_net))
 		return -EAFNOSUPPORT;
 
+	cp = can_try_module_get(protocol);
+
 #ifdef CONFIG_MODULES
-	/* try to load protocol module kernel is modular */
-	if (!proto_tab[protocol]) {
+	if (!cp) {
+		/* try to load protocol module if kernel is modular */
+
 		err = request_module("can-proto-%d", protocol);
 
 		/*
@@ -143,22 +159,18 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
 		if (err && printk_ratelimit())
 			printk(KERN_ERR "can: request_module "
 			       "(can-proto-%d) failed.\n", protocol);
+		else
+			cp = can_try_module_get(protocol);
 	}
 #endif
 
-	spin_lock(&proto_tab_lock);
-	cp = proto_tab[protocol];
-	if (cp && !try_module_get(cp->prot->owner))
-		cp = NULL;
-	spin_unlock(&proto_tab_lock);
-
 	/* check for available protocol and correct usage */
 
 	if (!cp)
 		return -EPROTONOSUPPORT;
 
 	if (cp->type != sock->type) {
-		err = -EPROTONOSUPPORT;
+		err = -EPROTOTYPE;
 		goto errout;
 	}
 
@@ -694,15 +706,16 @@ int can_proto_register(struct can_proto *cp)
 	if (err < 0)
 		return err;
 
-	spin_lock(&proto_tab_lock);
+	mutex_lock(&proto_tab_lock);
+
 	if (proto_tab[proto]) {
 		printk(KERN_ERR "can: protocol %d already registered\n",
 		       proto);
 		err = -EBUSY;
 	} else
-		proto_tab[proto] = cp;
+		rcu_assign_pointer(proto_tab[proto], cp);
 
-	spin_unlock(&proto_tab_lock);
+	mutex_unlock(&proto_tab_lock);
 
 	if (err < 0)
 		proto_unregister(cp->prot);
@@ -719,13 +732,12 @@ void can_proto_unregister(struct can_proto *cp)
 {
 	int proto = cp->protocol;
 
-	spin_lock(&proto_tab_lock);
-	if (!proto_tab[proto]) {
-		printk(KERN_ERR "BUG: can: protocol %d is not registered\n",
-		       proto);
-	}
-	proto_tab[proto] = NULL;
-	spin_unlock(&proto_tab_lock);
+	mutex_lock(&proto_tab_lock);
+	BUG_ON(proto_tab[proto] != cp);
+	rcu_assign_pointer(proto_tab[proto], NULL);
+	mutex_unlock(&proto_tab_lock);
+
+	synchronize_rcu();
 
 	proto_unregister(cp->prot);
 }


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

* Re: [PATCH net-next-2.6] can: convert protocol handling to RCU
  2011-04-04 20:21 [PATCH net-next-2.6] can: convert protocol handling to RCU Oliver Hartkopp
@ 2011-04-04 20:26 ` Eric Dumazet
  2011-04-05 17:52 ` Oliver Hartkopp
  1 sibling, 0 replies; 3+ messages in thread
From: Eric Dumazet @ 2011-04-04 20:26 UTC (permalink / raw)
  To: Oliver Hartkopp
  Cc: David Miller, Linux Netdev List, Kurt Van Dijck, Urs Thuermann

Le lundi 04 avril 2011 à 22:21 +0200, Oliver Hartkopp a écrit :
> This patch removes spin_locks at CAN socket creation time by using RCU.
> 
> Inspired by the discussion with Kurt van Dijck and Eric Dumazet the RCU code
> was partly derived from af_phonet.c
> 
> Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
> 
> ---
> 
> diff --git a/net/can/af_can.c b/net/can/af_can.c
> index 733d66f..551ebc1 100644
> --- a/net/can/af_can.c
> +++ b/net/can/af_can.c
> @@ -85,7 +85,7 @@ static struct kmem_cache *rcv_cache __read_mostly;

Seems good to me, thanks !

Reviewed-by: Eric Dumazet <eric.dumazet@gmail.com>




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

* Re: [PATCH net-next-2.6] can: convert protocol handling to RCU
  2011-04-04 20:21 [PATCH net-next-2.6] can: convert protocol handling to RCU Oliver Hartkopp
  2011-04-04 20:26 ` Eric Dumazet
@ 2011-04-05 17:52 ` Oliver Hartkopp
  1 sibling, 0 replies; 3+ messages in thread
From: Oliver Hartkopp @ 2011-04-05 17:52 UTC (permalink / raw)
  To: David Miller
  Cc: Linux Netdev List, Kurt Van Dijck, Eric Dumazet, Urs Thuermann

On 04.04.2011 22:21, Oliver Hartkopp wrote:
> This patch removes spin_locks at CAN socket creation time by using RCU.
> 


> @@ -143,22 +159,18 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
>  		if (err && printk_ratelimit())
>  			printk(KERN_ERR "can: request_module "
>  			       "(can-proto-%d) failed.\n", protocol);
> +		else
> +			cp = can_try_module_get(protocol);
>  	}

Hm, i just discovered a tiny issue here as putting can_try_module_get() into
the 'else' path is not needed.

Will send a V2 in a few minutes.


Regards,
Oliver

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

end of thread, other threads:[~2011-04-05 17:52 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-04 20:21 [PATCH net-next-2.6] can: convert protocol handling to RCU Oliver Hartkopp
2011-04-04 20:26 ` Eric Dumazet
2011-04-05 17:52 ` Oliver Hartkopp

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.