Skip to content

Commit 4ccfe5e

Browse files
Jon Paul Maloydavem330
authored andcommitted
tipc: connection oriented transport uses new send functions
We move the message sending across established connections to use the message preparation and send functions introduced earlier in this series. We now do the message preparation and call to the link send function directly from the socket, instead of going via the port layer. As a consequence of this change, the functions tipc_send(), tipc_port_iovec_rcv(), tipc_port_iovec_reject() and tipc_reject_msg() become unreferenced and can be eliminated from port.c. For the same reason, the functions tipc_link_xmit_fast(), tipc_link_iovec_xmit_long() and tipc_link_iovec_fast() can be eliminated from link.c. Signed-off-by: Jon Maloy <[email protected]> Reviewed-by: Erik Hugne <[email protected]> Reviewed-by: Ying Xue <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent e2dafe8 commit 4ccfe5e

File tree

4 files changed

+70
-513
lines changed

4 files changed

+70
-513
lines changed

net/tipc/link.c

Lines changed: 0 additions & 249 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,6 @@ static void tipc_link_proto_rcv(struct tipc_link *l_ptr, struct sk_buff *buf);
8282
static int tipc_link_tunnel_rcv(struct tipc_node *n_ptr,
8383
struct sk_buff **buf);
8484
static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tolerance);
85-
static int tipc_link_iovec_long_xmit(struct tipc_port *sender,
86-
struct iovec const *msg_sect,
87-
unsigned int len, u32 destnode);
8885
static void link_state_event(struct tipc_link *l_ptr, u32 event);
8986
static void link_reset_statistics(struct tipc_link *l_ptr);
9087
static void link_print(struct tipc_link *l_ptr, const char *str);
@@ -1070,252 +1067,6 @@ void tipc_link_names_xmit(struct list_head *message_list, u32 dest)
10701067
}
10711068
}
10721069

