[PATCH v1 36/40] j1939: move j1939_socks socket list to the priv

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



with attempt to reduce skb redistribution.

Signed-off-by: Oleksij Rempel <o.rempel@xxxxxxxxxxxxxx>
---
 net/can/j1939/j1939-priv.h |  5 +++-
 net/can/j1939/main.c       |  4 ++-
 net/can/j1939/socket.c     | 59 ++++++++++++++++----------------------
 net/can/j1939/transport.c  |  3 +-
 4 files changed, 34 insertions(+), 37 deletions(-)

diff --git a/net/can/j1939/j1939-priv.h b/net/can/j1939/j1939-priv.h
index dd9c513396e6..9e62e63aafbb 100644
--- a/net/can/j1939/j1939-priv.h
+++ b/net/can/j1939/j1939-priv.h
@@ -64,6 +64,9 @@ struct j1939_priv {
 	struct list_head tp_extsessionq;
 	wait_queue_head_t tp_wait;
 	unsigned int tp_max_packet_size;
+
+	struct list_head j1939_socks;
+	spinlock_t j1939_socks_lock;
 };
 
 void j1939_ecu_put(struct j1939_ecu *ecu);
@@ -150,7 +153,7 @@ static inline struct j1939_sk_buff_cb *j1939_skb_to_cb(struct sk_buff *skb)
 }
 
 int j1939_send_one(struct j1939_priv *priv, struct sk_buff *skb);
-void j1939_sk_recv(struct sk_buff *skb);
+void j1939_sk_recv(struct j1939_priv *priv, struct sk_buff *skb);
 
 /* stack entries */
 struct j1939_session *j1939_tp_send(struct j1939_priv *priv,
diff --git a/net/can/j1939/main.c b/net/can/j1939/main.c
index 13ac2661625c..11b63015b4f0 100644
--- a/net/can/j1939/main.c
+++ b/net/can/j1939/main.c
@@ -88,7 +88,7 @@ static void j1939_can_recv(struct sk_buff *iskb, void *data)
 	if (j1939_tp_recv(priv, skb))
 		/* this means the transport layer processed the message */
 		goto done;
-	j1939_sk_recv(skb);
+	j1939_sk_recv(priv, skb);
  done:
 	kfree_skb(skb);
 }
@@ -170,6 +170,8 @@ int j1939_netdev_start(struct net *net, struct net_device *ndev)
 		return -ENOMEM;
 
 	j1939_tp_init(priv);
