Lines Matching +full:node +full:- +full:version
1 // SPDX-License-Identifier: GPL-2.0-only
5 ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
6 ** Copyright (C) 2004-2021 Red Hat, Inc. All rights reserved.
15 * This is the appallingly named "mid-level" comms layer. It takes care about
27 * How version detection works:
29 * Due the fact that dlm has pre-configured node addresses on every side
33 * compatibility these messages are not covered by the midcomms re-transmission
34 * layer. These messages have their own re-transmission handling in the dlm
35 * application layer. The version field of every node will be set on these RCOM
36 * messages as soon as they arrived and the node isn't yet part of the nodes
37 * hash. There exists also logic to detect version mismatched if something weird
43 * like TCP supports it with half-closed socket support. SCTP doesn't support
44 * half-closed socket, so we do it on DLM layer. Also socket shutdown() can be
47 * compatibility. A node cannot send anything to another node when a DLM_FIN
51 * manager removed the node from internal lists, at this point DLM does not
52 * send any message to the other node. There exists two cases:
61 * +---------+
63 * +---------+
64 * | add member/receive RCOM version
67 * +---------+
69 * +---------+
71 * ------- | | -------
72 * +---------+ snd FIN / \ snd ACK +---------+
73 * | FIN |<----------------- ------------------>| CLOSE |
74 * | WAIT-1 |------------------ | WAIT |
75 * +---------+ rcv FIN \ +---------+
76 * | rcv ACK of FIN ------- | CLOSE | member
77 * | -------------- snd ACK | ------- | removal
79 * +---------+ +---------+ +---------+
80 * |FINWAIT-2| | CLOSING | | LAST-ACK|
81 * +---------+ +---------+ +---------+
83 * | rcv FIN -------------- | -------------- |
84 * | ------- x V x V
85 * \ snd ACK +---------+ +---------+
86 * ------------------------>| CLOSED | | CLOSED |
87 * +---------+ +---------+
91 * handling when we receive the version detection RCOM messages which is
97 * of them should be done in a next major dlm version bump which makes
104 * can be fixed in the next major version bump of dlm.
106 * Version detection:
108 * The version detection and how it's done is related to backwards
110 * However this should be changed in the next major version bump of dlm.
156 uint32_t version; member
160 * We could send a fence signal for a specific node to the cluster
185 /* counts how many lockspaces are using this node
187 * node wants to disconnect.
200 struct midcomms_node *node; member
206 void (*ack_rcv)(struct midcomms_node *node);
255 const char *dlm_midcomms_state(struct midcomms_node *node) in dlm_midcomms_state() argument
257 return dlm_state_str(node->state); in dlm_midcomms_state()
260 unsigned long dlm_midcomms_flags(struct midcomms_node *node) in dlm_midcomms_flags() argument
262 return node->flags; in dlm_midcomms_flags()
265 int dlm_midcomms_send_queue_cnt(struct midcomms_node *node) in dlm_midcomms_send_queue_cnt() argument
267 return atomic_read(&node->send_queue_cnt); in dlm_midcomms_send_queue_cnt()
270 uint32_t dlm_midcomms_version(struct midcomms_node *node) in dlm_midcomms_version() argument
272 return node->version; in dlm_midcomms_version()
277 struct midcomms_node *node; in __find_node() local
279 hlist_for_each_entry_rcu(node, &node_hash[r], hlist) { in __find_node()
280 if (node->nodeid == nodeid) in __find_node()
281 return node; in __find_node()
291 dlm_lowcomms_put_msg(mh->msg); in dlm_mhandle_release()
295 static void dlm_mhandle_delete(struct midcomms_node *node, in dlm_mhandle_delete() argument
298 list_del_rcu(&mh->list); in dlm_mhandle_delete()
299 atomic_dec(&node->send_queue_cnt); in dlm_mhandle_delete()
300 call_rcu(&mh->rcu, dlm_mhandle_release); in dlm_mhandle_delete()
303 static void dlm_send_queue_flush(struct midcomms_node *node) in dlm_send_queue_flush() argument
307 pr_debug("flush midcomms send queue of node %d\n", node->nodeid); in dlm_send_queue_flush()
310 spin_lock_bh(&node->send_queue_lock); in dlm_send_queue_flush()
311 list_for_each_entry_rcu(mh, &node->send_queue, list) { in dlm_send_queue_flush()
312 dlm_mhandle_delete(node, mh); in dlm_send_queue_flush()
314 spin_unlock_bh(&node->send_queue_lock); in dlm_send_queue_flush()
318 static void midcomms_node_reset(struct midcomms_node *node) in midcomms_node_reset() argument
320 pr_debug("reset node %d\n", node->nodeid); in midcomms_node_reset()
322 atomic_set(&node->seq_next, DLM_SEQ_INIT); in midcomms_node_reset()
323 atomic_set(&node->seq_send, DLM_SEQ_INIT); in midcomms_node_reset()
324 atomic_set(&node->ulp_delivered, 0); in midcomms_node_reset()
325 node->version = DLM_VERSION_NOT_SET; in midcomms_node_reset()
326 node->flags = 0; in midcomms_node_reset()
328 dlm_send_queue_flush(node); in midcomms_node_reset()
329 node->state = DLM_CLOSED; in midcomms_node_reset()
330 wake_up(&node->shutdown_wait); in midcomms_node_reset()
341 struct midcomms_node *node; in dlm_midcomms_addr() local
348 node = __find_node(nodeid, r); in dlm_midcomms_addr()
349 if (node) { in dlm_midcomms_addr()
355 node = kmalloc(sizeof(*node), GFP_NOFS); in dlm_midcomms_addr()
356 if (!node) in dlm_midcomms_addr()
357 return -ENOMEM; in dlm_midcomms_addr()
359 node->nodeid = nodeid; in dlm_midcomms_addr()
360 spin_lock_init(&node->state_lock); in dlm_midcomms_addr()
361 spin_lock_init(&node->send_queue_lock); in dlm_midcomms_addr()
362 atomic_set(&node->send_queue_cnt, 0); in dlm_midcomms_addr()
363 INIT_LIST_HEAD(&node->send_queue); in dlm_midcomms_addr()
364 init_waitqueue_head(&node->shutdown_wait); in dlm_midcomms_addr()
365 node->users = 0; in dlm_midcomms_addr()
366 midcomms_node_reset(node); in dlm_midcomms_addr()
369 hlist_add_head_rcu(&node->hlist, &node_hash[r]); in dlm_midcomms_addr()
372 node->debugfs = dlm_create_debug_comms_file(nodeid, node); in dlm_midcomms_addr()
386 return -ENOMEM; in dlm_send_ack()
390 m_header->h_version = cpu_to_le32(DLM_HEADER_MAJOR | DLM_HEADER_MINOR); in dlm_send_ack()
391 m_header->h_nodeid = cpu_to_le32(dlm_our_nodeid()); in dlm_send_ack()
392 m_header->h_length = cpu_to_le16(mb_len); in dlm_send_ack()
393 m_header->h_cmd = DLM_ACK; in dlm_send_ack()
394 m_header->u.h_seq = cpu_to_le32(seq); in dlm_send_ack()
402 static void dlm_send_ack_threshold(struct midcomms_node *node, in dlm_send_ack_threshold() argument
410 oval = atomic_read(&node->ulp_delivered); in dlm_send_ack_threshold()
418 } while (atomic_cmpxchg(&node->ulp_delivered, oval, nval) != oval); in dlm_send_ack_threshold()
421 dlm_send_ack(node->nodeid, atomic_read(&node->seq_next)); in dlm_send_ack_threshold()
424 static int dlm_send_fin(struct midcomms_node *node, in dlm_send_fin() argument
425 void (*ack_rcv)(struct midcomms_node *node)) in dlm_send_fin() argument
432 mh = dlm_midcomms_get_mhandle(node->nodeid, mb_len, GFP_ATOMIC, &ppc); in dlm_send_fin()
434 return -ENOMEM; in dlm_send_fin()
436 set_bit(DLM_NODE_FLAG_STOP_TX, &node->flags); in dlm_send_fin()
437 mh->ack_rcv = ack_rcv; in dlm_send_fin()
441 m_header->h_version = cpu_to_le32(DLM_HEADER_MAJOR | DLM_HEADER_MINOR); in dlm_send_fin()
442 m_header->h_nodeid = cpu_to_le32(dlm_our_nodeid()); in dlm_send_fin()
443 m_header->h_length = cpu_to_le16(mb_len); in dlm_send_fin()
444 m_header->h_cmd = DLM_FIN; in dlm_send_fin()
446 pr_debug("sending fin msg to node %d\n", node->nodeid); in dlm_send_fin()
452 static void dlm_receive_ack(struct midcomms_node *node, uint32_t seq) in dlm_receive_ack() argument
457 list_for_each_entry_rcu(mh, &node->send_queue, list) { in dlm_receive_ack()
458 if (before(mh->seq, seq)) { in dlm_receive_ack()
459 if (mh->ack_rcv) in dlm_receive_ack()
460 mh->ack_rcv(node); in dlm_receive_ack()
467 spin_lock_bh(&node->send_queue_lock); in dlm_receive_ack()
468 list_for_each_entry_rcu(mh, &node->send_queue, list) { in dlm_receive_ack()
469 if (before(mh->seq, seq)) { in dlm_receive_ack()
470 dlm_mhandle_delete(node, mh); in dlm_receive_ack()
476 spin_unlock_bh(&node->send_queue_lock); in dlm_receive_ack()
480 static void dlm_pas_fin_ack_rcv(struct midcomms_node *node) in dlm_pas_fin_ack_rcv() argument
482 spin_lock(&node->state_lock); in dlm_pas_fin_ack_rcv()
483 pr_debug("receive passive fin ack from node %d with state %s\n", in dlm_pas_fin_ack_rcv()
484 node->nodeid, dlm_state_str(node->state)); in dlm_pas_fin_ack_rcv()
486 switch (node->state) { in dlm_pas_fin_ack_rcv()
489 midcomms_node_reset(node); in dlm_pas_fin_ack_rcv()
493 wake_up(&node->shutdown_wait); in dlm_pas_fin_ack_rcv()
496 spin_unlock(&node->state_lock); in dlm_pas_fin_ack_rcv()
498 __func__, node->state); in dlm_pas_fin_ack_rcv()
502 spin_unlock(&node->state_lock); in dlm_pas_fin_ack_rcv()
508 switch (p->header.h_cmd) { in dlm_receive_buffer_3_2_trace()
510 trace_dlm_recv_message(dlm_our_nodeid(), seq, &p->message); in dlm_receive_buffer_3_2_trace()
513 trace_dlm_recv_rcom(dlm_our_nodeid(), seq, &p->rcom); in dlm_receive_buffer_3_2_trace()
521 struct midcomms_node *node, in dlm_midcomms_receive_buffer() argument
528 oval = atomic_read(&node->seq_next); in dlm_midcomms_receive_buffer()
534 } while (atomic_cmpxchg(&node->seq_next, oval, nval) != oval); in dlm_midcomms_receive_buffer()
537 switch (p->header.h_cmd) { in dlm_midcomms_receive_buffer()
539 spin_lock(&node->state_lock); in dlm_midcomms_receive_buffer()
540 pr_debug("receive fin msg from node %d with state %s\n", in dlm_midcomms_receive_buffer()
541 node->nodeid, dlm_state_str(node->state)); in dlm_midcomms_receive_buffer()
543 switch (node->state) { in dlm_midcomms_receive_buffer()
545 dlm_send_ack(node->nodeid, nval); in dlm_midcomms_receive_buffer()
548 * additional we check if the node is used by in dlm_midcomms_receive_buffer()
551 if (node->users == 0) { in dlm_midcomms_receive_buffer()
552 node->state = DLM_LAST_ACK; in dlm_midcomms_receive_buffer()
553 pr_debug("switch node %d to state %s case 1\n", in dlm_midcomms_receive_buffer()
554 node->nodeid, dlm_state_str(node->state)); in dlm_midcomms_receive_buffer()
555 set_bit(DLM_NODE_FLAG_STOP_RX, &node->flags); in dlm_midcomms_receive_buffer()
556 dlm_send_fin(node, dlm_pas_fin_ack_rcv); in dlm_midcomms_receive_buffer()
558 node->state = DLM_CLOSE_WAIT; in dlm_midcomms_receive_buffer()
559 pr_debug("switch node %d to state %s\n", in dlm_midcomms_receive_buffer()
560 node->nodeid, dlm_state_str(node->state)); in dlm_midcomms_receive_buffer()
564 dlm_send_ack(node->nodeid, nval); in dlm_midcomms_receive_buffer()
565 node->state = DLM_CLOSING; in dlm_midcomms_receive_buffer()
566 set_bit(DLM_NODE_FLAG_STOP_RX, &node->flags); in dlm_midcomms_receive_buffer()
567 pr_debug("switch node %d to state %s\n", in dlm_midcomms_receive_buffer()
568 node->nodeid, dlm_state_str(node->state)); in dlm_midcomms_receive_buffer()
571 dlm_send_ack(node->nodeid, nval); in dlm_midcomms_receive_buffer()
572 midcomms_node_reset(node); in dlm_midcomms_receive_buffer()
573 pr_debug("switch node %d to state %s\n", in dlm_midcomms_receive_buffer()
574 node->nodeid, dlm_state_str(node->state)); in dlm_midcomms_receive_buffer()
580 spin_unlock(&node->state_lock); in dlm_midcomms_receive_buffer()
582 __func__, node->state); in dlm_midcomms_receive_buffer()
586 spin_unlock(&node->state_lock); in dlm_midcomms_receive_buffer()
589 WARN_ON_ONCE(test_bit(DLM_NODE_FLAG_STOP_RX, &node->flags)); in dlm_midcomms_receive_buffer()
591 dlm_receive_buffer(p, node->nodeid); in dlm_midcomms_receive_buffer()
592 atomic_inc(&node->ulp_delivered); in dlm_midcomms_receive_buffer()
594 dlm_send_ack_threshold(node, DLM_RECV_ACK_BACK_MSG_THRESHOLD); in dlm_midcomms_receive_buffer()
599 * current node->seq_next number as ack. in dlm_midcomms_receive_buffer()
602 dlm_send_ack(node->nodeid, oval); in dlm_midcomms_receive_buffer()
605 seq, oval, node->nodeid); in dlm_midcomms_receive_buffer()
618 return -1; in dlm_opts_check_msglen()
619 len -= sizeof(struct dlm_opts); in dlm_opts_check_msglen()
621 if (len < le16_to_cpu(p->opts.o_optlen)) in dlm_opts_check_msglen()
622 return -1; in dlm_opts_check_msglen()
623 len -= le16_to_cpu(p->opts.o_optlen); in dlm_opts_check_msglen()
625 switch (p->opts.o_nextcmd) { in dlm_opts_check_msglen()
628 log_print("fin too small: %d, will skip this message from node %d", in dlm_opts_check_msglen()
630 return -1; in dlm_opts_check_msglen()
636 log_print("msg too small: %d, will skip this message from node %d", in dlm_opts_check_msglen()
638 return -1; in dlm_opts_check_msglen()
644 log_print("rcom msg too small: %d, will skip this message from node %d", in dlm_opts_check_msglen()
646 return -1; in dlm_opts_check_msglen()
651 log_print("unsupported o_nextcmd received: %u, will skip this message from node %d", in dlm_opts_check_msglen()
652 p->opts.o_nextcmd, nodeid); in dlm_opts_check_msglen()
653 return -1; in dlm_opts_check_msglen()
661 uint16_t msglen = le16_to_cpu(p->header.h_length); in dlm_midcomms_receive_buffer_3_2()
662 struct midcomms_node *node; in dlm_midcomms_receive_buffer_3_2() local
667 node = nodeid2node(nodeid); in dlm_midcomms_receive_buffer_3_2()
668 if (WARN_ON_ONCE(!node)) in dlm_midcomms_receive_buffer_3_2()
671 switch (node->version) { in dlm_midcomms_receive_buffer_3_2()
673 node->version = DLM_VERSION_3_2; in dlm_midcomms_receive_buffer_3_2()
674 wake_up(&node->shutdown_wait); in dlm_midcomms_receive_buffer_3_2()
675 log_print("version 0x%08x for node %d detected", DLM_VERSION_3_2, in dlm_midcomms_receive_buffer_3_2()
676 node->nodeid); in dlm_midcomms_receive_buffer_3_2()
678 spin_lock(&node->state_lock); in dlm_midcomms_receive_buffer_3_2()
679 switch (node->state) { in dlm_midcomms_receive_buffer_3_2()
681 node->state = DLM_ESTABLISHED; in dlm_midcomms_receive_buffer_3_2()
682 pr_debug("switch node %d to state %s\n", in dlm_midcomms_receive_buffer_3_2()
683 node->nodeid, dlm_state_str(node->state)); in dlm_midcomms_receive_buffer_3_2()
688 spin_unlock(&node->state_lock); in dlm_midcomms_receive_buffer_3_2()
694 log_print_ratelimited("version mismatch detected, assumed 0x%08x but node %d has 0x%08x", in dlm_midcomms_receive_buffer_3_2()
695 DLM_VERSION_3_2, node->nodeid, node->version); in dlm_midcomms_receive_buffer_3_2()
699 switch (p->header.h_cmd) { in dlm_midcomms_receive_buffer_3_2()
701 /* these rcom message we use to determine version. in dlm_midcomms_receive_buffer_3_2()
707 switch (p->rcom.rc_type) { in dlm_midcomms_receive_buffer_3_2()
717 log_print("unsupported rcom type received: %u, will skip this message from node %d", in dlm_midcomms_receive_buffer_3_2()
718 le32_to_cpu(p->rcom.rc_type), nodeid); in dlm_midcomms_receive_buffer_3_2()
722 WARN_ON_ONCE(test_bit(DLM_NODE_FLAG_STOP_RX, &node->flags)); in dlm_midcomms_receive_buffer_3_2()
726 seq = le32_to_cpu(p->header.u.h_seq); in dlm_midcomms_receive_buffer_3_2()
730 log_print("opts msg too small: %u, will skip this message from node %d", in dlm_midcomms_receive_buffer_3_2()
735 p = (union dlm_packet *)((unsigned char *)p->opts.o_opts + in dlm_midcomms_receive_buffer_3_2()
736 le16_to_cpu(p->opts.o_optlen)); in dlm_midcomms_receive_buffer_3_2()
739 msglen = le16_to_cpu(p->header.h_length); in dlm_midcomms_receive_buffer_3_2()
740 switch (p->header.h_cmd) { in dlm_midcomms_receive_buffer_3_2()
743 log_print("inner rcom msg too small: %u, will skip this message from node %d", in dlm_midcomms_receive_buffer_3_2()
751 log_print("inner msg too small: %u, will skip this message from node %d", in dlm_midcomms_receive_buffer_3_2()
759 log_print("inner fin too small: %u, will skip this message from node %d", in dlm_midcomms_receive_buffer_3_2()
766 log_print("unsupported inner h_cmd received: %u, will skip this message from node %d", in dlm_midcomms_receive_buffer_3_2()
771 dlm_midcomms_receive_buffer(p, node, seq); in dlm_midcomms_receive_buffer_3_2()
774 seq = le32_to_cpu(p->header.u.h_seq); in dlm_midcomms_receive_buffer_3_2()
775 dlm_receive_ack(node, seq); in dlm_midcomms_receive_buffer_3_2()
778 log_print("unsupported h_cmd received: %u, will skip this message from node %d", in dlm_midcomms_receive_buffer_3_2()
779 p->header.h_cmd, nodeid); in dlm_midcomms_receive_buffer_3_2()
789 uint16_t msglen = le16_to_cpu(p->header.h_length); in dlm_midcomms_receive_buffer_3_1()
790 struct midcomms_node *node; in dlm_midcomms_receive_buffer_3_1() local
794 node = nodeid2node(nodeid); in dlm_midcomms_receive_buffer_3_1()
795 if (WARN_ON_ONCE(!node)) { in dlm_midcomms_receive_buffer_3_1()
800 switch (node->version) { in dlm_midcomms_receive_buffer_3_1()
802 node->version = DLM_VERSION_3_1; in dlm_midcomms_receive_buffer_3_1()
803 wake_up(&node->shutdown_wait); in dlm_midcomms_receive_buffer_3_1()
804 log_print("version 0x%08x for node %d detected", DLM_VERSION_3_1, in dlm_midcomms_receive_buffer_3_1()
805 node->nodeid); in dlm_midcomms_receive_buffer_3_1()
810 log_print_ratelimited("version mismatch detected, assumed 0x%08x but node %d has 0x%08x", in dlm_midcomms_receive_buffer_3_1()
811 DLM_VERSION_3_1, node->nodeid, node->version); in dlm_midcomms_receive_buffer_3_1()
817 switch (p->header.h_cmd) { in dlm_midcomms_receive_buffer_3_1()
823 log_print("msg too small: %u, will skip this message from node %d", in dlm_midcomms_receive_buffer_3_1()
830 log_print("unsupported h_cmd received: %u, will skip this message from node %d", in dlm_midcomms_receive_buffer_3_1()
831 p->header.h_cmd, nodeid); in dlm_midcomms_receive_buffer_3_1()
857 * the next major version bump. in dlm_validate_incoming_buffer()
859 msglen = le16_to_cpu(hd->h_length); in dlm_validate_incoming_buffer()
862 log_print("received invalid length header: %u from node %d, will abort message parsing", in dlm_validate_incoming_buffer()
864 return -EBADMSG; in dlm_validate_incoming_buffer()
874 len -= msglen; in dlm_validate_incoming_buffer()
882 * Called from the low-level comms layer to process a buffer of
895 msglen = le16_to_cpu(hd->h_length); in dlm_process_incoming_buffer()
899 switch (hd->h_version) { in dlm_process_incoming_buffer()
907 log_print("received invalid version header: %u from node %d, will skip this message", in dlm_process_incoming_buffer()
908 le32_to_cpu(hd->h_version), nodeid); in dlm_process_incoming_buffer()
913 len -= msglen; in dlm_process_incoming_buffer()
922 struct midcomms_node *node; in dlm_midcomms_unack_msg_resend() local
927 node = nodeid2node(nodeid); in dlm_midcomms_unack_msg_resend()
928 if (WARN_ON_ONCE(!node)) { in dlm_midcomms_unack_msg_resend()
934 switch (node->version) { in dlm_midcomms_unack_msg_resend()
943 list_for_each_entry_rcu(mh, &node->send_queue, list) { in dlm_midcomms_unack_msg_resend()
944 if (!mh->committed) in dlm_midcomms_unack_msg_resend()
947 ret = dlm_lowcomms_resend_msg(mh->msg); in dlm_midcomms_unack_msg_resend()
950 mh->seq, node->nodeid); in dlm_midcomms_unack_msg_resend()
959 opts->o_header.h_cmd = DLM_OPTS; in dlm_fill_opts_header()
960 opts->o_header.h_version = cpu_to_le32(DLM_HEADER_MAJOR | DLM_HEADER_MINOR); in dlm_fill_opts_header()
961 opts->o_header.h_nodeid = cpu_to_le32(dlm_our_nodeid()); in dlm_fill_opts_header()
962 opts->o_header.h_length = cpu_to_le16(DLM_MIDCOMMS_OPT_LEN + inner_len); in dlm_fill_opts_header()
963 opts->o_header.u.h_seq = cpu_to_le32(seq); in dlm_fill_opts_header()
970 atomic_inc(&mh->node->send_queue_cnt); in midcomms_new_msg_cb()
972 spin_lock_bh(&mh->node->send_queue_lock); in midcomms_new_msg_cb()
973 list_add_tail_rcu(&mh->list, &mh->node->send_queue); in midcomms_new_msg_cb()
974 spin_unlock_bh(&mh->node->send_queue_lock); in midcomms_new_msg_cb()
976 mh->seq = atomic_fetch_inc(&mh->node->seq_send); in midcomms_new_msg_cb()
991 mh->opts = opts; in dlm_midcomms_get_msg_3_2()
994 dlm_fill_opts_header(opts, len, mh->seq); in dlm_midcomms_get_msg_3_2()
997 mh->inner_p = (const union dlm_packet *)*ppc; in dlm_midcomms_get_msg_3_2()
1008 struct midcomms_node *node; in dlm_midcomms_get_mhandle() local
1014 node = nodeid2node(nodeid); in dlm_midcomms_get_mhandle()
1015 if (WARN_ON_ONCE(!node)) in dlm_midcomms_get_mhandle()
1019 WARN_ON_ONCE(test_bit(DLM_NODE_FLAG_STOP_TX, &node->flags)); in dlm_midcomms_get_mhandle()
1025 mh->committed = false; in dlm_midcomms_get_mhandle()
1026 mh->ack_rcv = NULL; in dlm_midcomms_get_mhandle()
1027 mh->idx = idx; in dlm_midcomms_get_mhandle()
1028 mh->node = node; in dlm_midcomms_get_mhandle()
1030 switch (node->version) { in dlm_midcomms_get_mhandle()
1042 dlm_send_ack_threshold(node, DLM_SEND_ACK_BACK_MSG_THRESHOLD); in dlm_midcomms_get_mhandle()
1057 mh->msg = msg; in dlm_midcomms_get_mhandle()
1061 * nodes_srcu using mh->idx which is assumed in dlm_midcomms_get_mhandle()
1075 switch (mh->inner_p->header.h_cmd) { in dlm_midcomms_commit_msg_3_2_trace()
1077 trace_dlm_send_message(mh->node->nodeid, mh->seq, in dlm_midcomms_commit_msg_3_2_trace()
1078 &mh->inner_p->message, in dlm_midcomms_commit_msg_3_2_trace()
1082 trace_dlm_send_rcom(mh->node->nodeid, mh->seq, in dlm_midcomms_commit_msg_3_2_trace()
1083 &mh->inner_p->rcom); in dlm_midcomms_commit_msg_3_2_trace()
1095 mh->opts->o_nextcmd = mh->inner_p->header.h_cmd; in dlm_midcomms_commit_msg_3_2()
1096 mh->committed = true; in dlm_midcomms_commit_msg_3_2()
1098 dlm_lowcomms_commit_msg(mh->msg); in dlm_midcomms_commit_msg_3_2()
1109 switch (mh->node->version) { in dlm_midcomms_commit_mhandle()
1111 srcu_read_unlock(&nodes_srcu, mh->idx); in dlm_midcomms_commit_mhandle()
1113 dlm_lowcomms_commit_msg(mh->msg); in dlm_midcomms_commit_mhandle()
1114 dlm_lowcomms_put_msg(mh->msg); in dlm_midcomms_commit_mhandle()
1126 srcu_read_unlock(&nodes_srcu, mh->idx); in dlm_midcomms_commit_mhandle()
1130 srcu_read_unlock(&nodes_srcu, mh->idx); in dlm_midcomms_commit_mhandle()
1159 struct midcomms_node *node = container_of(rcu, struct midcomms_node, rcu); in midcomms_node_release() local
1161 WARN_ON_ONCE(atomic_read(&node->send_queue_cnt)); in midcomms_node_release()
1162 dlm_send_queue_flush(node); in midcomms_node_release()
1163 kfree(node); in midcomms_node_release()
1168 struct midcomms_node *node; in dlm_midcomms_exit() local
1173 hlist_for_each_entry_rcu(node, &node_hash[i], hlist) { in dlm_midcomms_exit()
1174 dlm_delete_debug_comms_file(node->debugfs); in dlm_midcomms_exit()
1177 hlist_del_rcu(&node->hlist); in dlm_midcomms_exit()
1180 call_srcu(&nodes_srcu, &node->rcu, midcomms_node_release); in dlm_midcomms_exit()
1188 static void dlm_act_fin_ack_rcv(struct midcomms_node *node) in dlm_act_fin_ack_rcv() argument
1190 spin_lock(&node->state_lock); in dlm_act_fin_ack_rcv()
1191 pr_debug("receive active fin ack from node %d with state %s\n", in dlm_act_fin_ack_rcv()
1192 node->nodeid, dlm_state_str(node->state)); in dlm_act_fin_ack_rcv()
1194 switch (node->state) { in dlm_act_fin_ack_rcv()
1196 node->state = DLM_FIN_WAIT2; in dlm_act_fin_ack_rcv()
1197 pr_debug("switch node %d to state %s\n", in dlm_act_fin_ack_rcv()
1198 node->nodeid, dlm_state_str(node->state)); in dlm_act_fin_ack_rcv()
1201 midcomms_node_reset(node); in dlm_act_fin_ack_rcv()
1202 pr_debug("switch node %d to state %s\n", in dlm_act_fin_ack_rcv()
1203 node->nodeid, dlm_state_str(node->state)); in dlm_act_fin_ack_rcv()
1207 wake_up(&node->shutdown_wait); in dlm_act_fin_ack_rcv()
1210 spin_unlock(&node->state_lock); in dlm_act_fin_ack_rcv()
1212 __func__, node->state); in dlm_act_fin_ack_rcv()
1216 spin_unlock(&node->state_lock); in dlm_act_fin_ack_rcv()
1221 struct midcomms_node *node; in dlm_midcomms_add_member() local
1225 node = nodeid2node(nodeid); in dlm_midcomms_add_member()
1226 if (WARN_ON_ONCE(!node)) { in dlm_midcomms_add_member()
1231 spin_lock(&node->state_lock); in dlm_midcomms_add_member()
1232 if (!node->users) { in dlm_midcomms_add_member()
1233 pr_debug("receive add member from node %d with state %s\n", in dlm_midcomms_add_member()
1234 node->nodeid, dlm_state_str(node->state)); in dlm_midcomms_add_member()
1235 switch (node->state) { in dlm_midcomms_add_member()
1239 node->state = DLM_ESTABLISHED; in dlm_midcomms_add_member()
1240 pr_debug("switch node %d to state %s\n", in dlm_midcomms_add_member()
1241 node->nodeid, dlm_state_str(node->state)); in dlm_midcomms_add_member()
1248 log_print("reset node %d because shutdown stuck", in dlm_midcomms_add_member()
1249 node->nodeid); in dlm_midcomms_add_member()
1251 midcomms_node_reset(node); in dlm_midcomms_add_member()
1252 node->state = DLM_ESTABLISHED; in dlm_midcomms_add_member()
1257 node->users++; in dlm_midcomms_add_member()
1258 pr_debug("node %d users inc count %d\n", nodeid, node->users); in dlm_midcomms_add_member()
1259 spin_unlock(&node->state_lock); in dlm_midcomms_add_member()
1266 struct midcomms_node *node; in dlm_midcomms_remove_member() local
1270 node = nodeid2node(nodeid); in dlm_midcomms_remove_member()
1271 /* in case of dlm_midcomms_close() removes node */ in dlm_midcomms_remove_member()
1272 if (!node) { in dlm_midcomms_remove_member()
1277 spin_lock(&node->state_lock); in dlm_midcomms_remove_member()
1278 /* case of dlm_midcomms_addr() created node but in dlm_midcomms_remove_member()
1280 * removed the node in dlm_midcomms_remove_member()
1282 if (!node->users) { in dlm_midcomms_remove_member()
1283 spin_unlock(&node->state_lock); in dlm_midcomms_remove_member()
1288 node->users--; in dlm_midcomms_remove_member()
1289 pr_debug("node %d users dec count %d\n", nodeid, node->users); in dlm_midcomms_remove_member()
1295 if (node->users == 0) { in dlm_midcomms_remove_member()
1296 pr_debug("receive remove member from node %d with state %s\n", in dlm_midcomms_remove_member()
1297 node->nodeid, dlm_state_str(node->state)); in dlm_midcomms_remove_member()
1298 switch (node->state) { in dlm_midcomms_remove_member()
1303 node->state = DLM_LAST_ACK; in dlm_midcomms_remove_member()
1304 pr_debug("switch node %d to state %s case 2\n", in dlm_midcomms_remove_member()
1305 node->nodeid, dlm_state_str(node->state)); in dlm_midcomms_remove_member()
1306 set_bit(DLM_NODE_FLAG_STOP_RX, &node->flags); in dlm_midcomms_remove_member()
1307 dlm_send_fin(node, dlm_pas_fin_ack_rcv); in dlm_midcomms_remove_member()
1317 __func__, node->state); in dlm_midcomms_remove_member()
1321 spin_unlock(&node->state_lock); in dlm_midcomms_remove_member()
1328 struct midcomms_node *node; in dlm_midcomms_version_wait() local
1333 hlist_for_each_entry_rcu(node, &node_hash[i], hlist) { in dlm_midcomms_version_wait()
1334 ret = wait_event_timeout(node->shutdown_wait, in dlm_midcomms_version_wait()
1335 node->version != DLM_VERSION_NOT_SET || in dlm_midcomms_version_wait()
1336 node->state == DLM_CLOSED || in dlm_midcomms_version_wait()
1337 test_bit(DLM_NODE_FLAG_CLOSE, &node->flags), in dlm_midcomms_version_wait()
1339 if (!ret || test_bit(DLM_NODE_FLAG_CLOSE, &node->flags)) in dlm_midcomms_version_wait()
1340 pr_debug("version wait timed out for node %d with state %s\n", in dlm_midcomms_version_wait()
1341 node->nodeid, dlm_state_str(node->state)); in dlm_midcomms_version_wait()
1347 static void midcomms_shutdown(struct midcomms_node *node) in midcomms_shutdown() argument
1352 switch (node->version) { in midcomms_shutdown()
1359 spin_lock(&node->state_lock); in midcomms_shutdown()
1360 pr_debug("receive active shutdown for node %d with state %s\n", in midcomms_shutdown()
1361 node->nodeid, dlm_state_str(node->state)); in midcomms_shutdown()
1362 switch (node->state) { in midcomms_shutdown()
1364 node->state = DLM_FIN_WAIT1; in midcomms_shutdown()
1365 pr_debug("switch node %d to state %s case 2\n", in midcomms_shutdown()
1366 node->nodeid, dlm_state_str(node->state)); in midcomms_shutdown()
1367 dlm_send_fin(node, dlm_act_fin_ack_rcv); in midcomms_shutdown()
1378 spin_unlock(&node->state_lock); in midcomms_shutdown()
1384 ret = wait_event_timeout(node->shutdown_wait, in midcomms_shutdown()
1385 node->state == DLM_CLOSED || in midcomms_shutdown()
1386 test_bit(DLM_NODE_FLAG_CLOSE, &node->flags), in midcomms_shutdown()
1389 pr_debug("active shutdown timed out for node %d with state %s\n", in midcomms_shutdown()
1390 node->nodeid, dlm_state_str(node->state)); in midcomms_shutdown()
1392 pr_debug("active shutdown done for node %d with state %s\n", in midcomms_shutdown()
1393 node->nodeid, dlm_state_str(node->state)); in midcomms_shutdown()
1398 struct midcomms_node *node; in dlm_midcomms_shutdown() local
1404 hlist_for_each_entry_rcu(node, &node_hash[i], hlist) { in dlm_midcomms_shutdown()
1405 midcomms_shutdown(node); in dlm_midcomms_shutdown()
1412 hlist_for_each_entry_rcu(node, &node_hash[i], hlist) { in dlm_midcomms_shutdown()
1413 midcomms_node_reset(node); in dlm_midcomms_shutdown()
1422 struct midcomms_node *node; in dlm_midcomms_close() local
1427 node = nodeid2node(nodeid); in dlm_midcomms_close()
1428 if (node) { in dlm_midcomms_close()
1430 set_bit(DLM_NODE_FLAG_CLOSE, &node->flags); in dlm_midcomms_close()
1431 wake_up(&node->shutdown_wait); in dlm_midcomms_close()
1439 node = nodeid2node(nodeid); in dlm_midcomms_close()
1440 if (!node) { in dlm_midcomms_close()
1447 dlm_delete_debug_comms_file(node->debugfs); in dlm_midcomms_close()
1450 hlist_del_rcu(&node->hlist); in dlm_midcomms_close()
1458 * this function get called when the node is fenced in dlm_midcomms_close()
1460 dlm_send_queue_flush(node); in dlm_midcomms_close()
1462 call_srcu(&nodes_srcu, &node->rcu, midcomms_node_release); in dlm_midcomms_close()
1470 struct midcomms_node *node; member
1477 struct dlm_header *h = rd->buf; in midcomms_new_rawmsg_cb()
1479 switch (h->h_version) { in midcomms_new_rawmsg_cb()
1483 switch (h->h_cmd) { in midcomms_new_rawmsg_cb()
1485 if (!h->u.h_seq) in midcomms_new_rawmsg_cb()
1486 h->u.h_seq = cpu_to_le32(atomic_fetch_inc(&rd->node->seq_send)); in midcomms_new_rawmsg_cb()
1495 int dlm_midcomms_rawmsg_send(struct midcomms_node *node, void *buf, in dlm_midcomms_rawmsg_send() argument
1502 rd.node = node; in dlm_midcomms_rawmsg_send()
1505 msg = dlm_lowcomms_new_msg(node->nodeid, buflen, GFP_NOFS, in dlm_midcomms_rawmsg_send()
1508 return -ENOMEM; in dlm_midcomms_rawmsg_send()