1073-
/*
1074-
* tipc_link_xmit_fast: Entry for data messages where the
1075-
* destination link is known and the header is complete,
1076-
* inclusive total message length. Very time critical.
1077-
* Link is locked. Returns user data length.
1078-
*/
1079-
static int tipc_link_xmit_fast(struct tipc_link *l_ptr, struct sk_buff *buf,
1080-
u32 *used_max_pkt)
1081-
{
1082-
struct tipc_msg *msg = buf_msg(buf);
1083-
int res = msg_data_sz(msg);
1084-
1085-
if (likely(!link_congested(l_ptr))) {
1086-
if (likely(msg_size(msg) <= l_ptr->max_pkt)) {
1087-
link_add_to_outqueue(l_ptr, buf, msg);
1088-
tipc_bearer_send(l_ptr->bearer_id, buf,
1089-
&l_ptr->media_addr);
1090-
l_ptr->unacked_window = 0;
1091-
return res;
1092-
}
1093-
else
1094-
*used_max_pkt = l_ptr->max_pkt;
1095-
}
1096-
return __tipc_link_xmit(l_ptr, buf); /* All other cases */
1097-
}
1098-
1099-
/*
1100-
* tipc_link_iovec_xmit_fast: Entry for messages where the
1101-
* destination processor is known and the header is complete,
1102-
* except for total message length.
1103-
* Returns user data length or errno.
1104-
*/
1105-
int tipc_link_iovec_xmit_fast(struct tipc_port *sender,
1106-
struct iovec const *msg_sect,
1107-
unsigned int len, u32 destaddr)
1108-
{
1109-
struct tipc_msg *hdr = &sender->phdr;
1110-
struct tipc_link *l_ptr;
1111-
struct sk_buff *buf;
1112-
struct tipc_node *node;
1113-
int res;
1114-
u32 selector = msg_origport(hdr) & 1;
1115-
1116-
again:
1117-
/*
1118-
* Try building message using port's max_pkt hint.
1119-
* (Must not hold any locks while building message.)
1120-
*/
1121-
res = tipc_msg_build(hdr, msg_sect, len, sender->max_pkt, &buf);
1122-
/* Exit if build request was invalid */
1123-
if (unlikely(res < 0))
1124-
return res;
1125-
1126-
node = tipc_node_find(destaddr);
1127-
if (likely(node)) {
1128-
tipc_node_lock(node);
1129-
l_ptr = node->active_links[selector];
1130-
if (likely(l_ptr)) {
1131-
if (likely(buf)) {
1132-
res = tipc_link_xmit_fast(l_ptr, buf,
1133-
&sender->max_pkt);
1134-
exit:
1135-
tipc_node_unlock(node);
1136-
return res;
1137-
}
1138-
1139-
/* Exit if link (or bearer) is congested */
1140-
if (link_congested(l_ptr)) {
1141-
res = link_schedule_port(l_ptr,
1142-
sender->ref, res);
1143-
goto exit;
1144-
}
1145-
1146-
/*
1147-
* Message size exceeds max_pkt hint; update hint,
1148-
* then re-try fast path or fragment the message
1149-
*/
1150-
sender->max_pkt = l_ptr->max_pkt;
1151-
tipc_node_unlock(node);
1152-
1153-
1154-
if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt)
1155-
goto again;
1156-
1157-
return tipc_link_iovec_long_xmit(sender, msg_sect,
1158-
len, destaddr);
1159-
}
1160-
tipc_node_unlock(node);
1161-
}
1162-
1163-
/* Couldn't find a link to the destination node */
1164-
kfree_skb(buf);
1165-
tipc_port_iovec_reject(sender, hdr, msg_sect, len, TIPC_ERR_NO_NODE);
1166-
return -ENETUNREACH;
1167-
}
1168-
1169-
/*
1170-
* tipc_link_iovec_long_xmit(): Entry for long messages where the
1171-
* destination node is known and the header is complete,
1172-
* inclusive total message length.
1173-
* Link and bearer congestion status have been checked to be ok,
1174-
* and are ignored if they change.
1175-
*
1176-
* Note that fragments do not use the full link MTU so that they won't have
1177-
* to undergo refragmentation if link changeover causes them to be sent
1178-
* over another link with an additional tunnel header added as prefix.
1179-
* (Refragmentation will still occur if the other link has a smaller MTU.)
1180-
*
1181-
* Returns user data length or errno.
1182-
*/
1183-
static int tipc_link_iovec_long_xmit(struct tipc_port *sender,
1184-
struct iovec const *msg_sect,
1185-
unsigned int len, u32 destaddr)
1186-
{
1187-
struct tipc_link *l_ptr;
1188-
struct tipc_node *node;
1189-
struct tipc_msg *hdr = &sender->phdr;
1190-
u32 dsz = len;
1191-
u32 max_pkt, fragm_sz, rest;
1192-
struct tipc_msg fragm_hdr;
1193-
struct sk_buff *buf, *buf_chain, *prev;
1194-
u32 fragm_crs, fragm_rest, hsz, sect_rest;
1195-
const unchar __user *sect_crs;
1196-
int curr_sect;
1197-
u32 fragm_no;
1198-
int res = 0;
1199-
1200-
again:
1201-
fragm_no = 1;
1202-
max_pkt = sender->max_pkt - INT_H_SIZE;
1203-
/* leave room for tunnel header in case of link changeover */
1204-
fragm_sz = max_pkt - INT_H_SIZE;
1205-
/* leave room for fragmentation header in each fragment */
1206-
rest = dsz;
1207-
fragm_crs = 0;
1208-
fragm_rest = 0;
1209-
sect_rest = 0;
1210-
sect_crs = NULL;
1211-
curr_sect = -1;
1212-
1213-
/* Prepare reusable fragment header */
1214-
tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
1215-
INT_H_SIZE, msg_destnode(hdr));
1216-
msg_set_size(&fragm_hdr, max_pkt);
1217-
msg_set_fragm_no(&fragm_hdr, 1);
1218-
1219-
/* Prepare header of first fragment */
1220-
buf_chain = buf = tipc_buf_acquire(max_pkt);
1221-
if (!buf)
1222-
return -ENOMEM;
1223-
buf->next = NULL;
1224-
skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE);
1225-
hsz = msg_hdr_sz(hdr);
1226-
skb_copy_to_linear_data_offset(buf, INT_H_SIZE, hdr, hsz);
1227-
1228-
/* Chop up message */
1229-
fragm_crs = INT_H_SIZE + hsz;
1230-
fragm_rest = fragm_sz - hsz;
1231-
1232-
do { /* For all sections */
1233-
u32 sz;
1234-
1235-
if (!sect_rest) {
1236-
sect_rest = msg_sect[++curr_sect].iov_len;
1237-
sect_crs = msg_sect[curr_sect].iov_base;
1238-
}
1239-
1240-
if (sect_rest < fragm_rest)
1241-
sz = sect_rest;
1242-
else
1243-
sz = fragm_rest;
1244-
1245-
if (copy_from_user(buf->data + fragm_crs, sect_crs, sz)) {
1246-
res = -EFAULT;
1247-
error:
1248-
kfree_skb_list(buf_chain);
1249-
return res;
1250-
}
1251-
sect_crs += sz;
1252-
sect_rest -= sz;
1253-
fragm_crs += sz;
1254-
fragm_rest -= sz;
1255-
rest -= sz;
1256-
1257-
if (!fragm_rest && rest) {
1258-
1259-
/* Initiate new fragment: */
1260-
if (rest <= fragm_sz) {
1261-
fragm_sz = rest;
1262-
msg_set_type(&fragm_hdr, LAST_FRAGMENT);
1263-
} else {
1264-
msg_set_type(&fragm_hdr, FRAGMENT);
1265-
}
1266-
msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE);
1267-
msg_set_fragm_no(&fragm_hdr, ++fragm_no);
1268-
prev = buf;
1269-
buf = tipc_buf_acquire(fragm_sz + INT_H_SIZE);
1270-
if (!buf) {
1271-
res = -ENOMEM;
1272-
goto error;
1273-
}
1274-
1275-
buf->next = NULL;
1276-
prev->next = buf;
1277-
skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE);
1278-
fragm_crs = INT_H_SIZE;
1279-
fragm_rest = fragm_sz;
1280-
}
1281-
} while (rest > 0);
1282-
1283-
/*
1284-
* Now we have a buffer chain. Select a link and check
1285-
* that packet size is still OK
1286-
*/
1287-
node = tipc_node_find(destaddr);
1288-
if (likely(node)) {
1289-
tipc_node_lock(node);
1290-
l_ptr = node->active_links[sender->ref & 1];
1291-
if (!l_ptr) {
1292-
tipc_node_unlock(node);
1293-
goto reject;
1294-
}
1295-
if (l_ptr->max_pkt < max_pkt) {
1296-
sender->max_pkt = l_ptr->max_pkt;
1297-
tipc_node_unlock(node);
1298-
kfree_skb_list(buf_chain);
1299-
goto again;
1300-
}
1301-
} else {
1302-
reject:
1303-
kfree_skb_list(buf_chain);
1304-
tipc_port_iovec_reject(sender, hdr, msg_sect, len,
1305-
TIPC_ERR_NO_NODE);
1306-
return -ENETUNREACH;
1307-
}
1308-
1309-
/* Append chain of fragments to send queue & send them */
1310-
l_ptr->long_msg_seq_no++;
1311-
link_add_chain_to_outqueue(l_ptr, buf_chain, l_ptr->long_msg_seq_no);
1312-
l_ptr->stats.sent_fragments += fragm_no;
1313-
l_ptr->stats.sent_fragmented++;
1314-
tipc_link_push_queue(l_ptr);
1315-
tipc_node_unlock(node);
1316-
return dsz;
1317-
}
1318-
13191070
/*
13201071
* tipc_link_push_packet: Push one unsent packet to the media
13211072
*/

0 commit comments

Comments
 (0)