All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jon Maloy <jon.maloy@ericsson.com>
To: davem@davemloft.net
Cc: netdev@vger.kernel.org,
	Paul Gortmaker <paul.gortmaker@windriver.com>,
	erik.hugne@ericsson.com, ying.xue@windriver.com,
	maloy@donjonn.com, tipc-discussion@lists.sourceforge.net,
	Jon Maloy <jon.maloy@ericsson.com>
Subject: [PATCH net-next 05/13] tipc: introduce direct iovec to buffer chain fragmentation function
Date: Wed, 25 Jun 2014 20:41:34 -0500	[thread overview]
Message-ID: <1403746902-20408-6-git-send-email-jon.maloy@ericsson.com> (raw)
In-Reply-To: <1403746902-20408-1-git-send-email-jon.maloy@ericsson.com>

Fragmentation at message sending is currently performed in two
places in link.c, depending on whether data to be transmitted
is delivered in the form of an iovec or as a big sk_buff. Those
functions are also tightly entangled with the send functions
that are using them.

We now introduce a re-entrant, standalone function, tipc_msg_build2(),
that builds a packet chain directly from an iovec. Each fragment is
sized according to the MTU value given by the caller, and is prepended
with a correctly built fragment header, when needed. The function is
independent from who is calling and where the chain will be delivered,
as long as the caller is able to indicate a correct MTU.

The function is tested, but not called by anybody yet. Since it is
incompatible with the existing tipc_msg_build(), and we cannot yet
remove that function, we have given it a temporary name.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/msg.c |  102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 net/tipc/msg.h |    3 ++
 2 files changed, 105 insertions(+)

diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index e02afc9..4093b4c 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -144,6 +144,108 @@ out_free:
 	return 0;
 }
 
+
+/**
+ * tipc_msg_build2 - create buffer chain containing specified header and data
+ * @mhdr: Message header, to be prepended to data
+ * @iov: User data
+ * @offset: Posision in iov to start copying from
+ * @dsz: Total length of user data
+ * @pktmax: Max packet size that can be used
+ * @chain: Buffer or chain of buffers to be returned to caller
+ * Returns message data size or errno: -ENOMEM, -EFAULT
+ */
+int tipc_msg_build2(struct tipc_msg *mhdr, struct iovec const *iov,
+		    int offset, int dsz, int pktmax , struct sk_buff **chain)
+{
+	int mhsz = msg_hdr_sz(mhdr);
+	int msz = mhsz + dsz;
+	int pktno = 1;
+	int pktsz;
+	int pktrem = pktmax;
+	int drem = dsz;
+	struct tipc_msg pkthdr;
+	struct sk_buff *buf, *prev;
+	char *pktpos;
+	int rc;
+
+	msg_set_size(mhdr, msz);
+
+	/* No fragmentation needed? */
+	if (likely(msz <= pktmax)) {
+		buf = tipc_buf_acquire(msz);
+		*chain = buf;
+		if (unlikely(!buf))
+			return -ENOMEM;
+		skb_copy_to_linear_data(buf, mhdr, mhsz);
+		pktpos = buf->data + mhsz;
+		if (!dsz || !memcpy_fromiovecend(pktpos, iov, offset, dsz))
+			return dsz;
+		rc = -EFAULT;
+		goto error;
+	}
+
+	/* Prepare reusable fragment header */
+	tipc_msg_init(&pkthdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
+		      INT_H_SIZE, msg_destnode(mhdr));
+	msg_set_size(&pkthdr, pktmax);
+	msg_set_fragm_no(&pkthdr, pktno);
+
+	/* Prepare first fragment */
+	*chain = buf = tipc_buf_acquire(pktmax);
+	if (!buf)
+		return -ENOMEM;
+	pktpos = buf->data;
+	skb_copy_to_linear_data(buf, &pkthdr, INT_H_SIZE);
+	pktpos += INT_H_SIZE;
+	pktrem -= INT_H_SIZE;
+	skb_copy_to_linear_data_offset(buf, INT_H_SIZE, mhdr, mhsz);
+	pktpos += mhsz;
+	pktrem -= mhsz;
+
+	do {
+		if (drem < pktrem)
+			pktrem = drem;
+
+		if (memcpy_fromiovecend(pktpos, iov, offset, pktrem)) {
+			rc = -EFAULT;
+			goto error;
+		}
+		drem -= pktrem;
+		offset += pktrem;
+
+		if (!drem)
+			break;
+
+		/* Prepare new fragment: */
+		if (drem < (pktmax - INT_H_SIZE))
+			pktsz = drem + INT_H_SIZE;
+		else
+			pktsz = pktmax;
+		prev = buf;
+		buf = tipc_buf_acquire(pktsz);
+		if (!buf) {
+			rc = -ENOMEM;
+			goto error;
+		}
+		prev->next = buf;
+		msg_set_type(&pkthdr, FRAGMENT);
+		msg_set_size(&pkthdr, pktsz);
+		msg_set_fragm_no(&pkthdr, ++pktno);
+		skb_copy_to_linear_data(buf, &pkthdr, INT_H_SIZE);
+		pktpos = buf->data + INT_H_SIZE;
+		pktrem = pktsz - INT_H_SIZE;
+
+	} while (1);
+
+	msg_set_type(buf_msg(buf), LAST_FRAGMENT);
+	return dsz;
+error:
+	kfree_skb_list(*chain);
+	*chain = NULL;
+	return rc;
+}
+
 /**
  * tipc_msg_bundle(): Append contents of a buffer to tail of an existing one
  * @bbuf: the existing buffer ("bundle")
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 41a05fa..5e1339d 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -737,4 +737,7 @@ bool tipc_msg_bundle(struct sk_buff *bbuf, struct sk_buff *buf, u32 mtu);
 
 bool tipc_msg_make_bundle(struct sk_buff **buf, u32 mtu, u32 dnode);
 
+int tipc_msg_build2(struct tipc_msg *mhdr, struct iovec const *iov,
+		    int offset, int dsz, int mtu , struct sk_buff **chain);
+
 #endif
-- 
1.7.9.5

  parent reply	other threads:[~2014-06-26  1:48 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-26  1:41 [PATCH net-next 00/13] tipc: new unicast transmission code Jon Maloy
2014-06-26  1:41 ` [PATCH net-next 01/13] tipc: eliminate case of writing to freed memory Jon Maloy
2014-06-26 10:56   ` Neil Horman
2014-06-27  3:33     ` Jon Maloy
2014-06-27 11:41       ` Neil Horman
2014-06-26  1:41 ` [PATCH net-next 02/13] tipc: use negative error return values in functions Jon Maloy
2014-06-26  1:41 ` [PATCH net-next 03/13] tipc: introduce send functions for chained buffers in link Jon Maloy
2014-06-26  1:41 ` [PATCH net-next 04/13] tipc: make link mtu easily accessible from socket Jon Maloy
2014-06-26  1:41 ` Jon Maloy [this message]
2014-06-26  1:41 ` [PATCH net-next 06/13] tipc: separate building and sending of rejected messages Jon Maloy
2014-06-26  1:41 ` [PATCH net-next 07/13] tipc: introduce message evaluation function Jon Maloy
2014-06-26  1:41 ` [PATCH net-next 08/13] tipc: RDM/DGRAM transport uses new fragmenting and sending functions Jon Maloy
2014-06-26  1:41 ` [PATCH net-next 09/13] tipc: connection oriented transport uses new send functions Jon Maloy
2014-06-26  1:41 ` [PATCH net-next 10/13] tipc: let port protocol senders use new link send function Jon Maloy
2014-06-26  1:41 ` [PATCH net-next 11/13] tipc: same receive code path for connection protocol and data messages Jon Maloy
2014-06-26  1:41 ` [PATCH net-next 12/13] tipc: clean up connection protocol reception function Jon Maloy
2014-06-26  1:41 ` [PATCH net-next 13/13] tipc: simplify connection congestion handling Jon Maloy
2014-06-27 19:56 ` [PATCH net-next 00/13] tipc: new unicast transmission code David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1403746902-20408-6-git-send-email-jon.maloy@ericsson.com \
    --to=jon.maloy@ericsson.com \
    --cc=davem@davemloft.net \
    --cc=erik.hugne@ericsson.com \
    --cc=maloy@donjonn.com \
    --cc=netdev@vger.kernel.org \
    --cc=paul.gortmaker@windriver.com \
    --cc=tipc-discussion@lists.sourceforge.net \
    --cc=ying.xue@windriver.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.