aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/msg.c
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2014-06-25 21:41:32 -0400
committerDavid S. Miller <davem@davemloft.net>2014-06-27 15:50:54 -0400
commit4f1688b2c63cd86f0d7bcf95a9b3040e38bd3c1a (patch)
tree757c43e51ba7260d1745a8d5b2e3bdfb6b0a005a /net/tipc/msg.c
parente4de5fab806f74622600ab7fd6ed22b7f911a8c5 (diff)
tipc: introduce send functions for chained buffers in link
The current link implementation provides several different transmit functions, depending on the characteristics of the message to be sent: if it is an iovec or an sk_buff, if it needs fragmentation or not, if the caller holds the node_lock or not. The permutation of these options gives us an unwanted amount of unnecessarily complex code. As a first step towards simplifying the send path for all messages, we introduce two new send functions at link level, tipc_link_xmit2() and __tipc_link_xmit2(). The former looks up a link to the message destination, and if one is found, it grabs the node lock and calls the second function, which works exclusively inside the node lock protection. If no link is found, and the destination is on the same node, it delivers the message directly to the local destination socket. The new functions take a buffer chain where all packet headers are already prepared, and the correct MTU has been used. These two functions will later replace all other link-level transmit functions. The functions are not backwards compatible, so we have added them as new functions with temporary names. They are tested, but have no users yet. Those will be added later in this series. 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> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/msg.c')
-rw-r--r--net/tipc/msg.c96
1 files changed, 85 insertions, 11 deletions
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 8be6e94a1ca9..e02afc96edd7 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -37,20 +37,11 @@
37#include "core.h" 37#include "core.h"
38#include "msg.h" 38#include "msg.h"
39 39
40u32 tipc_msg_tot_importance(struct tipc_msg *m) 40static unsigned int align(unsigned int i)
41{ 41{
42 if (likely(msg_isdata(m))) { 42 return (i + 3) & ~3u;
43 if (likely(msg_orignode(m) == tipc_own_addr))
44 return msg_importance(m);
45 return msg_importance(m) + 4;
46 }
47 if ((msg_user(m) == MSG_FRAGMENTER) &&
48 (msg_type(m) == FIRST_FRAGMENT))
49 return msg_importance(msg_get_wrapped(m));
50 return msg_importance(m);
51} 43}
52 44
53
54void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize, 45void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize,
55 u32 destnode) 46 u32 destnode)
56{ 47{
@@ -152,3 +143,86 @@ out_free:
152 kfree_skb(*buf); 143 kfree_skb(*buf);
153 return 0; 144 return 0;
154} 145}
146
147/**
148 * tipc_msg_bundle(): Append contents of a buffer to tail of an existing one
149 * @bbuf: the existing buffer ("bundle")
150 * @buf: buffer to be appended
151 * @mtu: max allowable size for the bundle buffer
152 * Consumes buffer if successful
153 * Returns true if bundling could be performed, otherwise false
154 */
155bool tipc_msg_bundle(struct sk_buff *bbuf, struct sk_buff *buf, u32 mtu)
156{
157 struct tipc_msg *bmsg = buf_msg(bbuf);
158 struct tipc_msg *msg = buf_msg(buf);
159 unsigned int bsz = msg_size(bmsg);
160 unsigned int msz = msg_size(msg);
161 u32 start = align(bsz);
162 u32 max = mtu - INT_H_SIZE;
163 u32 pad = start - bsz;
164
165 if (likely(msg_user(msg) == MSG_FRAGMENTER))
166 return false;
167 if (unlikely(msg_user(msg) == CHANGEOVER_PROTOCOL))
168 return false;
169 if (unlikely(msg_user(msg) == BCAST_PROTOCOL))
170 return false;
171 if (likely(msg_user(bmsg) != MSG_BUNDLER))
172 return false;
173 if (likely(msg_type(bmsg) != BUNDLE_OPEN))
174 return false;
175 if (unlikely(skb_tailroom(bbuf) < (pad + msz)))
176 return false;
177 if (unlikely(max < (start + msz)))
178 return false;
179
180 skb_put(bbuf, pad + msz);
181 skb_copy_to_linear_data_offset(bbuf, start, buf->data, msz);
182 msg_set_size(bmsg, start + msz);
183 msg_set_msgcnt(bmsg, msg_msgcnt(bmsg) + 1);
184 bbuf->next = buf->next;
185 kfree_skb(buf);
186 return true;
187}
188
189/**
190 * tipc_msg_make_bundle(): Create bundle buf and append message to its tail
191 * @buf: buffer to be appended and replaced
192 * @mtu: max allowable size for the bundle buffer, inclusive header
193 * @dnode: destination node for message. (Not always present in header)
194 * Replaces buffer if successful
195 * Returns true if sucess, otherwise false
196 */
197bool tipc_msg_make_bundle(struct sk_buff **buf, u32 mtu, u32 dnode)
198{
199 struct sk_buff *bbuf;
200 struct tipc_msg *bmsg;
201 struct tipc_msg *msg = buf_msg(*buf);
202 u32 msz = msg_size(msg);
203 u32 max = mtu - INT_H_SIZE;
204
205 if (msg_user(msg) == MSG_FRAGMENTER)
206 return false;
207 if (msg_user(msg) == CHANGEOVER_PROTOCOL)
208 return false;
209 if (msg_user(msg) == BCAST_PROTOCOL)
210 return false;
211 if (msz > (max / 2))
212 return false;
213
214 bbuf = tipc_buf_acquire(max);
215 if (!bbuf)
216 return false;
217
218 skb_trim(bbuf, INT_H_SIZE);
219 bmsg = buf_msg(bbuf);
220 tipc_msg_init(bmsg, MSG_BUNDLER, BUNDLE_OPEN, INT_H_SIZE, dnode);
221 msg_set_seqno(bmsg, msg_seqno(msg));
222 msg_set_ack(bmsg, msg_ack(msg));
223 msg_set_bcast_ack(bmsg, msg_bcast_ack(msg));
224 bbuf->next = (*buf)->next;
225 tipc_msg_bundle(bbuf, *buf, mtu);
226 *buf = bbuf;
227 return true;
228}