[PATCH v1 25/40] j1939: allow to use session by socket code

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

 



for multi skb session socket code should be able to queue
skbs directly to the session. So, refactor the code appropriately.

Signed-off-by: Oleksij Rempel <o.rempel@xxxxxxxxxxxxxx>
---
 net/can/j1939/j1939-priv.h | 59 +++++++++++++++++++++++++++++-
 net/can/j1939/socket.c     |  9 ++++-
 net/can/j1939/transport.c  | 73 ++++++--------------------------------
 3 files changed, 77 insertions(+), 64 deletions(-)

diff --git a/net/can/j1939/j1939-priv.h b/net/can/j1939/j1939-priv.h
index 8bd092a007b5..dd9c513396e6 100644
--- a/net/can/j1939/j1939-priv.h
+++ b/net/can/j1939/j1939-priv.h
@@ -153,7 +153,8 @@ int j1939_send_one(struct j1939_priv *priv, struct sk_buff *skb);
 void j1939_sk_recv(struct sk_buff *skb);
 
 /* stack entries */
-int j1939_tp_send(struct j1939_priv *priv, struct sk_buff *skb);
+struct j1939_session *j1939_tp_send(struct j1939_priv *priv,
+				    struct sk_buff *skb, size_t size);
 int j1939_tp_recv(struct j1939_priv *priv, struct sk_buff *skb);
 int j1939_ac_fixup(struct j1939_priv *priv, struct sk_buff *skb);
 void j1939_ac_recv(struct j1939_priv *priv, struct sk_buff *skb);
@@ -180,6 +181,62 @@ void j1939_tp_init(struct j1939_priv *priv);
 /* decrement pending skb for a j1939 socket */
 void j1939_sock_pending_del(struct sock *sk);
 
+struct j1939_session {
+	struct j1939_priv *priv;
+	struct list_head list;
+	struct kref kref;
+	spinlock_t lock;
+
+	/* ifindex, src, dst, pgn define the session block
+	 * the are _never_ modified after insertion in the list
+	 * this decreases locking problems a _lot_
+	 */
+	struct j1939_sk_buff_cb skcb;
+	struct sk_buff_head skb_queue;
+
+	/* all tx related stuff (last_txcmd, pkt.tx)
+	 * is protected (modified only) with the txtimer hrtimer
+	 * 'total' & 'block' are never changed,
+	 * last_cmd, last & block are protected by ->lock
+	 * this means that the tx may run after cts is received that should
+	 * have stopped tx, but this time discrepancy is never avoided anyhow
+	 */
+	u8 last_cmd, last_txcmd;
+	bool transmission;
+	bool extd;
+	unsigned int total_message_size; /* Total message size, number of bytes */
+
+	/* Packets counters for a (extended) transfer session. The packet is
+	 * maximal of 7 bytes. */
+	struct {
+		/* total - total number of packets for this session */
+		unsigned int total;
+		/* last - last packet of a transfer block after which responder
+		 * should send ETP.CM_CTS and originator ETP.CM_DPO */
+		unsigned int last;
+		/* tx - number of packets send by originator node.
+		 * this counter can be set back if responder node didn't
+		 * received all packets send by originator. */
+		unsigned int tx;
+		/* done - number of packets received and confirmed by
+		 * responder */
+		unsigned int done;
+		/* block - amount of packets expected in one block */
+		unsigned int block;
+		/* dpo - ETP.CM_DPO, Data Packet Offset */
+		unsigned int dpo;
+	} pkt;
+	struct hrtimer txtimer, rxtimer;
+};
+
+void j1939_session_get(struct j1939_session *session);
+void j1939_session_put(struct j1939_session *session);
+void j1939_session_skb_queue(struct j1939_session *session,
+			     struct sk_buff *skb);
+
+#define J1939_MAX_TP_PACKET_SIZE (7 * 0xff)
+#define J1939_MAX_ETP_PACKET_SIZE (7 * 0x00ffffff)
+
 /* CAN protocol */
 extern const struct can_proto j1939_can_proto;
 
