Lines Matching +full:0 +full:- +full:mon
73 * @down_cnt: - numbers of other peers which have reported this on lost
102 return tipc_net(net)->monitors[bearer_id]; in tipc_monitor()
111 return ((void *)&dom->members - (void *)dom) + (mcnt * sizeof(u32)); in dom_rec_len()
118 int i = 0; in dom_size()
138 return list_last_entry(&peer->list, struct tipc_peer, list); in peer_prev()
143 return list_first_entry(&peer->list, struct tipc_peer, list); in peer_nxt()
148 while (!peer->is_head) in peer_head()
153 static struct tipc_peer *get_peer(struct tipc_monitor *mon, u32 addr) in get_peer() argument
158 hlist_for_each_entry(peer, &mon->peers[thash], hash) { in get_peer()
159 if (peer->addr == addr) in get_peer()
167 struct tipc_monitor *mon = tipc_monitor(net, bearer_id); in get_self() local
169 return mon->self; in get_self()
172 static inline bool tipc_mon_is_active(struct net *net, struct tipc_monitor *mon) in tipc_mon_is_active() argument
176 return mon->peer_cnt > tn->mon_threshold; in tipc_mon_is_active()
179 /* mon_identify_lost_members() : - identify amd mark potentially lost members
186 struct tipc_mon_domain *dom_aft = peer->domain; in mon_identify_lost_members()
187 int applied_aft = peer->applied; in mon_identify_lost_members()
190 for (i = 0; i < applied_bef; i++) { in mon_identify_lost_members()
194 if (!member->is_up || !map_get(dom_bef->up_map, i)) in mon_identify_lost_members()
198 if (member->is_local) in mon_identify_lost_members()
203 member->down_cnt = 1; in mon_identify_lost_members()
208 if (!map_get(dom_aft->up_map, i)) in mon_identify_lost_members()
209 member->down_cnt++; in mon_identify_lost_members()
215 static void mon_apply_domain(struct tipc_monitor *mon, in mon_apply_domain() argument
218 struct tipc_mon_domain *dom = peer->domain; in mon_apply_domain()
223 if (!dom || !peer->is_up) in mon_apply_domain()
227 peer->applied = 0; in mon_apply_domain()
229 for (i = 0; i < dom->member_cnt; i++) { in mon_apply_domain()
230 addr = dom->members[i]; in mon_apply_domain()
231 if (addr != member->addr) in mon_apply_domain()
233 peer->applied++; in mon_apply_domain()
240 static void mon_update_local_domain(struct tipc_monitor *mon) in mon_update_local_domain() argument
242 struct tipc_peer *self = mon->self; in mon_update_local_domain()
243 struct tipc_mon_domain *cache = &mon->cache; in mon_update_local_domain()
244 struct tipc_mon_domain *dom = self->domain; in mon_update_local_domain()
246 u64 prev_up_map = dom->up_map; in mon_update_local_domain()
251 member_cnt = dom_size(mon->peer_cnt) - 1; in mon_update_local_domain()
252 self->applied = member_cnt; in mon_update_local_domain()
255 dom->len = dom_rec_len(dom, member_cnt); in mon_update_local_domain()
256 diff = dom->member_cnt != member_cnt; in mon_update_local_domain()
257 dom->member_cnt = member_cnt; in mon_update_local_domain()
258 for (i = 0; i < member_cnt; i++) { in mon_update_local_domain()
260 diff |= dom->members[i] != peer->addr; in mon_update_local_domain()
261 dom->members[i] = peer->addr; in mon_update_local_domain()
262 map_set(&dom->up_map, i, peer->is_up); in mon_update_local_domain()
263 cache->members[i] = htonl(peer->addr); in mon_update_local_domain()
265 diff |= dom->up_map != prev_up_map; in mon_update_local_domain()
268 dom->gen = ++mon->dom_gen; in mon_update_local_domain()
269 cache->len = htons(dom->len); in mon_update_local_domain()
270 cache->gen = htons(dom->gen); in mon_update_local_domain()
271 cache->member_cnt = htons(member_cnt); in mon_update_local_domain()
272 cache->up_map = cpu_to_be64(dom->up_map); in mon_update_local_domain()
273 mon_apply_domain(mon, self); in mon_update_local_domain()
278 static void mon_update_neighbors(struct tipc_monitor *mon, in mon_update_neighbors() argument
283 dz = dom_size(mon->peer_cnt); in mon_update_neighbors()
284 for (i = 0; i < dz; i++) { in mon_update_neighbors()
285 mon_apply_domain(mon, peer); in mon_update_neighbors()
294 static void mon_assign_roles(struct tipc_monitor *mon, struct tipc_peer *head) in mon_assign_roles() argument
297 struct tipc_peer *self = mon->self; in mon_assign_roles()
298 int i = 0; in mon_assign_roles()
301 peer->is_local = false; in mon_assign_roles()
304 if (i++ < head->applied) { in mon_assign_roles()
305 peer->is_head = false; in mon_assign_roles()
307 peer->is_local = true; in mon_assign_roles()
311 if (!peer->is_up) in mon_assign_roles()
313 if (peer->is_head) in mon_assign_roles()
316 head->is_head = true; in mon_assign_roles()
317 i = 0; in mon_assign_roles()
319 mon->list_gen++; in mon_assign_roles()
324 struct tipc_monitor *mon = tipc_monitor(net, bearer_id); in tipc_mon_remove_peer() local
328 if (!mon) in tipc_mon_remove_peer()
332 write_lock_bh(&mon->lock); in tipc_mon_remove_peer()
333 peer = get_peer(mon, addr); in tipc_mon_remove_peer()
337 list_del(&peer->list); in tipc_mon_remove_peer()
338 hlist_del(&peer->hash); in tipc_mon_remove_peer()
339 kfree(peer->domain); in tipc_mon_remove_peer()
341 mon->peer_cnt--; in tipc_mon_remove_peer()
344 mon_update_local_domain(mon); in tipc_mon_remove_peer()
345 mon_update_neighbors(mon, prev); in tipc_mon_remove_peer()
347 /* Revert to full-mesh monitoring if we reach threshold */ in tipc_mon_remove_peer()
348 if (!tipc_mon_is_active(net, mon)) { in tipc_mon_remove_peer()
349 list_for_each_entry(peer, &self->list, list) { in tipc_mon_remove_peer()
350 kfree(peer->domain); in tipc_mon_remove_peer()
351 peer->domain = NULL; in tipc_mon_remove_peer()
352 peer->applied = 0; in tipc_mon_remove_peer()
355 mon_assign_roles(mon, head); in tipc_mon_remove_peer()
357 write_unlock_bh(&mon->lock); in tipc_mon_remove_peer()
360 static bool tipc_mon_add_peer(struct tipc_monitor *mon, u32 addr, in tipc_mon_add_peer() argument
363 struct tipc_peer *self = mon->self; in tipc_mon_add_peer()
370 p->addr = addr; in tipc_mon_add_peer()
373 INIT_LIST_HEAD(&p->list); in tipc_mon_add_peer()
374 hlist_add_head(&p->hash, &mon->peers[tipc_hashfn(addr)]); in tipc_mon_add_peer()
378 list_for_each_entry(cur, &self->list, list) { in tipc_mon_add_peer()
379 if ((addr > prev->addr) && (addr < cur->addr)) in tipc_mon_add_peer()
381 if (((addr < cur->addr) || (addr > prev->addr)) && in tipc_mon_add_peer()
382 (prev->addr > cur->addr)) in tipc_mon_add_peer()
386 list_add_tail(&p->list, &cur->list); in tipc_mon_add_peer()
387 mon->peer_cnt++; in tipc_mon_add_peer()
388 mon_update_neighbors(mon, p); in tipc_mon_add_peer()
394 struct tipc_monitor *mon = tipc_monitor(net, bearer_id); in tipc_mon_peer_up() local
398 write_lock_bh(&mon->lock); in tipc_mon_peer_up()
399 peer = get_peer(mon, addr); in tipc_mon_peer_up()
400 if (!peer && !tipc_mon_add_peer(mon, addr, &peer)) in tipc_mon_peer_up()
402 peer->is_up = true; in tipc_mon_peer_up()
405 mon_update_local_domain(mon); in tipc_mon_peer_up()
406 mon_assign_roles(mon, head); in tipc_mon_peer_up()
408 write_unlock_bh(&mon->lock); in tipc_mon_peer_up()
413 struct tipc_monitor *mon = tipc_monitor(net, bearer_id); in tipc_mon_peer_down() local
419 if (!mon) in tipc_mon_peer_down()
423 write_lock_bh(&mon->lock); in tipc_mon_peer_down()
424 peer = get_peer(mon, addr); in tipc_mon_peer_down()
426 pr_warn("Mon: unknown link %x/%u DOWN\n", addr, bearer_id); in tipc_mon_peer_down()
429 applied = peer->applied; in tipc_mon_peer_down()
430 peer->applied = 0; in tipc_mon_peer_down()
431 dom = peer->domain; in tipc_mon_peer_down()
432 peer->domain = NULL; in tipc_mon_peer_down()
433 if (peer->is_head) in tipc_mon_peer_down()
436 peer->is_up = false; in tipc_mon_peer_down()
437 peer->is_head = false; in tipc_mon_peer_down()
438 peer->is_local = false; in tipc_mon_peer_down()
439 peer->down_cnt = 0; in tipc_mon_peer_down()
442 mon_update_local_domain(mon); in tipc_mon_peer_down()
443 mon_assign_roles(mon, head); in tipc_mon_peer_down()
445 write_unlock_bh(&mon->lock); in tipc_mon_peer_down()
448 /* tipc_mon_rcv - process monitor domain event message
453 struct tipc_monitor *mon = tipc_monitor(net, bearer_id); in tipc_mon_rcv() local
458 u16 new_member_cnt = ntohs(arrv_dom->member_cnt); in tipc_mon_rcv()
460 u16 new_gen = ntohs(arrv_dom->gen); in tipc_mon_rcv()
461 u16 acked_gen = ntohs(arrv_dom->ack_gen); in tipc_mon_rcv()
462 bool probing = state->probing; in tipc_mon_rcv()
465 state->probing = false; in tipc_mon_rcv()
470 if (dlen < dom_rec_len(arrv_dom, 0)) in tipc_mon_rcv()
474 if ((dlen < new_dlen) || ntohs(arrv_dom->len) != new_dlen) in tipc_mon_rcv()
478 if (!state->synched) { in tipc_mon_rcv()
479 state->peer_gen = new_gen - 1; in tipc_mon_rcv()
480 state->acked_gen = acked_gen; in tipc_mon_rcv()
481 state->synched = true; in tipc_mon_rcv()
484 if (more(acked_gen, state->acked_gen)) in tipc_mon_rcv()
485 state->acked_gen = acked_gen; in tipc_mon_rcv()
488 if (!more(new_gen, state->peer_gen) && !probing) in tipc_mon_rcv()
491 write_lock_bh(&mon->lock); in tipc_mon_rcv()
492 peer = get_peer(mon, addr); in tipc_mon_rcv()
493 if (!peer || !peer->is_up) in tipc_mon_rcv()
497 peer->down_cnt = 0; in tipc_mon_rcv()
500 if (!more(new_gen, state->peer_gen)) in tipc_mon_rcv()
503 state->peer_gen = new_gen; in tipc_mon_rcv()
506 dom_bef.member_cnt = 0; in tipc_mon_rcv()
507 dom = peer->domain; in tipc_mon_rcv()
509 memcpy(&dom_bef, dom, dom->len); in tipc_mon_rcv()
512 if (!dom || (dom->len < new_dlen)) { in tipc_mon_rcv()
515 peer->domain = dom; in tipc_mon_rcv()
519 dom->len = new_dlen; in tipc_mon_rcv()
520 dom->gen = new_gen; in tipc_mon_rcv()
521 dom->member_cnt = new_member_cnt; in tipc_mon_rcv()
522 dom->up_map = be64_to_cpu(arrv_dom->up_map); in tipc_mon_rcv()
523 for (i = 0; i < new_member_cnt; i++) in tipc_mon_rcv()
524 dom->members[i] = ntohl(arrv_dom->members[i]); in tipc_mon_rcv()
527 applied_bef = peer->applied; in tipc_mon_rcv()
528 mon_apply_domain(mon, peer); in tipc_mon_rcv()
530 mon_assign_roles(mon, peer_head(peer)); in tipc_mon_rcv()
532 write_unlock_bh(&mon->lock); in tipc_mon_rcv()
538 struct tipc_monitor *mon = tipc_monitor(net, bearer_id); in tipc_mon_prep() local
540 u16 gen = mon->dom_gen; in tipc_mon_prep()
544 if (!tipc_mon_is_active(net, mon)) { in tipc_mon_prep()
545 dom->len = 0; in tipc_mon_prep()
550 if (likely(state->acked_gen == gen)) { in tipc_mon_prep()
551 len = dom_rec_len(dom, 0); in tipc_mon_prep()
553 dom->len = htons(len); in tipc_mon_prep()
554 dom->gen = htons(gen); in tipc_mon_prep()
555 dom->ack_gen = htons(state->peer_gen); in tipc_mon_prep()
556 dom->member_cnt = 0; in tipc_mon_prep()
560 read_lock_bh(&mon->lock); in tipc_mon_prep()
561 len = ntohs(mon->cache.len); in tipc_mon_prep()
563 memcpy(data, &mon->cache, len); in tipc_mon_prep()
564 read_unlock_bh(&mon->lock); in tipc_mon_prep()
565 dom->ack_gen = htons(state->peer_gen); in tipc_mon_prep()
572 struct tipc_monitor *mon = tipc_monitor(net, bearer_id); in tipc_mon_get_state() local
575 if (!tipc_mon_is_active(net, mon)) { in tipc_mon_get_state()
576 state->probing = false; in tipc_mon_get_state()
577 state->monitoring = true; in tipc_mon_get_state()
582 if (!state->probing && in tipc_mon_get_state()
583 (state->list_gen == mon->list_gen) && in tipc_mon_get_state()
584 (state->acked_gen == mon->dom_gen)) in tipc_mon_get_state()
587 read_lock_bh(&mon->lock); in tipc_mon_get_state()
588 peer = get_peer(mon, addr); in tipc_mon_get_state()
590 state->probing = state->acked_gen != mon->dom_gen; in tipc_mon_get_state()
591 state->probing |= peer->down_cnt; in tipc_mon_get_state()
592 state->reset |= peer->down_cnt >= MAX_PEER_DOWN_EVENTS; in tipc_mon_get_state()
593 state->monitoring = peer->is_local; in tipc_mon_get_state()
594 state->monitoring |= peer->is_head; in tipc_mon_get_state()
595 state->list_gen = mon->list_gen; in tipc_mon_get_state()
597 read_unlock_bh(&mon->lock); in tipc_mon_get_state()
602 struct tipc_monitor *mon = from_timer(mon, t, timer); in mon_timeout() local
604 int best_member_cnt = dom_size(mon->peer_cnt) - 1; in mon_timeout()
606 write_lock_bh(&mon->lock); in mon_timeout()
607 self = mon->self; in mon_timeout()
608 if (self && (best_member_cnt != self->applied)) { in mon_timeout()
609 mon_update_local_domain(mon); in mon_timeout()
610 mon_assign_roles(mon, self); in mon_timeout()
612 write_unlock_bh(&mon->lock); in mon_timeout()
613 mod_timer(&mon->timer, jiffies + mon->timer_intv); in mon_timeout()
619 struct tipc_monitor *mon; in tipc_mon_create() local
623 if (tn->monitors[bearer_id]) in tipc_mon_create()
624 return 0; in tipc_mon_create()
626 mon = kzalloc(sizeof(*mon), GFP_ATOMIC); in tipc_mon_create()
629 if (!mon || !self || !dom) { in tipc_mon_create()
630 kfree(mon); in tipc_mon_create()
633 return -ENOMEM; in tipc_mon_create()
635 tn->monitors[bearer_id] = mon; in tipc_mon_create()
636 rwlock_init(&mon->lock); in tipc_mon_create()
637 mon->net = net; in tipc_mon_create()
638 mon->peer_cnt = 1; in tipc_mon_create()
639 mon->self = self; in tipc_mon_create()
640 self->domain = dom; in tipc_mon_create()
641 self->addr = tipc_own_addr(net); in tipc_mon_create()
642 self->is_up = true; in tipc_mon_create()
643 self->is_head = true; in tipc_mon_create()
644 INIT_LIST_HEAD(&self->list); in tipc_mon_create()
645 timer_setup(&mon->timer, mon_timeout, 0); in tipc_mon_create()
646 mon->timer_intv = msecs_to_jiffies(MON_TIMEOUT + (tn->random & 0xffff)); in tipc_mon_create()
647 mod_timer(&mon->timer, jiffies + mon->timer_intv); in tipc_mon_create()
648 return 0; in tipc_mon_create()
654 struct tipc_monitor *mon = tipc_monitor(net, bearer_id); in tipc_mon_delete() local
658 if (!mon) in tipc_mon_delete()
662 write_lock_bh(&mon->lock); in tipc_mon_delete()
663 tn->monitors[bearer_id] = NULL; in tipc_mon_delete()
664 list_for_each_entry_safe(peer, tmp, &self->list, list) { in tipc_mon_delete()
665 list_del(&peer->list); in tipc_mon_delete()
666 hlist_del(&peer->hash); in tipc_mon_delete()
667 kfree(peer->domain); in tipc_mon_delete()
670 mon->self = NULL; in tipc_mon_delete()
671 write_unlock_bh(&mon->lock); in tipc_mon_delete()
672 del_timer_sync(&mon->timer); in tipc_mon_delete()
673 kfree(self->domain); in tipc_mon_delete()
675 kfree(mon); in tipc_mon_delete()
680 struct tipc_monitor *mon; in tipc_mon_reinit_self() local
683 for (bearer_id = 0; bearer_id < MAX_BEARERS; bearer_id++) { in tipc_mon_reinit_self()
684 mon = tipc_monitor(net, bearer_id); in tipc_mon_reinit_self()
685 if (!mon) in tipc_mon_reinit_self()
687 write_lock_bh(&mon->lock); in tipc_mon_reinit_self()
688 mon->self->addr = tipc_own_addr(net); in tipc_mon_reinit_self()
689 write_unlock_bh(&mon->lock); in tipc_mon_reinit_self()
698 return -EINVAL; in tipc_nl_monitor_set_threshold()
700 tn->mon_threshold = cluster_size; in tipc_nl_monitor_set_threshold()
702 return 0; in tipc_nl_monitor_set_threshold()
709 return tn->mon_threshold; in tipc_nl_monitor_get_threshold()
715 struct tipc_mon_domain *dom = peer->domain; in __tipc_nl_add_monitor_peer()
719 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, in __tipc_nl_add_monitor_peer()
722 return -EMSGSIZE; in __tipc_nl_add_monitor_peer()
724 attrs = nla_nest_start_noflag(msg->skb, TIPC_NLA_MON_PEER); in __tipc_nl_add_monitor_peer()
728 if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEER_ADDR, peer->addr)) in __tipc_nl_add_monitor_peer()
730 if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEER_APPLIED, peer->applied)) in __tipc_nl_add_monitor_peer()
733 if (peer->is_up) in __tipc_nl_add_monitor_peer()
734 if (nla_put_flag(msg->skb, TIPC_NLA_MON_PEER_UP)) in __tipc_nl_add_monitor_peer()
736 if (peer->is_local) in __tipc_nl_add_monitor_peer()
737 if (nla_put_flag(msg->skb, TIPC_NLA_MON_PEER_LOCAL)) in __tipc_nl_add_monitor_peer()
739 if (peer->is_head) in __tipc_nl_add_monitor_peer()
740 if (nla_put_flag(msg->skb, TIPC_NLA_MON_PEER_HEAD)) in __tipc_nl_add_monitor_peer()
744 if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEER_DOMGEN, dom->gen)) in __tipc_nl_add_monitor_peer()
746 if (nla_put_u64_64bit(msg->skb, TIPC_NLA_MON_PEER_UPMAP, in __tipc_nl_add_monitor_peer()
747 dom->up_map, TIPC_NLA_MON_PEER_PAD)) in __tipc_nl_add_monitor_peer()
749 if (nla_put(msg->skb, TIPC_NLA_MON_PEER_MEMBERS, in __tipc_nl_add_monitor_peer()
750 dom->member_cnt * sizeof(u32), &dom->members)) in __tipc_nl_add_monitor_peer()
754 nla_nest_end(msg->skb, attrs); in __tipc_nl_add_monitor_peer()
755 genlmsg_end(msg->skb, hdr); in __tipc_nl_add_monitor_peer()
756 return 0; in __tipc_nl_add_monitor_peer()
759 nla_nest_cancel(msg->skb, attrs); in __tipc_nl_add_monitor_peer()
761 genlmsg_cancel(msg->skb, hdr); in __tipc_nl_add_monitor_peer()
763 return -EMSGSIZE; in __tipc_nl_add_monitor_peer()
769 struct tipc_monitor *mon = tipc_monitor(net, bearer_id); in tipc_nl_add_monitor_peer() local
772 if (!mon) in tipc_nl_add_monitor_peer()
773 return -EINVAL; in tipc_nl_add_monitor_peer()
775 read_lock_bh(&mon->lock); in tipc_nl_add_monitor_peer()
776 peer = mon->self; in tipc_nl_add_monitor_peer()
779 if (peer->addr == *prev_node) in tipc_nl_add_monitor_peer()
780 *prev_node = 0; in tipc_nl_add_monitor_peer()
785 *prev_node = peer->addr; in tipc_nl_add_monitor_peer()
786 read_unlock_bh(&mon->lock); in tipc_nl_add_monitor_peer()
787 return -EMSGSIZE; in tipc_nl_add_monitor_peer()
789 } while ((peer = peer_nxt(peer)) != mon->self); in tipc_nl_add_monitor_peer()
790 read_unlock_bh(&mon->lock); in tipc_nl_add_monitor_peer()
792 return 0; in tipc_nl_add_monitor_peer()
798 struct tipc_monitor *mon = tipc_monitor(net, bearer_id); in __tipc_nl_add_monitor() local
805 if (ret || !mon) in __tipc_nl_add_monitor()
806 return 0; in __tipc_nl_add_monitor()
808 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, in __tipc_nl_add_monitor()
811 return -EMSGSIZE; in __tipc_nl_add_monitor()
813 attrs = nla_nest_start_noflag(msg->skb, TIPC_NLA_MON); in __tipc_nl_add_monitor()
817 read_lock_bh(&mon->lock); in __tipc_nl_add_monitor()
818 if (nla_put_u32(msg->skb, TIPC_NLA_MON_REF, bearer_id)) in __tipc_nl_add_monitor()
820 if (tipc_mon_is_active(net, mon)) in __tipc_nl_add_monitor()
821 if (nla_put_flag(msg->skb, TIPC_NLA_MON_ACTIVE)) in __tipc_nl_add_monitor()
823 if (nla_put_string(msg->skb, TIPC_NLA_MON_BEARER_NAME, bearer_name)) in __tipc_nl_add_monitor()
825 if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEERCNT, mon->peer_cnt)) in __tipc_nl_add_monitor()
827 if (nla_put_u32(msg->skb, TIPC_NLA_MON_LISTGEN, mon->list_gen)) in __tipc_nl_add_monitor()
830 read_unlock_bh(&mon->lock); in __tipc_nl_add_monitor()
831 nla_nest_end(msg->skb, attrs); in __tipc_nl_add_monitor()
832 genlmsg_end(msg->skb, hdr); in __tipc_nl_add_monitor()
834 return 0; in __tipc_nl_add_monitor()
837 read_unlock_bh(&mon->lock); in __tipc_nl_add_monitor()
838 nla_nest_cancel(msg->skb, attrs); in __tipc_nl_add_monitor()
840 genlmsg_cancel(msg->skb, hdr); in __tipc_nl_add_monitor()
842 return -EMSGSIZE; in __tipc_nl_add_monitor()