152
152
struct midcomms_node {
153
153
int nodeid ;
154
154
uint32_t version ;
155
- uint32_t seq_send ;
156
- uint32_t seq_next ;
155
+ atomic_t seq_send ;
156
+ atomic_t seq_next ;
157
157
/* These queues are unbound because we cannot drop any message in dlm.
158
158
* We could send a fence signal for a specific node to the cluster
159
159
* manager if queues hits some maximum value, however this handling
@@ -317,8 +317,8 @@ static void midcomms_node_reset(struct midcomms_node *node)
317
317
{
318
318
pr_debug ("reset node %d\n" , node -> nodeid );
319
319
320
- node -> seq_next = DLM_SEQ_INIT ;
321
- node -> seq_send = DLM_SEQ_INIT ;
320
+ atomic_set ( & node -> seq_next , DLM_SEQ_INIT ) ;
321
+ atomic_set ( & node -> seq_send , DLM_SEQ_INIT ) ;
322
322
node -> version = DLM_VERSION_NOT_SET ;
323
323
node -> flags = 0 ;
324
324
@@ -492,9 +492,19 @@ static void dlm_midcomms_receive_buffer(union dlm_packet *p,
492
492
struct midcomms_node * node ,
493
493
uint32_t seq )
494
494
{
495
- if ( seq == node -> seq_next ) {
496
- node -> seq_next ++ ;
495
+ bool is_expected_seq ;
496
+ uint32_t oval , nval ;
497
497
498
+ do {
499
+ oval = atomic_read (& node -> seq_next );
500
+ is_expected_seq = (oval == seq );
501
+ if (!is_expected_seq )
502
+ break ;
503
+
504
+ nval = oval + 1 ;
505
+ } while (atomic_cmpxchg (& node -> seq_next , oval , nval ) != oval );
506
+
507
+ if (is_expected_seq ) {
498
508
switch (p -> header .h_cmd ) {
499
509
case DLM_FIN :
500
510
spin_lock (& node -> state_lock );
@@ -503,7 +513,7 @@ static void dlm_midcomms_receive_buffer(union dlm_packet *p,
503
513
504
514
switch (node -> state ) {
505
515
case DLM_ESTABLISHED :
506
- dlm_send_ack (node -> nodeid , node -> seq_next );
516
+ dlm_send_ack (node -> nodeid , nval );
507
517
508
518
/* passive shutdown DLM_LAST_ACK case 1
509
519
* additional we check if the node is used by
@@ -522,14 +532,14 @@ static void dlm_midcomms_receive_buffer(union dlm_packet *p,
522
532
}
523
533
break ;
524
534
case DLM_FIN_WAIT1 :
525
- dlm_send_ack (node -> nodeid , node -> seq_next );
535
+ dlm_send_ack (node -> nodeid , nval );
526
536
node -> state = DLM_CLOSING ;
527
537
set_bit (DLM_NODE_FLAG_STOP_RX , & node -> flags );
528
538
pr_debug ("switch node %d to state %s\n" ,
529
539
node -> nodeid , dlm_state_str (node -> state ));
530
540
break ;
531
541
case DLM_FIN_WAIT2 :
532
- dlm_send_ack (node -> nodeid , node -> seq_next );
542
+ dlm_send_ack (node -> nodeid , nval );
533
543
midcomms_node_reset (node );
534
544
pr_debug ("switch node %d to state %s\n" ,
535
545
node -> nodeid , dlm_state_str (node -> state ));
@@ -557,11 +567,11 @@ static void dlm_midcomms_receive_buffer(union dlm_packet *p,
557
567
/* retry to ack message which we already have by sending back
558
568
* current node->seq_next number as ack.
559
569
*/
560
- if (seq < node -> seq_next )
561
- dlm_send_ack (node -> nodeid , node -> seq_next );
570
+ if (seq < oval )
571
+ dlm_send_ack (node -> nodeid , oval );
562
572
563
573
log_print_ratelimited ("ignore dlm msg because seq mismatch, seq: %u, expected: %u, nodeid: %d" ,
564
- seq , node -> seq_next , node -> nodeid );
574
+ seq , oval , node -> nodeid );
565
575
}
566
576
}
567
577
@@ -992,7 +1002,7 @@ void dlm_midcomms_receive_done(int nodeid)
992
1002
switch (node -> state ) {
993
1003
case DLM_ESTABLISHED :
994
1004
spin_unlock (& node -> state_lock );
995
- dlm_send_ack (node -> nodeid , node -> seq_next );
1005
+ dlm_send_ack (node -> nodeid , atomic_read ( & node -> seq_next ) );
996
1006
break ;
997
1007
default :
998
1008
spin_unlock (& node -> state_lock );
@@ -1058,7 +1068,7 @@ static void midcomms_new_msg_cb(void *data)
1058
1068
list_add_tail_rcu (& mh -> list , & mh -> node -> send_queue );
1059
1069
spin_unlock_bh (& mh -> node -> send_queue_lock );
1060
1070
1061
- mh -> seq = mh -> node -> seq_send ++ ;
1071
+ mh -> seq = atomic_fetch_inc ( & mh -> node -> seq_send ) ;
1062
1072
}
1063
1073
1064
1074
static struct dlm_msg * dlm_midcomms_get_msg_3_2 (struct dlm_mhandle * mh , int nodeid ,
@@ -1530,7 +1540,7 @@ static void midcomms_new_rawmsg_cb(void *data)
1530
1540
switch (h -> h_cmd ) {
1531
1541
case DLM_OPTS :
1532
1542
if (!h -> u .h_seq )
1533
- h -> u .h_seq = cpu_to_le32 (rd -> node -> seq_send ++ );
1543
+ h -> u .h_seq = cpu_to_le32 (atomic_fetch_inc ( & rd -> node -> seq_send ) );
1534
1544
break ;
1535
1545
default :
1536
1546
break ;
0 commit comments