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()
507 if (!state->synched) { in tipc_mon_rcv()
508 state->peer_gen = new_gen - 1; in tipc_mon_rcv()
509 state->acked_gen = acked_gen; in tipc_mon_rcv()
510 state->synched = true; in tipc_mon_rcv()
513 if (more(acked_gen, state->acked_gen)) in tipc_mon_rcv()
514 state->acked_gen = acked_gen; in tipc_mon_rcv()
517 if (!more(new_gen, state->peer_gen) && !probing) in tipc_mon_rcv()
520 write_lock_bh(&mon->lock); in tipc_mon_rcv()
522 if (!peer || !peer->is_up) in tipc_mon_rcv()
526 peer->down_cnt = 0; in tipc_mon_rcv()
529 if (!more(new_gen, state->peer_gen)) in tipc_mon_rcv()
532 state->peer_gen = new_gen; in tipc_mon_rcv()
536 dom = peer->domain; in tipc_mon_rcv()
538 memcpy(&dom_bef, dom, dom->len); in tipc_mon_rcv()
541 if (!dom || (dom->len < new_dlen)) { in tipc_mon_rcv()
544 peer->domain = dom; in tipc_mon_rcv()
548 dom->len = new_dlen; in tipc_mon_rcv()
549 dom->gen = new_gen; in tipc_mon_rcv()
550 dom->member_cnt = new_member_cnt; in tipc_mon_rcv()
551 dom->up_map = mon_le64_to_cpu(arrv_dom->up_map); in tipc_mon_rcv()
553 dom->members[i] = mon_le32_to_cpu(arrv_dom->members[i]); in tipc_mon_rcv()
556 applied_bef = peer->applied; in tipc_mon_rcv()
561 write_unlock_bh(&mon->lock); in tipc_mon_rcv()
569 u16 gen = mon->dom_gen; in tipc_mon_prep()
574 dom->len = 0; in tipc_mon_prep()
579 if (likely(state->acked_gen == gen)) { in tipc_mon_prep()
582 dom->len = mon_cpu_to_le16(len); in tipc_mon_prep()
583 dom->gen = mon_cpu_to_le16(gen); in tipc_mon_prep()
584 dom->ack_gen = mon_cpu_to_le16(state->peer_gen); in tipc_mon_prep()
585 dom->member_cnt = 0; in tipc_mon_prep()
589 read_lock_bh(&mon->lock); in tipc_mon_prep()
590 len = mon_le16_to_cpu(mon->cache.len); in tipc_mon_prep()
592 memcpy(data, &mon->cache, len); in tipc_mon_prep()
593 read_unlock_bh(&mon->lock); in tipc_mon_prep()
594 dom->ack_gen = mon_cpu_to_le16(state->peer_gen); in tipc_mon_prep()
605 state->probing = false; in tipc_mon_get_state()
606 state->monitoring = true; in tipc_mon_get_state()
611 if (!state->probing && in tipc_mon_get_state()
612 (state->list_gen == mon->list_gen) && in tipc_mon_get_state()
613 (state->acked_gen == mon->dom_gen)) in tipc_mon_get_state()
616 read_lock_bh(&mon->lock); in tipc_mon_get_state()
619 state->probing = state->acked_gen != mon->dom_gen; in tipc_mon_get_state()
620 state->probing |= peer->down_cnt; in tipc_mon_get_state()
621 state->reset |= peer->down_cnt >= MAX_PEER_DOWN_EVENTS; in tipc_mon_get_state()
622 state->monitoring = peer->is_local; in tipc_mon_get_state()
623 state->monitoring |= peer->is_head; in tipc_mon_get_state()
624 state->list_gen = mon->list_gen; in tipc_mon_get_state()
626 read_unlock_bh(&mon->lock); in tipc_mon_get_state()
633 int best_member_cnt = dom_size(mon->peer_cnt) - 1; in mon_timeout()
635 write_lock_bh(&mon->lock); in mon_timeout()
636 self = mon->self; in mon_timeout()
637 if (self && (best_member_cnt != self->applied)) { in mon_timeout()
641 write_unlock_bh(&mon->lock); in mon_timeout()
642 mod_timer(&mon->timer, jiffies + mon->timer_intv); in mon_timeout()
652 if (tn->monitors[bearer_id]) in tipc_mon_create()
662 return -ENOMEM; in tipc_mon_create()
664 tn->monitors[bearer_id] = mon; in tipc_mon_create()
665 rwlock_init(&mon->lock); in tipc_mon_create()
666 mon->net = net; in tipc_mon_create()
667 mon->peer_cnt = 1; in tipc_mon_create()
668 mon->self = self; in tipc_mon_create()
669 self->domain = dom; in tipc_mon_create()
670 self->addr = tipc_own_addr(net); in tipc_mon_create()
671 self->is_up = true; in tipc_mon_create()
672 self->is_head = true; in tipc_mon_create()
673 INIT_LIST_HEAD(&self->list); in tipc_mon_create()
674 timer_setup(&mon->timer, mon_timeout, 0); in tipc_mon_create()
675 mon->timer_intv = msecs_to_jiffies(MON_TIMEOUT + (tn->random & 0xffff)); in tipc_mon_create()
676 mod_timer(&mon->timer, jiffies + mon->timer_intv); in tipc_mon_create()
691 write_lock_bh(&mon->lock); in tipc_mon_delete()
692 tn->monitors[bearer_id] = NULL; in tipc_mon_delete()
693 list_for_each_entry_safe(peer, tmp, &self->list, list) { in tipc_mon_delete()
694 list_del(&peer->list); in tipc_mon_delete()
695 hlist_del(&peer->hash); in tipc_mon_delete()
696 kfree(peer->domain); in tipc_mon_delete()
699 mon->self = NULL; in tipc_mon_delete()
700 write_unlock_bh(&mon->lock); in tipc_mon_delete()
701 del_timer_sync(&mon->timer); in tipc_mon_delete()
702 kfree(self->domain); in tipc_mon_delete()
716 write_lock_bh(&mon->lock); in tipc_mon_reinit_self()
717 mon->self->addr = tipc_own_addr(net); in tipc_mon_reinit_self()
718 write_unlock_bh(&mon->lock); in tipc_mon_reinit_self()
727 return -EINVAL; in tipc_nl_monitor_set_threshold()
729 tn->mon_threshold = cluster_size; in tipc_nl_monitor_set_threshold()
738 return tn->mon_threshold; in tipc_nl_monitor_get_threshold()
744 struct tipc_mon_domain *dom = peer->domain; in __tipc_nl_add_monitor_peer()
748 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, in __tipc_nl_add_monitor_peer()
751 return -EMSGSIZE; in __tipc_nl_add_monitor_peer()
753 attrs = nla_nest_start_noflag(msg->skb, TIPC_NLA_MON_PEER); in __tipc_nl_add_monitor_peer()
757 if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEER_ADDR, peer->addr)) in __tipc_nl_add_monitor_peer()
759 if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEER_APPLIED, peer->applied)) in __tipc_nl_add_monitor_peer()
762 if (peer->is_up) in __tipc_nl_add_monitor_peer()
763 if (nla_put_flag(msg->skb, TIPC_NLA_MON_PEER_UP)) in __tipc_nl_add_monitor_peer()
765 if (peer->is_local) in __tipc_nl_add_monitor_peer()
766 if (nla_put_flag(msg->skb, TIPC_NLA_MON_PEER_LOCAL)) in __tipc_nl_add_monitor_peer()
768 if (peer->is_head) in __tipc_nl_add_monitor_peer()
769 if (nla_put_flag(msg->skb, TIPC_NLA_MON_PEER_HEAD)) in __tipc_nl_add_monitor_peer()
773 if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEER_DOMGEN, dom->gen)) in __tipc_nl_add_monitor_peer()
775 if (nla_put_u64_64bit(msg->skb, TIPC_NLA_MON_PEER_UPMAP, in __tipc_nl_add_monitor_peer()
776 dom->up_map, TIPC_NLA_MON_PEER_PAD)) in __tipc_nl_add_monitor_peer()
778 if (nla_put(msg->skb, TIPC_NLA_MON_PEER_MEMBERS, in __tipc_nl_add_monitor_peer()
779 dom->member_cnt * sizeof(u32), &dom->members)) in __tipc_nl_add_monitor_peer()
783 nla_nest_end(msg->skb, attrs); in __tipc_nl_add_monitor_peer()
784 genlmsg_end(msg->skb, hdr); in __tipc_nl_add_monitor_peer()
788 nla_nest_cancel(msg->skb, attrs); in __tipc_nl_add_monitor_peer()
790 genlmsg_cancel(msg->skb, hdr); in __tipc_nl_add_monitor_peer()
792 return -EMSGSIZE; in __tipc_nl_add_monitor_peer()
802 return -EINVAL; in tipc_nl_add_monitor_peer()
804 read_lock_bh(&mon->lock); in tipc_nl_add_monitor_peer()
805 peer = mon->self; in tipc_nl_add_monitor_peer()
808 if (peer->addr == *prev_node) in tipc_nl_add_monitor_peer()
814 *prev_node = peer->addr; in tipc_nl_add_monitor_peer()
815 read_unlock_bh(&mon->lock); in tipc_nl_add_monitor_peer()
816 return -EMSGSIZE; in tipc_nl_add_monitor_peer()
818 } while ((peer = peer_nxt(peer)) != mon->self); in tipc_nl_add_monitor_peer()
819 read_unlock_bh(&mon->lock); in tipc_nl_add_monitor_peer()
837 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, in __tipc_nl_add_monitor()
840 return -EMSGSIZE; in __tipc_nl_add_monitor()
842 attrs = nla_nest_start_noflag(msg->skb, TIPC_NLA_MON); in __tipc_nl_add_monitor()
846 read_lock_bh(&mon->lock); in __tipc_nl_add_monitor()
847 if (nla_put_u32(msg->skb, TIPC_NLA_MON_REF, bearer_id)) in __tipc_nl_add_monitor()
850 if (nla_put_flag(msg->skb, TIPC_NLA_MON_ACTIVE)) in __tipc_nl_add_monitor()
852 if (nla_put_string(msg->skb, TIPC_NLA_MON_BEARER_NAME, bearer_name)) in __tipc_nl_add_monitor()
854 if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEERCNT, mon->peer_cnt)) in __tipc_nl_add_monitor()
856 if (nla_put_u32(msg->skb, TIPC_NLA_MON_LISTGEN, mon->list_gen)) in __tipc_nl_add_monitor()
859 read_unlock_bh(&mon->lock); in __tipc_nl_add_monitor()
860 nla_nest_end(msg->skb, attrs); in __tipc_nl_add_monitor()
861 genlmsg_end(msg->skb, hdr); in __tipc_nl_add_monitor()
866 read_unlock_bh(&mon->lock); in __tipc_nl_add_monitor()
867 nla_nest_cancel(msg->skb, attrs); in __tipc_nl_add_monitor()
869 genlmsg_cancel(msg->skb, hdr); in __tipc_nl_add_monitor()
871 return -EMSGSIZE; in __tipc_nl_add_monitor()