From 670c54083aa6e0eeefda1c4b307a91679b577664 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Sun, 17 Apr 2011 10:29:16 -0400 Subject: tipc: Don't initialize link selector field in fragmented messages Eliminates code that sets the link selector field in the header of fragmented messages, since this information is never referenced. (The unnecessary initialization was harmless as it was over-written by the fragmented message identifier value before the fragments were transmitted.) Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker --- net/tipc/link.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'net/tipc/link.c') diff --git a/net/tipc/link.c b/net/tipc/link.c index ebf338f7b14e..95249ba6e2d6 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -1169,7 +1169,6 @@ again: tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, INT_H_SIZE, msg_destnode(hdr)); - msg_set_link_selector(&fragm_hdr, sender->ref); msg_set_size(&fragm_hdr, max_pkt); msg_set_fragm_no(&fragm_hdr, 1); @@ -2427,7 +2426,6 @@ static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, INT_H_SIZE, destaddr); - msg_set_link_selector(&fragm_hdr, msg_link_selector(inmsg)); msg_set_long_msgno(&fragm_hdr, mod(l_ptr->long_msg_seq_no++)); msg_set_fragm_no(&fragm_hdr, fragm_no); l_ptr->stats.sent_fragmented++; -- cgit v1.2.3 From e0f085964cac97a3a9e47741365ef6a03e500873 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Sun, 17 Apr 2011 11:44:24 -0400 Subject: tipc: Avoid pointless masking of fragmented message identifier Eliminates code that restricts a link's counter of its fragmented messages to a 16-bit value, since the counter value is automatically restricted to this range when it is written into the message header. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker --- net/tipc/link.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net/tipc/link.c') diff --git a/net/tipc/link.c b/net/tipc/link.c index 95249ba6e2d6..ad356df12d1e 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -1276,7 +1276,7 @@ reject: /* Append whole chain to send queue: */ buf = buf_chain; - l_ptr->long_msg_seq_no = mod(l_ptr->long_msg_seq_no + 1); + l_ptr->long_msg_seq_no++; if (!l_ptr->next_out) l_ptr->next_out = buf_chain; l_ptr->stats.sent_fragmented++; @@ -2426,7 +2426,7 @@ static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, INT_H_SIZE, destaddr); - msg_set_long_msgno(&fragm_hdr, mod(l_ptr->long_msg_seq_no++)); + msg_set_long_msgno(&fragm_hdr, l_ptr->long_msg_seq_no++); msg_set_fragm_no(&fragm_hdr, fragm_no); l_ptr->stats.sent_fragmented++; -- cgit v1.2.3 From 77561557447d3be586e701815e261c93c11ded00 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Sun, 17 Apr 2011 13:06:23 -0400 Subject: tipc: Fix issues with fragmentation of an existing message buffer Modifies the routine that fragments an existing message buffer to use similar logic to that used when generating fragments from an iovec. The routine now creates a complete chain of fragments and adds them to the link transmit queue as a unit, so that the link sends all fragments or none; this prevents the incomplete transmission of a fragmented message that might otherwise result because of link congestion or memory exhaustion. This change also ensures that the counter recording the number of fragmented messages sent by the link is now incremented only if the message is actually sent. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker --- net/tipc/link.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) (limited to 'net/tipc/link.c') diff --git a/net/tipc/link.c b/net/tipc/link.c index ad356df12d1e..02b083e5c219 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -2406,6 +2406,8 @@ void tipc_link_recv_bundle(struct sk_buff *buf) */ static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) { + struct sk_buff *buf_chain = NULL; + struct sk_buff *buf_chain_tail = (struct sk_buff *)&buf_chain; struct tipc_msg *inmsg = buf_msg(buf); struct tipc_msg fragm_hdr; u32 insize = msg_size(inmsg); @@ -2414,7 +2416,7 @@ static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) u32 rest = insize; u32 pack_sz = l_ptr->max_pkt; u32 fragm_sz = pack_sz - INT_H_SIZE; - u32 fragm_no = 1; + u32 fragm_no = 0; u32 destaddr; if (msg_short(inmsg)) @@ -2426,9 +2428,6 @@ static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, INT_H_SIZE, destaddr); - msg_set_long_msgno(&fragm_hdr, l_ptr->long_msg_seq_no++); - msg_set_fragm_no(&fragm_hdr, fragm_no); - l_ptr->stats.sent_fragmented++; /* Chop up message: */ @@ -2441,27 +2440,37 @@ static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) } fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE); if (fragm == NULL) { - warn("Link unable to fragment message\n"); - dsz = -ENOMEM; - goto exit; + buf_discard(buf); + while (buf_chain) { + buf = buf_chain; + buf_chain = buf_chain->next; + buf_discard(buf); + } + return -ENOMEM; } msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE); + fragm_no++; + msg_set_fragm_no(&fragm_hdr, fragm_no); skb_copy_to_linear_data(fragm, &fragm_hdr, INT_H_SIZE); skb_copy_to_linear_data_offset(fragm, INT_H_SIZE, crs, fragm_sz); - /* Send queued messages first, if any: */ + buf_chain_tail->next = fragm; + buf_chain_tail = fragm; - l_ptr->stats.sent_fragments++; - tipc_link_send_buf(l_ptr, fragm); - if (!tipc_link_is_up(l_ptr)) - return dsz; - msg_set_fragm_no(&fragm_hdr, ++fragm_no); rest -= fragm_sz; crs += fragm_sz; msg_set_type(&fragm_hdr, FRAGMENT); } -exit: buf_discard(buf); + + /* Append chain of fragments to send queue & send them */ + + l_ptr->long_msg_seq_no++; + link_add_chain_to_outqueue(l_ptr, buf_chain, l_ptr->long_msg_seq_no); + l_ptr->stats.sent_fragments += fragm_no; + l_ptr->stats.sent_fragmented++; + tipc_link_push_queue(l_ptr); + return dsz; } -- cgit v1.2.3 From bebc55aeffa72d8198e5c54cab9973a30e92f854 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 19 Apr 2011 10:17:58 -0400 Subject: tipc: Fix sk_buff leaks when link congestion is detected Modifies a TIPC send routine that did not discard the outgoing sk_buff if it was not transmitted because of link congestion; this eliminates the potential for buffer leakage in the many callers who did not clean up the unsent buffer. (The two routines that previously did discard the unsent buffer have been updated to eliminate their now-redundant clean up.) Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker --- net/tipc/bcast.c | 4 +--- net/tipc/link.c | 7 +++---- 2 files changed, 4 insertions(+), 7 deletions(-) (limited to 'net/tipc/link.c') diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 08e3216a33d2..fa68d1e9ff4b 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -407,9 +407,7 @@ int tipc_bclink_send_msg(struct sk_buff *buf) spin_lock_bh(&bc_lock); res = tipc_link_send_buf(bcl, buf); - if (unlikely(res == -ELINKCONG)) - buf_discard(buf); - else + if (likely(res > 0)) bclink_set_last_sent(); bcl->stats.queue_sz_counts++; diff --git a/net/tipc/link.c b/net/tipc/link.c index 02b083e5c219..2a9f44a203eb 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -864,8 +864,9 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf) if (unlikely(queue_size >= queue_limit)) { if (imp <= TIPC_CRITICAL_IMPORTANCE) { - return link_schedule_port(l_ptr, msg_origport(msg), - size); + link_schedule_port(l_ptr, msg_origport(msg), size); + buf_discard(buf); + return -ELINKCONG; } buf_discard(buf); if (imp > CONN_MANAGER) { @@ -1069,8 +1070,6 @@ again: if (likely(buf)) { res = link_send_buf_fast(l_ptr, buf, &sender->max_pkt); - if (unlikely(res < 0)) - buf_discard(buf); exit: tipc_node_unlock(node); read_unlock_bh(&tipc_net_lock); -- cgit v1.2.3 From 2689690469c9fd76f9db0afcdf2523f48cce4006 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Thu, 21 Apr 2011 10:42:07 -0500 Subject: tipc: Avoid recomputation of outgoing message length Rework TIPC's message sending routines to take advantage of the total amount of data value passed to it by the kernel socket infrastructure. This change eliminates the need for TIPC to compute the size of outgoing messages itself, as well as the check for an oversize message in tipc_msg_build(). In addition, this change warrants an explanation: - res = send_packet(NULL, sock, &my_msg, 0); + res = send_packet(NULL, sock, &my_msg, bytes_to_send); Previously, the final argument to send_packet() was ignored (since the amount of data being sent was recalculated by a lower-level routine) and we could just pass in a dummy value (0). Now that the recalculation is being eliminated, the argument value being passed to send_packet() is significant and we have to supply the actual amount of data we want to send. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker --- net/tipc/link.c | 18 +++++++++++------- net/tipc/link.h | 1 + net/tipc/msg.c | 25 +++---------------------- net/tipc/msg.h | 5 ++--- net/tipc/port.c | 49 +++++++++++++++++++++++++++---------------------- net/tipc/port.h | 14 +++++++++----- net/tipc/socket.c | 14 +++++++++----- net/tipc/subscr.c | 4 ++-- 8 files changed, 64 insertions(+), 66 deletions(-) (limited to 'net/tipc/link.c') diff --git a/net/tipc/link.c b/net/tipc/link.c index 2a9f44a203eb..4bab139d5e74 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -92,7 +92,8 @@ static int link_recv_changeover_msg(struct link **l_ptr, struct sk_buff **buf); static void link_set_supervision_props(struct link *l_ptr, u32 tolerance); static int link_send_sections_long(struct tipc_port *sender, struct iovec const *msg_sect, - u32 num_sect, u32 destnode); + u32 num_sect, unsigned int total_len, + u32 destnode); static void link_check_defragm_bufs(struct link *l_ptr); static void link_state_event(struct link *l_ptr, u32 event); static void link_reset_statistics(struct link *l_ptr); @@ -1043,6 +1044,7 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode) int tipc_link_send_sections_fast(struct tipc_port *sender, struct iovec const *msg_sect, const u32 num_sect, + unsigned int total_len, u32 destaddr) { struct tipc_msg *hdr = &sender->phdr; @@ -1058,8 +1060,8 @@ again: * (Must not hold any locks while building message.) */ - res = tipc_msg_build(hdr, msg_sect, num_sect, sender->max_pkt, - !sender->user_port, &buf); + res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, + sender->max_pkt, !sender->user_port, &buf); read_lock_bh(&tipc_net_lock); node = tipc_node_find(destaddr); @@ -1104,7 +1106,8 @@ exit: goto again; return link_send_sections_long(sender, msg_sect, - num_sect, destaddr); + num_sect, total_len, + destaddr); } tipc_node_unlock(node); } @@ -1116,7 +1119,7 @@ exit: return tipc_reject_msg(buf, TIPC_ERR_NO_NODE); if (res >= 0) return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect, - TIPC_ERR_NO_NODE); + total_len, TIPC_ERR_NO_NODE); return res; } @@ -1137,12 +1140,13 @@ exit: static int link_send_sections_long(struct tipc_port *sender, struct iovec const *msg_sect, u32 num_sect, + unsigned int total_len, u32 destaddr) { struct link *l_ptr; struct tipc_node *node; struct tipc_msg *hdr = &sender->phdr; - u32 dsz = msg_data_sz(hdr); + u32 dsz = total_len; u32 max_pkt, fragm_sz, rest; struct tipc_msg fragm_hdr; struct sk_buff *buf, *buf_chain, *prev; @@ -1269,7 +1273,7 @@ reject: buf_discard(buf_chain); } return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect, - TIPC_ERR_NO_NODE); + total_len, TIPC_ERR_NO_NODE); } /* Append whole chain to send queue: */ diff --git a/net/tipc/link.h b/net/tipc/link.h index e6a30dbe1aaa..74fbecab1ea0 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -228,6 +228,7 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector); int tipc_link_send_sections_fast(struct tipc_port *sender, struct iovec const *msg_sect, const u32 num_sect, + unsigned int total_len, u32 destnode); void tipc_link_recv_bundle(struct sk_buff *buf); int tipc_link_recv_fragment(struct sk_buff **pending, diff --git a/net/tipc/msg.c b/net/tipc/msg.c index 6d92d17e7fb5..03e57bf92c73 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c @@ -67,20 +67,6 @@ void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, } } -/** - * tipc_msg_calc_data_size - determine total data size for message - */ - -int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect) -{ - int dsz = 0; - int i; - - for (i = 0; i < num_sect; i++) - dsz += msg_sect[i].iov_len; - return dsz; -} - /** * tipc_msg_build - create message using specified header and data * @@ -89,18 +75,13 @@ int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect) * Returns message data size or errno */ -int tipc_msg_build(struct tipc_msg *hdr, - struct iovec const *msg_sect, u32 num_sect, +int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect, + u32 num_sect, unsigned int total_len, int max_size, int usrmem, struct sk_buff **buf) { int dsz, sz, hsz, pos, res, cnt; - dsz = tipc_msg_calc_data_size(msg_sect, num_sect); - if (unlikely(dsz > TIPC_MAX_USER_MSG_SIZE)) { - *buf = NULL; - return -EINVAL; - } - + dsz = total_len; pos = hsz = msg_hdr_sz(hdr); sz = hsz + dsz; msg_set_size(hdr, sz); diff --git a/net/tipc/msg.h b/net/tipc/msg.h index 005b318fd328..8452454731fa 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h @@ -750,9 +750,8 @@ static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n) u32 tipc_msg_tot_importance(struct tipc_msg *m); void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize, u32 destnode); -int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect); -int tipc_msg_build(struct tipc_msg *hdr, - struct iovec const *msg_sect, u32 num_sect, +int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect, + u32 num_sect, unsigned int total_len, int max_size, int usrmem, struct sk_buff **buf); static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a) diff --git a/net/tipc/port.c b/net/tipc/port.c index 9f2ff12cf436..c68dc956a423 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -74,7 +74,8 @@ static u32 port_peerport(struct tipc_port *p_ptr) */ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, - u32 num_sect, struct iovec const *msg_sect) + u32 num_sect, struct iovec const *msg_sect, + unsigned int total_len) { struct tipc_msg *hdr; struct sk_buff *buf; @@ -98,7 +99,7 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, msg_set_namelower(hdr, seq->lower); msg_set_nameupper(hdr, seq->upper); msg_set_hdr_sz(hdr, MCAST_H_SIZE); - res = tipc_msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE, + res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE, !oport->user_port, &buf); if (unlikely(!buf)) return res; @@ -418,12 +419,12 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err) int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr, struct iovec const *msg_sect, u32 num_sect, - int err) + unsigned int total_len, int err) { struct sk_buff *buf; int res; - res = tipc_msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE, + res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE, !p_ptr->user_port, &buf); if (!buf) return res; @@ -1163,12 +1164,13 @@ int tipc_shutdown(u32 ref) */ static int tipc_port_recv_sections(struct tipc_port *sender, unsigned int num_sect, - struct iovec const *msg_sect) + struct iovec const *msg_sect, + unsigned int total_len) { struct sk_buff *buf; int res; - res = tipc_msg_build(&sender->phdr, msg_sect, num_sect, + res = tipc_msg_build(&sender->phdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE, !sender->user_port, &buf); if (likely(buf)) tipc_port_recv_msg(buf); @@ -1179,7 +1181,8 @@ static int tipc_port_recv_sections(struct tipc_port *sender, unsigned int num_se * tipc_send - send message sections on connection */ -int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect) +int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect, + unsigned int total_len) { struct tipc_port *p_ptr; u32 destnode; @@ -1194,9 +1197,10 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect) destnode = port_peernode(p_ptr); if (likely(destnode != tipc_own_addr)) res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, - destnode); + total_len, destnode); else - res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect); + res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect, + total_len); if (likely(res != -ELINKCONG)) { p_ptr->congested = 0; @@ -1207,8 +1211,7 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect) } if (port_unreliable(p_ptr)) { p_ptr->congested = 0; - /* Just calculate msg length and return */ - return tipc_msg_calc_data_size(msg_sect, num_sect); + return total_len; } return -ELINKCONG; } @@ -1218,7 +1221,8 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect) */ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain, - unsigned int num_sect, struct iovec const *msg_sect) + unsigned int num_sect, struct iovec const *msg_sect, + unsigned int total_len) { struct tipc_port *p_ptr; struct tipc_msg *msg; @@ -1245,23 +1249,23 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain, if (likely(destport)) { if (likely(destnode == tipc_own_addr)) res = tipc_port_recv_sections(p_ptr, num_sect, - msg_sect); + msg_sect, total_len); else res = tipc_link_send_sections_fast(p_ptr, msg_sect, - num_sect, destnode); + num_sect, total_len, + destnode); if (likely(res != -ELINKCONG)) { if (res > 0) p_ptr->sent++; return res; } if (port_unreliable(p_ptr)) { - /* Just calculate msg length and return */ - return tipc_msg_calc_data_size(msg_sect, num_sect); + return total_len; } return -ELINKCONG; } return tipc_port_reject_sections(p_ptr, msg, msg_sect, num_sect, - TIPC_ERR_NO_NAME); + total_len, TIPC_ERR_NO_NAME); } /** @@ -1269,7 +1273,8 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain, */ int tipc_send2port(u32 ref, struct tipc_portid const *dest, - unsigned int num_sect, struct iovec const *msg_sect) + unsigned int num_sect, struct iovec const *msg_sect, + unsigned int total_len) { struct tipc_port *p_ptr; struct tipc_msg *msg; @@ -1289,18 +1294,18 @@ int tipc_send2port(u32 ref, struct tipc_portid const *dest, msg_set_hdr_sz(msg, DIR_MSG_H_SIZE); if (dest->node == tipc_own_addr) - res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect); + res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect, + total_len); else res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, - dest->node); + total_len, dest->node); if (likely(res != -ELINKCONG)) { if (res > 0) p_ptr->sent++; return res; } if (port_unreliable(p_ptr)) { - /* Just calculate msg length and return */ - return tipc_msg_calc_data_size(msg_sect, num_sect); + return total_len; } return -ELINKCONG; } diff --git a/net/tipc/port.h b/net/tipc/port.h index 87b9424ae0ec..b9aa34195aec 100644 --- a/net/tipc/port.h +++ b/net/tipc/port.h @@ -205,23 +205,27 @@ int tipc_disconnect_port(struct tipc_port *tp_ptr); /* * TIPC messaging routines */ -int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect); +int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect, + unsigned int total_len); int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain, - unsigned int num_sect, struct iovec const *msg_sect); + unsigned int num_sect, struct iovec const *msg_sect, + unsigned int total_len); int tipc_send2port(u32 portref, struct tipc_portid const *dest, - unsigned int num_sect, struct iovec const *msg_sect); + unsigned int num_sect, struct iovec const *msg_sect, + unsigned int total_len); int tipc_send_buf2port(u32 portref, struct tipc_portid const *dest, struct sk_buff *buf, unsigned int dsz); int tipc_multicast(u32 portref, struct tipc_name_seq const *seq, - unsigned int section_count, struct iovec const *msg); + unsigned int section_count, struct iovec const *msg, + unsigned int total_len); int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr, struct iovec const *msg_sect, u32 num_sect, - int err); + unsigned int total_len, int err); struct sk_buff *tipc_port_get_ports(void); void tipc_port_recv_proto_msg(struct sk_buff *buf); void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp); diff --git a/net/tipc/socket.c b/net/tipc/socket.c index e1c791798ba1..338837396642 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -576,12 +576,14 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, &dest->addr.name.name, dest->addr.name.domain, m->msg_iovlen, - m->msg_iov); + m->msg_iov, + total_len); } else if (dest->addrtype == TIPC_ADDR_ID) { res = tipc_send2port(tport->ref, &dest->addr.id, m->msg_iovlen, - m->msg_iov); + m->msg_iov, + total_len); } else if (dest->addrtype == TIPC_ADDR_MCAST) { if (needs_conn) { res = -EOPNOTSUPP; @@ -593,7 +595,8 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, res = tipc_multicast(tport->ref, &dest->addr.nameseq, m->msg_iovlen, - m->msg_iov); + m->msg_iov, + total_len); } if (likely(res != -ELINKCONG)) { if (needs_conn && (res >= 0)) @@ -659,7 +662,8 @@ static int send_packet(struct kiocb *iocb, struct socket *sock, break; } - res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov); + res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov, + total_len); if (likely(res != -ELINKCONG)) break; if (m->msg_flags & MSG_DONTWAIT) { @@ -766,7 +770,7 @@ static int send_stream(struct kiocb *iocb, struct socket *sock, bytes_to_send = curr_left; my_iov.iov_base = curr_start; my_iov.iov_len = bytes_to_send; - res = send_packet(NULL, sock, &my_msg, 0); + res = send_packet(NULL, sock, &my_msg, bytes_to_send); if (res < 0) { if (bytes_sent) res = bytes_sent; diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index aae9eae13404..6cf726863485 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c @@ -109,7 +109,7 @@ static void subscr_send_event(struct subscription *sub, sub->evt.found_upper = htohl(found_upper, sub->swap); sub->evt.port.ref = htohl(port_ref, sub->swap); sub->evt.port.node = htohl(node, sub->swap); - tipc_send(sub->server_ref, 1, &msg_sect); + tipc_send(sub->server_ref, 1, &msg_sect, msg_sect.iov_len); } /** @@ -521,7 +521,7 @@ static void subscr_named_msg_event(void *usr_handle, /* Send an ACK- to complete connection handshaking */ - tipc_send(server_port_ref, 0, NULL); + tipc_send(server_port_ref, 0, NULL, 0); /* Handle optional subscription request */ -- cgit v1.2.3 From dc63d91eb1cf74233c68b0058dcd477f5d019d02 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Thu, 21 Apr 2011 11:50:42 -0400 Subject: tipc: Introduce routine to enqueue a chain of messages on link tx queue Create a helper routine to enqueue a chain of sk_buffs to a link's transmit queue. It improves readability and the new function is anticipated to be used more than just once in the future as well. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker --- net/tipc/link.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) (limited to 'net/tipc/link.c') diff --git a/net/tipc/link.c b/net/tipc/link.c index 4bab139d5e74..5ed4b4f7452d 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -843,6 +843,25 @@ static void link_add_to_outqueue(struct link *l_ptr, l_ptr->stats.max_queue_sz = l_ptr->out_queue_size; } +static void link_add_chain_to_outqueue(struct link *l_ptr, + struct sk_buff *buf_chain, + u32 long_msgno) +{ + struct sk_buff *buf; + struct tipc_msg *msg; + + if (!l_ptr->next_out) + l_ptr->next_out = buf_chain; + while (buf_chain) { + buf = buf_chain; + buf_chain = buf_chain->next; + + msg = buf_msg(buf); + msg_set_long_msgno(msg, long_msgno); + link_add_to_outqueue(l_ptr, buf, msg); + } +} + /* * tipc_link_send_buf() is the 'full path' for messages, called from * inside TIPC when the 'fast path' in tipc_send_buf @@ -1276,25 +1295,12 @@ reject: total_len, TIPC_ERR_NO_NODE); } - /* Append whole chain to send queue: */ + /* Append chain of fragments to send queue & send them */ - buf = buf_chain; l_ptr->long_msg_seq_no++; - if (!l_ptr->next_out) - l_ptr->next_out = buf_chain; + link_add_chain_to_outqueue(l_ptr, buf_chain, l_ptr->long_msg_seq_no); + l_ptr->stats.sent_fragments += fragm_no; l_ptr->stats.sent_fragmented++; - while (buf) { - struct sk_buff *next = buf->next; - struct tipc_msg *msg = buf_msg(buf); - - l_ptr->stats.sent_fragments++; - msg_set_long_msgno(msg, l_ptr->long_msg_seq_no); - link_add_to_outqueue(l_ptr, buf, msg); - buf = next; - } - - /* Send it, if possible: */ - tipc_link_push_queue(l_ptr); tipc_node_unlock(node); return dsz; -- cgit v1.2.3