+	spin_lock_init(&priv->j1939_socks_lock);
+	INIT_LIST_HEAD(&priv->j1939_socks);
 
 	/* add CAN handler */
 	ret = can_rx_register(net, ndev, J1939_CAN_ID, J1939_CAN_MASK,
diff --git a/net/can/j1939/socket.c b/net/can/j1939/socket.c
index 155af82f5b3a..c1ee5fa7b6f7 100644
--- a/net/can/j1939/socket.c
+++ b/net/can/j1939/socket.c
@@ -15,10 +15,6 @@
 
 #define J1939_MIN_NAMELEN REQUIRED_SIZE(struct sockaddr_can, can_addr.j1939)
 
-/* list of sockets */
-static struct list_head j1939_socks = LIST_HEAD_INIT(j1939_socks);
-static DEFINE_SPINLOCK(j1939_socks_lock);
-
 struct j1939_sock {
 	struct sock sk; /* must be first to skip with memset */
 	struct list_head list;
@@ -197,15 +193,15 @@ static void j1939_sk_recv_one(struct j1939_sock *jsk, struct sk_buff *oskb)
 		kfree_skb(skb);
 }
 
-void j1939_sk_recv(struct sk_buff *skb)
+void j1939_sk_recv(struct j1939_priv *priv, struct sk_buff *skb)
 {
 	struct j1939_sock *jsk;
 
-	spin_lock_bh(&j1939_socks_lock);
-	list_for_each_entry(jsk, &j1939_socks, list) {
+	spin_lock_bh(&priv->j1939_socks_lock);
+	list_for_each_entry(jsk, &priv->j1939_socks, list) {
 		j1939_sk_recv_one(jsk, skb);
 	}
-	spin_unlock_bh(&j1939_socks_lock);
+	spin_unlock_bh(&priv->j1939_socks_lock);
 }
 
 static int j1939_sk_init(struct sock *sk)
@@ -297,19 +293,19 @@ static int j1939_sk_bind(struct socket *sock, struct sockaddr *uaddr, int len)
 
 	/* get new references */
 	ret = j1939_local_ecu_get(priv, jsk->addr.src_name, jsk->addr.sa);
-	j1939_priv_put(priv);
 	if (ret) {
 		j1939_netdev_stop(ndev);
 		goto out_dev_put;
 	}
 
 	if (!(jsk->state & J1939_SOCK_BOUND)) {
-		spin_lock_bh(&j1939_socks_lock);
-		list_add_tail(&jsk->list, &j1939_socks);
-		spin_unlock_bh(&j1939_socks_lock);
+		spin_lock_bh(&priv->j1939_socks_lock);
+		list_add_tail(&jsk->list, &priv->j1939_socks);
+		spin_unlock_bh(&priv->j1939_socks_lock);
 
 		jsk->state |= J1939_SOCK_BOUND;
 	}
+	j1939_priv_put(priv);
 
  out_dev_put:	/* fallthrough */
 	dev_put(ndev);
@@ -400,7 +396,6 @@ static int j1939_sk_release(struct socket *sock)
 {
 	struct sock *sk = sock->sk;
 	struct j1939_sock *jsk;
-	struct j1939_priv *priv;
 
 	if (!sk)
 		return 0;
@@ -409,25 +404,25 @@ static int j1939_sk_release(struct socket *sock)
 	lock_sock(sk);
 
 	if (jsk->state & J1939_SOCK_BOUND) {
+		struct j1939_priv *priv;
 		struct net_device *ndev;
 
 		wait_event_interruptible(jsk->waitq,
 					 j1939_sock_pending_get(&jsk->sk) == 0);
 
-		spin_lock_bh(&j1939_socks_lock);
+		ndev = dev_get_by_index(sock_net(sk), jsk->ifindex);
+		priv = j1939_priv_get_by_ndev(ndev);
+
+		spin_lock_bh(&priv->j1939_socks_lock);
 		list_del_init(&jsk->list);
-		spin_unlock_bh(&j1939_socks_lock);
+		spin_unlock_bh(&priv->j1939_socks_lock);
 
-		ndev = dev_get_by_index(sock_net(sk), jsk->ifindex);
-		if (ndev) {
-			priv = j1939_priv_get_by_ndev(ndev);
-			j1939_local_ecu_put(priv, jsk->addr.src_name,
+		j1939_local_ecu_put(priv, jsk->addr.src_name,
 					    jsk->addr.sa);
-			j1939_priv_put(priv);
+		j1939_priv_put(priv);
 
-			j1939_netdev_stop(ndev);
-			dev_put(ndev);
-		}
+		j1939_netdev_stop(ndev);
+		dev_put(ndev);
 	}
 
 	sock_orphan(sk);
@@ -484,11 +479,11 @@ static int j1939_sk_setsockopt(struct socket *sock, int level, int optname,
 				return PTR_ERR(filters);
 		}
 
-		spin_lock_bh(&j1939_socks_lock);
+		lock_sock(&jsk->sk);
 		ofilters = jsk->filters;
 		jsk->filters = filters;
 		jsk->nfilters = count;
-		spin_unlock_bh(&j1939_socks_lock);
+		release_sock(&jsk->sk);
 		kfree(ofilters);
 		return 0;
 	case SO_J1939_PROMISC:
@@ -817,30 +812,26 @@ static int j1939_sk_sendmsg(struct socket *sock, struct msghdr *msg,
 
 void j1939_sk_netdev_event(struct net_device *ndev, int error_code)
 {
+	struct j1939_priv *priv = j1939_priv_get_by_ndev(ndev);
 	struct j1939_sock *jsk;
 
-	spin_lock_bh(&j1939_socks_lock);
-	list_for_each_entry(jsk, &j1939_socks, list) {
-		if (jsk->ifindex != ndev->ifindex)
-			continue;
+	spin_lock_bh(&priv->j1939_socks_lock);
+	list_for_each_entry(jsk, &priv->j1939_socks, list) {
 
 		jsk->sk.sk_err = error_code;
 		if (!sock_flag(&jsk->sk, SOCK_DEAD))
 			jsk->sk.sk_error_report(&jsk->sk);
 
 		if (error_code == ENODEV) {
-			struct j1939_priv *priv;
-
-			priv = j1939_priv_get_by_ndev(ndev);
 			j1939_local_ecu_put(priv, jsk->addr.src_name,
 					    jsk->addr.sa);
-			j1939_priv_put(priv);
 
 			j1939_netdev_stop(ndev);
 		}
 		/* do not remove filters here */
 	}
-	spin_unlock_bh(&j1939_socks_lock);
+	spin_unlock_bh(&priv->j1939_socks_lock);
+	j1939_priv_put(priv);
 }
 
 static const struct proto_ops j1939_ops = {
diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
index b17c7e8573a1..dec4e8749805 100644
--- a/net/can/j1939/transport.c
+++ b/net/can/j1939/transport.c
@@ -697,8 +697,9 @@ static void __j1939_session_drop(struct j1939_session *session)
 static void j1939_session_completed(struct j1939_session *session)
 {
 	struct sk_buff *se_skb = j1939_session_skb_find(session);
+
 	/* distribute among j1939 receivers */
-	j1939_sk_recv(se_skb);
+	j1939_sk_recv(session->priv, se_skb);
 	__j1939_session_drop(session);
 }
 
-- 
2.19.1




[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux