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
next prev 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 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).