Lines Matching +full:loss +full:- +full:of +full:- +full:lock

10  * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * notice, this list of conditions and the following disclaimer in the
15 * 3. Neither the names of the copyright holders nor the names of its
19 * Alternatively, this software may be distributed under the terms of the
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
47 * @len: actual size of domain record
48 * @gen: current generation of sender's domain
49 * @ack_gen: most recent generation of self's domain acked by peer
50 * @member_cnt: number of domain member nodes described in this record
51 * @up_map: bit map indicating which of the members the sender considers up
52 * @members: identity of the domain members
63 /* struct tipc_peer: state of a peer node and its domain
64 * @addr: tipc node identity of peer
69 * @applied: number of reported domain members applied on this monitor list
73 * @down_cnt: - numbers of other peers which have reported this on lost
91 rwlock_t lock; member
102 return tipc_net(net)->monitors[bearer_id]; in tipc_monitor()
137 /* dom_rec_len(): actual length of domain record for transport
144 /* dom_size() : calculate size of own domain based on number of peers
168 return list_last_entry(&peer->list, struct tipc_peer, list); in peer_prev()
173 return list_first_entry(&peer->list, struct tipc_peer, list); in peer_nxt()
178 while (!peer->is_head) in peer_head()
188 hlist_for_each_entry(peer, &mon->peers[thash], hash) { in get_peer()
189 if (peer->addr == addr) in get_peer()
199 return mon->self; in get_self()
206 return mon->peer_cnt > tn->mon_threshold; in tipc_mon_is_active()
209 /* mon_identify_lost_members() : - identify amd mark potentially lost members
216 struct tipc_mon_domain *dom_aft = peer->domain; in mon_identify_lost_members()
217 int applied_aft = peer->applied; in mon_identify_lost_members()
224 if (!member->is_up || !map_get(dom_bef->up_map, i)) in mon_identify_lost_members()
227 /* Loss of local node must be detected by active probing */ in mon_identify_lost_members()
228 if (member->is_local) in mon_identify_lost_members()
233 member->down_cnt = 1; in mon_identify_lost_members()
237 /* Member loss is confirmed if it is still in applied domain */ in mon_identify_lost_members()
238 if (!map_get(dom_aft->up_map, i)) in mon_identify_lost_members()
239 member->down_cnt++; in mon_identify_lost_members()
248 struct tipc_mon_domain *dom = peer->domain; in mon_apply_domain()
253 if (!dom || !peer->is_up) in mon_apply_domain()
257 peer->applied = 0; in mon_apply_domain()
259 for (i = 0; i < dom->member_cnt; i++) { in mon_apply_domain()
260 addr = dom->members[i]; in mon_apply_domain()
261 if (addr != member->addr) in mon_apply_domain()
263 peer->applied++; in mon_apply_domain()
272 struct tipc_peer *self = mon->self; in mon_update_local_domain()
273 struct tipc_mon_domain *cache = &mon->cache; in mon_update_local_domain()
274 struct tipc_mon_domain *dom = self->domain; in mon_update_local_domain()
276 u64 prev_up_map = dom->up_map; in mon_update_local_domain()
280 /* Update local domain size based on current size of cluster */ in mon_update_local_domain()
281 member_cnt = dom_size(mon->peer_cnt) - 1; in mon_update_local_domain()
282 self->applied = member_cnt; in mon_update_local_domain()
285 dom->len = dom_rec_len(dom, member_cnt); in mon_update_local_domain()
286 diff = dom->member_cnt != member_cnt; in mon_update_local_domain()
287 dom->member_cnt = member_cnt; in mon_update_local_domain()
290 diff |= dom->members[i] != peer->addr; in mon_update_local_domain()
291 dom->members[i] = peer->addr; in mon_update_local_domain()
292 map_set(&dom->up_map, i, peer->is_up); in mon_update_local_domain()
293 cache->members[i] = mon_cpu_to_le32(peer->addr); in mon_update_local_domain()
295 diff |= dom->up_map != prev_up_map; in mon_update_local_domain()
298 dom->gen = ++mon->dom_gen; in mon_update_local_domain()
299 cache->len = mon_cpu_to_le16(dom->len); in mon_update_local_domain()
300 cache->gen = mon_cpu_to_le16(dom->gen); in mon_update_local_domain()
301 cache->member_cnt = mon_cpu_to_le16(member_cnt); in mon_update_local_domain()
302 cache->up_map = mon_cpu_to_le64(dom->up_map); in mon_update_local_domain()
306 /* mon_update_neighbors() : update preceding neighbors of added/removed peer
313 dz = dom_size(mon->peer_cnt); in mon_update_neighbors()
322 * a set of domain members as matched between domain record and the monitor list
327 struct tipc_peer *self = mon->self; in mon_assign_roles()
331 peer->is_local = false; in mon_assign_roles()
334 if (i++ < head->applied) { in mon_assign_roles()
335 peer->is_head = false; in mon_assign_roles()
337 peer->is_local = true; in mon_assign_roles()
341 if (!peer->is_up) in mon_assign_roles()
343 if (peer->is_head) in mon_assign_roles()
346 head->is_head = true; in mon_assign_roles()
349 mon->list_gen++; in mon_assign_roles()
362 write_lock_bh(&mon->lock); in tipc_mon_remove_peer()
367 list_del(&peer->list); in tipc_mon_remove_peer()
368 hlist_del(&peer->hash); in tipc_mon_remove_peer()
369 kfree(peer->domain); in tipc_mon_remove_peer()
371 mon->peer_cnt--; in tipc_mon_remove_peer()
377 /* Revert to full-mesh monitoring if we reach threshold */ in tipc_mon_remove_peer()
379 list_for_each_entry(peer, &self->list, list) { in tipc_mon_remove_peer()
380 kfree(peer->domain); in tipc_mon_remove_peer()
381 peer->domain = NULL; in tipc_mon_remove_peer()
382 peer->applied = 0; in tipc_mon_remove_peer()
387 write_unlock_bh(&mon->lock); in tipc_mon_remove_peer()
393 struct tipc_peer *self = mon->self; in tipc_mon_add_peer()
400 p->addr = addr; in tipc_mon_add_peer()
403 INIT_LIST_HEAD(&p->list); in tipc_mon_add_peer()
404 hlist_add_head(&p->hash, &mon->peers[tipc_hashfn(addr)]); in tipc_mon_add_peer()
408 list_for_each_entry(cur, &self->list, list) { in tipc_mon_add_peer()
409 if ((addr > prev->addr) && (addr < cur->addr)) in tipc_mon_add_peer()
411 if (((addr < cur->addr) || (addr > prev->addr)) && in tipc_mon_add_peer()
412 (prev->addr > cur->addr)) in tipc_mon_add_peer()
416 list_add_tail(&p->list, &cur->list); in tipc_mon_add_peer()
417 mon->peer_cnt++; in tipc_mon_add_peer()
428 write_lock_bh(&mon->lock); in tipc_mon_peer_up()
432 peer->is_up = true; in tipc_mon_peer_up()
438 write_unlock_bh(&mon->lock); in tipc_mon_peer_up()
453 write_lock_bh(&mon->lock); in tipc_mon_peer_down()
459 applied = peer->applied; in tipc_mon_peer_down()
460 peer->applied = 0; in tipc_mon_peer_down()
461 dom = peer->domain; in tipc_mon_peer_down()
462 peer->domain = NULL; in tipc_mon_peer_down()
463 if (peer->is_head) in tipc_mon_peer_down()
466 peer->is_up = false; in tipc_mon_peer_down()
467 peer->is_head = false; in tipc_mon_peer_down()
468 peer->is_local = false; in tipc_mon_peer_down()
469 peer->down_cnt = 0; in tipc_mon_peer_down()
475 write_unlock_bh(&mon->lock); in tipc_mon_peer_down()
478 /* tipc_mon_rcv - process monitor domain event message
488 u16 new_member_cnt = mon_le16_to_cpu(arrv_dom->member_cnt); in tipc_mon_rcv()
490 u16 new_gen = mon_le16_to_cpu(arrv_dom->gen); in tipc_mon_rcv()
491 u16 acked_gen = mon_le16_to_cpu(arrv_dom->ack_gen); in tipc_mon_rcv()
492 u16 arrv_dlen = mon_le16_to_cpu(arrv_dom->len); in tipc_mon_rcv()
493 bool probing = state->probing; in tipc_mon_rcv()
496 state->probing = false; in tipc_mon_rcv()
509 if (!state->synched) { in tipc_mon_rcv()
510 state->peer_gen = new_gen - 1; in tipc_mon_rcv()
511 state->acked_gen = acked_gen; in tipc_mon_rcv()
512 state->synched = true; in tipc_mon_rcv()
515 if (more(acked_gen, state->acked_gen)) in tipc_mon_rcv()
516 state->acked_gen = acked_gen; in tipc_mon_rcv()
519 if (!more(new_gen, state->peer_gen) && !probing) in tipc_mon_rcv()
522 write_lock_bh(&mon->lock); in tipc_mon_rcv()
524 if (!peer || !peer->is_up) in tipc_mon_rcv()
528 peer->down_cnt = 0; in tipc_mon_rcv()
531 if (!more(new_gen, state->peer_gen)) in tipc_mon_rcv()
534 state->peer_gen = new_gen; in tipc_mon_rcv()
538 dom = peer->domain; in tipc_mon_rcv()
540 memcpy(&dom_bef, dom, dom->len); in tipc_mon_rcv()
543 if (!dom || (dom->len < new_dlen)) { in tipc_mon_rcv()
546 peer->domain = dom; in tipc_mon_rcv()
550 dom->len = new_dlen; in tipc_mon_rcv()
551 dom->gen = new_gen; in tipc_mon_rcv()
552 dom->member_cnt = new_member_cnt; in tipc_mon_rcv()
553 dom->up_map = mon_le64_to_cpu(arrv_dom->up_map); in tipc_mon_rcv()
555 dom->members[i] = mon_le32_to_cpu(arrv_dom->members[i]); in tipc_mon_rcv()
558 applied_bef = peer->applied; in tipc_mon_rcv()
563 write_unlock_bh(&mon->lock); in tipc_mon_rcv()
571 u16 gen = mon->dom_gen; in tipc_mon_prep()
576 dom->len = 0; in tipc_mon_prep()
581 if (likely(state->acked_gen == gen)) { in tipc_mon_prep()
584 dom->len = mon_cpu_to_le16(len); in tipc_mon_prep()
585 dom->gen = mon_cpu_to_le16(gen); in tipc_mon_prep()
586 dom->ack_gen = mon_cpu_to_le16(state->peer_gen); in tipc_mon_prep()
587 dom->member_cnt = 0; in tipc_mon_prep()
591 read_lock_bh(&mon->lock); in tipc_mon_prep()
592 len = mon_le16_to_cpu(mon->cache.len); in tipc_mon_prep()
594 memcpy(data, &mon->cache, len); in tipc_mon_prep()
595 read_unlock_bh(&mon->lock); in tipc_mon_prep()
596 dom->ack_gen = mon_cpu_to_le16(state->peer_gen); in tipc_mon_prep()
607 state->probing = false; in tipc_mon_get_state()
608 state->monitoring = true; in tipc_mon_get_state()
613 if (!state->probing && in tipc_mon_get_state()
614 (state->list_gen == mon->list_gen) && in tipc_mon_get_state()
615 (state->acked_gen == mon->dom_gen)) in tipc_mon_get_state()
618 read_lock_bh(&mon->lock); in tipc_mon_get_state()
621 state->probing = state->acked_gen != mon->dom_gen; in tipc_mon_get_state()
622 state->probing |= peer->down_cnt; in tipc_mon_get_state()
623 state->reset |= peer->down_cnt >= MAX_PEER_DOWN_EVENTS; in tipc_mon_get_state()
624 state->monitoring = peer->is_local; in tipc_mon_get_state()
625 state->monitoring |= peer->is_head; in tipc_mon_get_state()
626 state->list_gen = mon->list_gen; in tipc_mon_get_state()
628 read_unlock_bh(&mon->lock); in tipc_mon_get_state()
635 int best_member_cnt = dom_size(mon->peer_cnt) - 1; in mon_timeout()
637 write_lock_bh(&mon->lock); in mon_timeout()
638 self = mon->self; in mon_timeout()
639 if (self && (best_member_cnt != self->applied)) { in mon_timeout()
643 write_unlock_bh(&mon->lock); in mon_timeout()
644 mod_timer(&mon->timer, jiffies + mon->timer_intv); in mon_timeout()
654 if (tn->monitors[bearer_id]) in tipc_mon_create()
664 return -ENOMEM; in tipc_mon_create()
666 tn->monitors[bearer_id] = mon; in tipc_mon_create()
667 rwlock_init(&mon->lock); in tipc_mon_create()
668 mon->net = net; in tipc_mon_create()
669 mon->peer_cnt = 1; in tipc_mon_create()
670 mon->self = self; in tipc_mon_create()
671 self->domain = dom; in tipc_mon_create()
672 self->addr = tipc_own_addr(net); in tipc_mon_create()
673 self->is_up = true; in tipc_mon_create()
674 self->is_head = true; in tipc_mon_create()
675 INIT_LIST_HEAD(&self->list); in tipc_mon_create()
676 timer_setup(&mon->timer, mon_timeout, 0); in tipc_mon_create()
677 mon->timer_intv = msecs_to_jiffies(MON_TIMEOUT + (tn->random & 0xffff)); in tipc_mon_create()
678 mod_timer(&mon->timer, jiffies + mon->timer_intv); in tipc_mon_create()
693 write_lock_bh(&mon->lock); in tipc_mon_delete()
694 tn->monitors[bearer_id] = NULL; in tipc_mon_delete()
695 list_for_each_entry_safe(peer, tmp, &self->list, list) { in tipc_mon_delete()
696 list_del(&peer->list); in tipc_mon_delete()
697 hlist_del(&peer->hash); in tipc_mon_delete()
698 kfree(peer->domain); in tipc_mon_delete()
701 mon->self = NULL; in tipc_mon_delete()
702 write_unlock_bh(&mon->lock); in tipc_mon_delete()
703 timer_shutdown_sync(&mon->timer); in tipc_mon_delete()
704 kfree(self->domain); in tipc_mon_delete()
718 write_lock_bh(&mon->lock); in tipc_mon_reinit_self()
719 mon->self->addr = tipc_own_addr(net); in tipc_mon_reinit_self()
720 write_unlock_bh(&mon->lock); in tipc_mon_reinit_self()
729 return -EINVAL; in tipc_nl_monitor_set_threshold()
731 tn->mon_threshold = cluster_size; in tipc_nl_monitor_set_threshold()
740 return tn->mon_threshold; in tipc_nl_monitor_get_threshold()
746 struct tipc_mon_domain *dom = peer->domain; in __tipc_nl_add_monitor_peer()
750 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, in __tipc_nl_add_monitor_peer()
753 return -EMSGSIZE; in __tipc_nl_add_monitor_peer()
755 attrs = nla_nest_start_noflag(msg->skb, TIPC_NLA_MON_PEER); in __tipc_nl_add_monitor_peer()
759 if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEER_ADDR, peer->addr)) in __tipc_nl_add_monitor_peer()
761 if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEER_APPLIED, peer->applied)) in __tipc_nl_add_monitor_peer()
764 if (peer->is_up) in __tipc_nl_add_monitor_peer()
765 if (nla_put_flag(msg->skb, TIPC_NLA_MON_PEER_UP)) in __tipc_nl_add_monitor_peer()
767 if (peer->is_local) in __tipc_nl_add_monitor_peer()
768 if (nla_put_flag(msg->skb, TIPC_NLA_MON_PEER_LOCAL)) in __tipc_nl_add_monitor_peer()
770 if (peer->is_head) in __tipc_nl_add_monitor_peer()
771 if (nla_put_flag(msg->skb, TIPC_NLA_MON_PEER_HEAD)) in __tipc_nl_add_monitor_peer()
775 if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEER_DOMGEN, dom->gen)) in __tipc_nl_add_monitor_peer()
777 if (nla_put_u64_64bit(msg->skb, TIPC_NLA_MON_PEER_UPMAP, in __tipc_nl_add_monitor_peer()
778 dom->up_map, TIPC_NLA_MON_PEER_PAD)) in __tipc_nl_add_monitor_peer()
780 if (nla_put(msg->skb, TIPC_NLA_MON_PEER_MEMBERS, in __tipc_nl_add_monitor_peer()
781 dom->member_cnt * sizeof(u32), &dom->members)) in __tipc_nl_add_monitor_peer()
785 nla_nest_end(msg->skb, attrs); in __tipc_nl_add_monitor_peer()
786 genlmsg_end(msg->skb, hdr); in __tipc_nl_add_monitor_peer()
790 nla_nest_cancel(msg->skb, attrs); in __tipc_nl_add_monitor_peer()
792 genlmsg_cancel(msg->skb, hdr); in __tipc_nl_add_monitor_peer()
794 return -EMSGSIZE; in __tipc_nl_add_monitor_peer()
804 return -EINVAL; in tipc_nl_add_monitor_peer()
806 read_lock_bh(&mon->lock); in tipc_nl_add_monitor_peer()
807 peer = mon->self; in tipc_nl_add_monitor_peer()
810 if (peer->addr == *prev_node) in tipc_nl_add_monitor_peer()
816 *prev_node = peer->addr; in tipc_nl_add_monitor_peer()
817 read_unlock_bh(&mon->lock); in tipc_nl_add_monitor_peer()
818 return -EMSGSIZE; in tipc_nl_add_monitor_peer()
820 } while ((peer = peer_nxt(peer)) != mon->self); in tipc_nl_add_monitor_peer()
821 read_unlock_bh(&mon->lock); in tipc_nl_add_monitor_peer()
839 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, in __tipc_nl_add_monitor()
842 return -EMSGSIZE; in __tipc_nl_add_monitor()
844 attrs = nla_nest_start_noflag(msg->skb, TIPC_NLA_MON); in __tipc_nl_add_monitor()
848 read_lock_bh(&mon->lock); in __tipc_nl_add_monitor()
849 if (nla_put_u32(msg->skb, TIPC_NLA_MON_REF, bearer_id)) in __tipc_nl_add_monitor()
852 if (nla_put_flag(msg->skb, TIPC_NLA_MON_ACTIVE)) in __tipc_nl_add_monitor()
854 if (nla_put_string(msg->skb, TIPC_NLA_MON_BEARER_NAME, bearer_name)) in __tipc_nl_add_monitor()
856 if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEERCNT, mon->peer_cnt)) in __tipc_nl_add_monitor()
858 if (nla_put_u32(msg->skb, TIPC_NLA_MON_LISTGEN, mon->list_gen)) in __tipc_nl_add_monitor()
861 read_unlock_bh(&mon->lock); in __tipc_nl_add_monitor()
862 nla_nest_end(msg->skb, attrs); in __tipc_nl_add_monitor()
863 genlmsg_end(msg->skb, hdr); in __tipc_nl_add_monitor()
868 read_unlock_bh(&mon->lock); in __tipc_nl_add_monitor()
869 nla_nest_cancel(msg->skb, attrs); in __tipc_nl_add_monitor()
871 genlmsg_cancel(msg->skb, hdr); in __tipc_nl_add_monitor()
873 return -EMSGSIZE; in __tipc_nl_add_monitor()