diff --git a/net/can/j1939/socket.c b/net/can/j1939/socket.c
index a3ba03593fe6..2ba4a35c1c84 100644
--- a/net/can/j1939/socket.c
+++ b/net/can/j1939/socket.c
@@ -681,6 +681,7 @@ static int j1939_sk_send_multi(struct j1939_priv *priv,  struct sock *sk,
 			       struct msghdr *msg, size_t size)
 
 {
+	struct j1939_session *session;
 	struct sk_buff *skb;
 	int ret;
 
@@ -688,7 +689,13 @@ static int j1939_sk_send_multi(struct j1939_priv *priv,  struct sock *sk,
 	if (ret)
 		return ret;
 
-	return j1939_tp_send(priv, skb);
+	session = j1939_tp_send(priv, skb, size);
+	if (IS_ERR(session))
+		return PTR_ERR(session);
+
+	j1939_session_put(session);
+
+	return 0;
 }
 
 static int j1939_sk_send_one(struct j1939_priv *priv,  struct sock *sk,
diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
index 1970590a65d0..a97ab434156b 100644
--- a/net/can/j1939/transport.c
+++ b/net/can/j1939/transport.c
@@ -37,62 +37,11 @@ enum j1939_xtp_abort {
 	J1939_XTP_ABORT_FAULT = 5,
 };
 
-#define J1939_MAX_TP_PACKET_SIZE (7 * 0xff)
-#define J1939_MAX_ETP_PACKET_SIZE (7 * 0x00ffffff)
-
 static unsigned int j1939_tp_block = 255;
 static unsigned int j1939_tp_retry_ms = 20;
 static unsigned int j1939_tp_packet_delay;
 static unsigned int j1939_tp_padding = 1;
 
-struct j1939_session {
-	struct j1939_priv *priv;
-	struct list_head list;
-	struct kref kref;
-	spinlock_t lock;
-
-	/* ifindex, src, dst, pgn define the session block
-	 * the are _never_ modified after insertion in the list
-	 * this decreases locking problems a _lot_
-	 */
-	struct j1939_sk_buff_cb skcb;
-	struct sk_buff_head skb_queue;
-
-	/* all tx related stuff (last_txcmd, pkt.tx)
-	 * is protected (modified only) with the txtimer hrtimer
-	 * 'total' & 'block' are never changed,
-	 * last_cmd, last & block are protected by ->lock
-	 * this means that the tx may run after cts is received that should
-	 * have stopped tx, but this time discrepancy is never avoided anyhow
-	 */
-	u8 last_cmd, last_txcmd;
-	bool transmission;
-	bool extd;
-	unsigned int total_message_size; /* Total message size, number of bytes */
-
-	/* Packets counters for a (extended) transfer session. The packet is
-	 * maximal of 7 bytes. */
-	struct {
-		/* total - total number of packets for this session */
-		unsigned int total;
-		/* last - last packet of a transfer block after which responder
-		 * should send ETP.CM_CTS and originator ETP.CM_DPO */
-		unsigned int last;
-		/* tx - number of packets send by originator node.
-		 * this counter can be set back if responder node didn't
-		 * received all packets send by originator. */
-		unsigned int tx;
-		/* done - number of packets received and confirmed by
-		 * responder */
-		unsigned int done;
-		/* block - amount of packets expected in one block */
-		unsigned int block;
-		/* dpo - ETP.CM_DPO, Data Packet Offset */
-		unsigned int dpo;
-	} pkt;
-	struct hrtimer txtimer, rxtimer;
-};
-
 /* helpers */
 static inline void j1939_fix_cb(struct j1939_sk_buff_cb *skcb)
 {
@@ -130,7 +79,7 @@ static void j1939_session_list_del(struct j1939_session *session)
 	list_del_init(&session->list);
 }
 
-static inline void j1939_session_get(struct j1939_session *session)
+void j1939_session_get(struct j1939_session *session)
 {
 	kref_get(&session->kref);
 }
@@ -153,7 +102,7 @@ static void __j1939_session_release(struct kref *kref)
 	j1939_session_destroy(session);
 }
 
-static inline void j1939_session_put(struct j1939_session *session)
+void j1939_session_put(struct j1939_session *session)
 {
 	kref_put(&session->kref, __j1939_session_release);
 }
@@ -1290,7 +1239,8 @@ static inline int j1939_tp_tx_initial(struct j1939_session *session)
 }
 
 /* j1939 main intf */
-int j1939_tp_send(struct j1939_priv *priv, struct sk_buff *skb)
+struct j1939_session *j1939_tp_send(struct j1939_priv *priv,
+				    struct sk_buff *skb, size_t size)
 {
 	struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb);
 	struct j1939_session *session;
@@ -1302,21 +1252,21 @@ int j1939_tp_send(struct j1939_priv *priv, struct sk_buff *skb)
 	    skcb->addr.pgn == J1939_ETP_PGN_DAT ||
 	    skcb->addr.pgn == J1939_ETP_PGN_CTL)
 		/* avoid conflict */
-		return -EDOM;
+		return ERR_PTR(-EDOM);
 
 	if (skb->len > priv->tp_max_packet_size)
-		return -EMSGSIZE;
+		return ERR_PTR(-EMSGSIZE);
 
 	if (skb->len > J1939_MAX_TP_PACKET_SIZE)
 		extd = J1939_EXTENDED;
 
 	if (extd && j1939_cb_is_broadcast(skcb))
-		return -EDESTADDRREQ;
+		return ERR_PTR(-EDESTADDRREQ);
 
 	/* fill in addresses from names */
 	ret = j1939_ac_fixup(priv, skb);
 	if (unlikely(ret))
-		return ret;
+		return ERR_PTR(ret);
 
 	/* fix dst_flags, it may be used there soon */
 	if (j1939_address_is_unicast(skcb->addr.da) &&
@@ -1329,7 +1279,7 @@ int j1939_tp_send(struct j1939_priv *priv, struct sk_buff *skb)
 	/* prepare new session */
 	session = j1939_session_new(priv, skb);
 	if (!session)
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 
 	/* skb is recounted in j1939_session_new() */
 	session->extd = extd;
@@ -1356,14 +1306,13 @@ int j1939_tp_send(struct j1939_priv *priv, struct sk_buff *skb)
 		goto failed;
 
 	/* transmission started */
-	j1939_session_put(session);
-	return 0;
+	return session;
 
  failed:
 	j1939_session_timers_cancel(session);
 	j1939_session_cancel(session, J1939_XTP_ABORT_NO_ERROR);
 	j1939_session_put(session);
-	return ret;
+	return ERR_PTR(ret);
 }
 
 static void j1939_tp_cmd_recv(struct j1939_priv *priv, struct sk_buff *skb,
-- 
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