Skip to content

Commit 8b7f8a9

Browse files
committed
Merge branch 'tipc-next'
Ying Xue says: ==================== standardize TIPC SKB queue operations Now the following SKB queues are created and maintained within internal TIPC stack: - link transmission queue - link deferred queue - link receive queue - socket outgoing packet chain - name table outgoing packet chain In order to manage above queues, TIPC stack declares a sk_buff pointer for each queue to record its head, and directly modifies "prev" and "next" SKB pointers of SKB structure when inserting or deleting a SKB to or from the queue. As these operations are pretty complex, they easily involve fatal mistakes. If these sk_buff pointers are replaced with sk_buff_head instances as queue heads and corresponding generic SKB list APIs are used to manage them, the entire TIPC code would become quite clean and readable. But before make the change, we need to clean up below redundant functionalities: - remove node subscribe infrastructure - remove protocol message queue - remove retransmission queue - clean up process of pushing packets in link layer ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 73cf0e9 + a6ca109 commit 8b7f8a9

File tree

18 files changed

+496
-740
lines changed

18 files changed

+496
-740
lines changed

net/tipc/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ obj-$(CONFIG_TIPC) := tipc.o
77
tipc-y += addr.o bcast.o bearer.o config.o \
88
core.o link.o discover.o msg.o \
99
name_distr.o subscr.o name_table.o net.o \
10-
netlink.o node.o node_subscr.o \
11-
socket.o log.o eth_media.o server.o
10+
netlink.o node.o socket.o log.o eth_media.o \
11+
server.o
1212

1313
tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o
1414
tipc-$(CONFIG_SYSCTL) += sysctl.o

net/tipc/bcast.c

Lines changed: 48 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -217,12 +217,13 @@ struct tipc_node *tipc_bclink_retransmit_to(void)
217217
*/
218218
static void bclink_retransmit_pkt(u32 after, u32 to)
219219
{
220-
struct sk_buff *buf;
220+
struct sk_buff *skb;
221221

222-
buf = bcl->first_out;
223-
while (buf && less_eq(buf_seqno(buf), after))
224-
buf = buf->next;
225-
tipc_link_retransmit(bcl, buf, mod(to - after));
222+
skb_queue_walk(&bcl->outqueue, skb) {
223+
if (more(buf_seqno(skb), after))
224+
break;
225+
}
226+
tipc_link_retransmit(bcl, skb, mod(to - after));
226227
}
227228

228229
/**
@@ -245,14 +246,14 @@ void tipc_bclink_wakeup_users(void)
245246
*/
246247
void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
247248
{
248-
struct sk_buff *crs;
249+
struct sk_buff *skb, *tmp;
249250
struct sk_buff *next;
250251
unsigned int released = 0;
251252

252253
tipc_bclink_lock();
253254
/* Bail out if tx queue is empty (no clean up is required) */
254-
crs = bcl->first_out;
255-
if (!crs)
255+
skb = skb_peek(&bcl->outqueue);
256+
if (!skb)
256257
goto exit;
257258

258259
/* Determine which messages need to be acknowledged */
@@ -271,43 +272,43 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
271272
* Bail out if specified sequence number does not correspond
272273
* to a message that has been sent and not yet acknowledged
273274
*/
274-
if (less(acked, buf_seqno(crs)) ||
275+
if (less(acked, buf_seqno(skb)) ||
275276
less(bcl->fsm_msg_cnt, acked) ||
276277
less_eq(acked, n_ptr->bclink.acked))
277278
goto exit;
278279
}
279280

280281
/* Skip over packets that node has previously acknowledged */
281-
while (crs && less_eq(buf_seqno(crs), n_ptr->bclink.acked))
282-
crs = crs->next;
282+
skb_queue_walk(&bcl->outqueue, skb) {
283+
if (more(buf_seqno(skb), n_ptr->bclink.acked))
284+
break;
285+
}
283286

284287
/* Update packets that node is now acknowledging */
288+
skb_queue_walk_from_safe(&bcl->outqueue, skb, tmp) {
289+
if (more(buf_seqno(skb), acked))
290+
break;
285291

286-
while (crs && less_eq(buf_seqno(crs), acked)) {
287-
next = crs->next;
288-
289-
if (crs != bcl->next_out)
290-
bcbuf_decr_acks(crs);
291-
else {
292-
bcbuf_set_acks(crs, 0);
292+
next = tipc_skb_queue_next(&bcl->outqueue, skb);
293+
if (skb != bcl->next_out) {
294+
bcbuf_decr_acks(skb);
295+
} else {
296+
bcbuf_set_acks(skb, 0);
293297
bcl->next_out = next;
294298
bclink_set_last_sent();
295299
}
296300

297-
if (bcbuf_acks(crs) == 0) {
298-
bcl->first_out = next;
299-
bcl->out_queue_size--;
300-
kfree_skb(crs);
301+
if (bcbuf_acks(skb) == 0) {
302+
__skb_unlink(skb, &bcl->outqueue);
303+
kfree_skb(skb);
301304
released = 1;
302305
}
303-
crs = next;
304306
}
305307
n_ptr->bclink.acked = acked;
306308

307309
/* Try resolving broadcast link congestion, if necessary */
308-
309310
if (unlikely(bcl->next_out)) {
310-
tipc_link_push_queue(bcl);
311+
tipc_link_push_packets(bcl);
311312
bclink_set_last_sent();
312313
}
313314
if (unlikely(released && !skb_queue_empty(&bcl->waiting_sks)))
@@ -327,45 +328,40 @@ void tipc_bclink_update_link_state(struct tipc_node *n_ptr, u32 last_sent)
327328
struct sk_buff *buf;
328329

329330
/* Ignore "stale" link state info */
330-
331331
if (less_eq(last_sent, n_ptr->bclink.last_in))
332332
return;
333333

334334
/* Update link synchronization state; quit if in sync */
335-
336335
bclink_update_last_sent(n_ptr, last_sent);
337336

338337
if (n_ptr->bclink.last_sent == n_ptr->bclink.last_in)
339338
return;
340339

341340
/* Update out-of-sync state; quit if loss is still unconfirmed */
342-
343341
if ((++n_ptr->bclink.oos_state) == 1) {
344342
if (n_ptr->bclink.deferred_size < (TIPC_MIN_LINK_WIN / 2))
345343
return;
346344
n_ptr->bclink.oos_state++;
347345
}
348346

349347
/* Don't NACK if one has been recently sent (or seen) */
350-
351348
if (n_ptr->bclink.oos_state & 0x1)
352349
return;
353350

354351
/* Send NACK */
355-
356352
buf = tipc_buf_acquire(INT_H_SIZE);
357353
if (buf) {
358354
struct tipc_msg *msg = buf_msg(buf);
355+
struct sk_buff *skb = skb_peek(&n_ptr->bclink.deferred_queue);
356+
u32 to = skb ? buf_seqno(skb) - 1 : n_ptr->bclink.last_sent;
359357

360358
tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG,
361359
INT_H_SIZE, n_ptr->addr);
362360
msg_set_non_seq(msg, 1);
363361
msg_set_mc_netid(msg, tipc_net_id);
364362
msg_set_bcast_ack(msg, n_ptr->bclink.last_in);
365363
msg_set_bcgap_after(msg, n_ptr->bclink.last_in);
366-
msg_set_bcgap_to(msg, n_ptr->bclink.deferred_head
367-
? buf_seqno(n_ptr->bclink.deferred_head) - 1
368-
: n_ptr->bclink.last_sent);
364+
msg_set_bcgap_to(msg, to);
369365

370366
tipc_bclink_lock();
371367
tipc_bearer_send(MAX_BEARERS, buf, NULL);
@@ -402,46 +398,48 @@ static void bclink_peek_nack(struct tipc_msg *msg)
402398

403399
/* tipc_bclink_xmit - broadcast buffer chain to all nodes in cluster
404400
* and to identified node local sockets
405-
* @buf: chain of buffers containing message
401+
* @list: chain of buffers containing message
406402
* Consumes the buffer chain, except when returning -ELINKCONG
407403
* Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE
408404
*/
409-
int tipc_bclink_xmit(struct sk_buff *buf)
405+
int tipc_bclink_xmit(struct sk_buff_head *list)
410406
{
411407
int rc = 0;
412408
int bc = 0;
413-
struct sk_buff *clbuf;
409+
struct sk_buff *skb;
414410

415411
/* Prepare clone of message for local node */
416-
clbuf = tipc_msg_reassemble(buf);
417-
if (unlikely(!clbuf)) {
418-
kfree_skb_list(buf);
412+
skb = tipc_msg_reassemble(list);
413+
if (unlikely(!skb)) {
414+
__skb_queue_purge(list);
419415
return -EHOSTUNREACH;
420416
}
421417

422418
/* Broadcast to all other nodes */
423419
if (likely(bclink)) {
424420
tipc_bclink_lock();
425421
if (likely(bclink->bcast_nodes.count)) {
426-
rc = __tipc_link_xmit(bcl, buf);
422+
rc = __tipc_link_xmit(bcl, list);
427423
if (likely(!rc)) {
424+
u32 len = skb_queue_len(&bcl->outqueue);
425+
428426
bclink_set_last_sent();
429427
bcl->stats.queue_sz_counts++;
430-
bcl->stats.accu_queue_sz += bcl->out_queue_size;
428+
bcl->stats.accu_queue_sz += len;
431429
}
432430
bc = 1;
433431
}
434432
tipc_bclink_unlock();
435433
}
436434

437435
if (unlikely(!bc))
438-
kfree_skb_list(buf);
436+
__skb_queue_purge(list);
439437

440438
/* Deliver message clone */
441439
if (likely(!rc))
442-
tipc_sk_mcast_rcv(clbuf);
440+
tipc_sk_mcast_rcv(skb);
443441
else
444-
kfree_skb(clbuf);
442+
kfree_skb(skb);
445443

446444
return rc;
447445
}
@@ -462,7 +460,6 @@ static void bclink_accept_pkt(struct tipc_node *node, u32 seqno)
462460
* Unicast an ACK periodically, ensuring that
463461
* all nodes in the cluster don't ACK at the same time
464462
*/
465-
466463
if (((seqno - tipc_own_addr) % TIPC_MIN_LINK_WIN) == 0) {
467464
tipc_link_proto_xmit(node->active_links[node->addr & 1],
468465
STATE_MSG, 0, 0, 0, 0, 0);
@@ -484,7 +481,6 @@ void tipc_bclink_rcv(struct sk_buff *buf)
484481
int deferred = 0;
485482

486483
/* Screen out unwanted broadcast messages */
487-
488484
if (msg_mc_netid(msg) != tipc_net_id)
489485
goto exit;
490486

@@ -497,7 +493,6 @@ void tipc_bclink_rcv(struct sk_buff *buf)
497493
goto unlock;
498494

499495
/* Handle broadcast protocol message */
500-
501496
if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) {
502497
if (msg_type(msg) != STATE_MSG)
503498
goto unlock;
@@ -518,14 +513,12 @@ void tipc_bclink_rcv(struct sk_buff *buf)
518513
}
519514

520515
/* Handle in-sequence broadcast message */
521-
522516
seqno = msg_seqno(msg);
523517
next_in = mod(node->bclink.last_in + 1);
524518

525519
if (likely(seqno == next_in)) {
526520
receive:
527521
/* Deliver message to destination */
528-
529522
if (likely(msg_isdata(msg))) {
530523
tipc_bclink_lock();
531524
bclink_accept_pkt(node, seqno);
@@ -574,41 +567,33 @@ void tipc_bclink_rcv(struct sk_buff *buf)
574567
buf = NULL;
575568

576569
/* Determine new synchronization state */
577-
578570
tipc_node_lock(node);
579571
if (unlikely(!tipc_node_is_up(node)))
580572
goto unlock;
581573

582574
if (node->bclink.last_in == node->bclink.last_sent)
583575
goto unlock;
584576

585-
if (!node->bclink.deferred_head) {
577+
if (skb_queue_empty(&node->bclink.deferred_queue)) {
586578
node->bclink.oos_state = 1;
587579
goto unlock;
588580
}
589581

590-
msg = buf_msg(node->bclink.deferred_head);
582+
msg = buf_msg(skb_peek(&node->bclink.deferred_queue));
591583
seqno = msg_seqno(msg);
592584
next_in = mod(next_in + 1);
593585
if (seqno != next_in)
594586
goto unlock;
595587

596588
/* Take in-sequence message from deferred queue & deliver it */
597-
598-
buf = node->bclink.deferred_head;
599-
node->bclink.deferred_head = buf->next;
600-
buf->next = NULL;
601-
node->bclink.deferred_size--;
589+
buf = __skb_dequeue(&node->bclink.deferred_queue);
602590
goto receive;
603591
}
604592

605593
/* Handle out-of-sequence broadcast message */
606-
607594
if (less(next_in, seqno)) {
608-
deferred = tipc_link_defer_pkt(&node->bclink.deferred_head,
609-
&node->bclink.deferred_tail,
595+
deferred = tipc_link_defer_pkt(&node->bclink.deferred_queue,
610596
buf);
611-
node->bclink.deferred_size += deferred;
612597
bclink_update_last_sent(node, seqno);
613598
buf = NULL;
614599
}
@@ -963,6 +948,8 @@ int tipc_bclink_init(void)
963948
sprintf(bcbearer->media.name, "tipc-broadcast");
964949

965950
spin_lock_init(&bclink->lock);
951+
__skb_queue_head_init(&bcl->outqueue);
952+
__skb_queue_head_init(&bcl->deferred_queue);
966953
__skb_queue_head_init(&bcl->waiting_sks);
967954
bcl->next_out_no = 1;
968955
spin_lock_init(&bclink->node.lock);

net/tipc/bcast.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ int tipc_bclink_reset_stats(void);
100100
int tipc_bclink_set_queue_limits(u32 limit);
101101
void tipc_bcbearer_sort(struct tipc_node_map *nm_ptr, u32 node, bool action);
102102
uint tipc_bclink_get_mtu(void);
103-
int tipc_bclink_xmit(struct sk_buff *buf);
103+
int tipc_bclink_xmit(struct sk_buff_head *list);
104104
void tipc_bclink_wakeup_users(void);
105105
int tipc_nl_add_bc_link(struct tipc_nl_msg *msg);
106106

net/tipc/bearer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ extern struct tipc_bearer __rcu *bearer_list[];
165165
* TIPC routines available to supported media types
166166
*/
167167

168-
void tipc_rcv(struct sk_buff *buf, struct tipc_bearer *tb_ptr);
168+
void tipc_rcv(struct sk_buff *skb, struct tipc_bearer *tb_ptr);
169169
int tipc_enable_bearer(const char *bearer_name, u32 disc_domain, u32 priority);
170170
int tipc_disable_bearer(const char *name);
171171

net/tipc/core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ struct tipc_skb_cb {
192192
struct sk_buff *tail;
193193
bool deferred;
194194
bool wakeup_pending;
195+
bool bundling;
195196
u16 chain_sz;
196197
u16 chain_imp;
197198
};

0 commit comments

Comments
 (0)