Lines Matching refs:tp_vars
134 * @tp_vars: the private data of the current TP meter session
142 static void batadv_tp_update_cwnd(struct batadv_tp_vars *tp_vars, u32 mss)
144 spin_lock_bh(&tp_vars->cwnd_lock);
147 if (tp_vars->cwnd <= tp_vars->ss_threshold) {
148 tp_vars->dec_cwnd = 0;
149 tp_vars->cwnd = batadv_tp_cwnd(tp_vars->cwnd, mss, mss);
150 spin_unlock_bh(&tp_vars->cwnd_lock);
155 tp_vars->dec_cwnd += max_t(u32, 1U << 3,
156 ((mss * mss) << 6) / (tp_vars->cwnd << 3));
157 if (tp_vars->dec_cwnd < (mss << 3)) {
158 spin_unlock_bh(&tp_vars->cwnd_lock);
162 tp_vars->cwnd = batadv_tp_cwnd(tp_vars->cwnd, mss, mss);
163 tp_vars->dec_cwnd = 0;
165 spin_unlock_bh(&tp_vars->cwnd_lock);
170 * @tp_vars: the private data of the current TP meter session
173 static void batadv_tp_update_rto(struct batadv_tp_vars *tp_vars,
184 if (tp_vars->srtt != 0) {
185 m -= (tp_vars->srtt >> 3); /* m is now error in rtt est */
186 tp_vars->srtt += m; /* rtt = 7/8 srtt + 1/8 new */
190 m -= (tp_vars->rttvar >> 2);
191 tp_vars->rttvar += m; /* mdev ~= 3/4 rttvar + 1/4 new */
194 tp_vars->srtt = m << 3; /* take the measured time to be srtt */
195 tp_vars->rttvar = m << 1; /* new_rtt / 2 */
201 tp_vars->rto = (tp_vars->srtt >> 3) + tp_vars->rttvar;
252 * batadv_tp_list_find() - find a tp_vars object in the global list
256 * Look for a tp_vars object matching dst as end_point and return it after
259 * Return: matching tp_vars or NULL when no tp_vars with @dst was found
264 struct batadv_tp_vars *pos, *tp_vars = NULL;
278 tp_vars = pos;
283 return tp_vars;
287 * batadv_tp_list_find_session() - find tp_vars session object in the global
293 * Look for a tp_vars object matching dst as end_point, session as tp meter
297 * Return: matching tp_vars or NULL when no tp_vars was found
303 struct batadv_tp_vars *pos, *tp_vars = NULL;
320 tp_vars = pos;
325 return tp_vars;
335 struct batadv_tp_vars *tp_vars;
338 tp_vars = container_of(ref, struct batadv_tp_vars, refcount);
343 spin_lock_bh(&tp_vars->unacked_lock);
344 list_for_each_entry_safe(un, safe, &tp_vars->unacked_list, list) {
348 spin_unlock_bh(&tp_vars->unacked_lock);
350 kfree_rcu(tp_vars, rcu);
356 * @tp_vars: the private data of the current TP meter session to be free'd
358 static void batadv_tp_vars_put(struct batadv_tp_vars *tp_vars)
360 if (!tp_vars)
363 kref_put(&tp_vars->refcount, batadv_tp_vars_release);
369 * @tp_vars: the private data of the current TP meter session to cleanup
372 struct batadv_tp_vars *tp_vars)
374 cancel_delayed_work(&tp_vars->finish_work);
376 spin_lock_bh(&tp_vars->bat_priv->tp_list_lock);
377 hlist_del_rcu(&tp_vars->list);
378 spin_unlock_bh(&tp_vars->bat_priv->tp_list_lock);
381 batadv_tp_vars_put(tp_vars);
383 atomic_dec(&tp_vars->bat_priv->tp_num);
386 del_timer_sync(&tp_vars->timer);
392 del_timer(&tp_vars->timer);
393 batadv_tp_vars_put(tp_vars);
399 * @tp_vars: the private data of the current TP meter session
402 struct batadv_tp_vars *tp_vars)
408 tp_vars->other_end, tp_vars->reason);
412 tp_vars->srtt >> 3, tp_vars->rttvar >> 2, tp_vars->rto);
416 tp_vars->cwnd, tp_vars->ss_threshold);
418 session_cookie = batadv_tp_session_cookie(tp_vars->session,
419 tp_vars->icmp_uid);
421 batadv_tp_batctl_notify(tp_vars->reason,
422 tp_vars->other_end,
424 tp_vars->start_time,
425 atomic64_read(&tp_vars->tot_sent),
431 * @tp_vars: the private data of the current TP meter session
434 static void batadv_tp_sender_shutdown(struct batadv_tp_vars *tp_vars,
437 if (!atomic_dec_and_test(&tp_vars->sending))
440 tp_vars->reason = reason;
445 * @work: delayed work reference of the related tp_vars
450 struct batadv_tp_vars *tp_vars;
453 tp_vars = container_of(delayed_work, struct batadv_tp_vars,
456 batadv_tp_sender_shutdown(tp_vars, BATADV_TP_REASON_COMPLETE);
461 * @tp_vars: the private TP meter data for this session
463 * Reschedule the timer using tp_vars->rto as delay
465 static void batadv_tp_reset_sender_timer(struct batadv_tp_vars *tp_vars)
470 if (unlikely(atomic_read(&tp_vars->sending) == 0))
474 mod_timer(&tp_vars->timer, jiffies + msecs_to_jiffies(tp_vars->rto));
479 * @t: address to timer_list inside tp_vars
487 struct batadv_tp_vars *tp_vars = from_timer(tp_vars, t, timer);
488 struct batadv_priv *bat_priv = tp_vars->bat_priv;
490 if (atomic_read(&tp_vars->sending) == 0)
494 if (unlikely(tp_vars->rto >= BATADV_TP_MAX_RTO)) {
495 batadv_tp_sender_shutdown(tp_vars,
503 tp_vars->rto <<= 1;
505 spin_lock_bh(&tp_vars->cwnd_lock);
507 tp_vars->ss_threshold = tp_vars->cwnd >> 1;
508 if (tp_vars->ss_threshold < BATADV_TP_PLEN * 2)
509 tp_vars->ss_threshold = BATADV_TP_PLEN * 2;
513 tp_vars->other_end, tp_vars->cwnd, tp_vars->ss_threshold,
514 atomic_read(&tp_vars->last_acked));
516 tp_vars->cwnd = BATADV_TP_PLEN * 3;
518 spin_unlock_bh(&tp_vars->cwnd_lock);
521 tp_vars->last_sent = atomic_read(&tp_vars->last_acked);
522 wake_up(&tp_vars->more_bytes);
524 batadv_tp_reset_sender_timer(tp_vars);
529 * @tp_vars: the private TP meter data for this session
533 static void batadv_tp_fill_prerandom(struct batadv_tp_vars *tp_vars,
541 spin_lock_bh(&tp_vars->prerandom_lock);
542 local_offset = tp_vars->prerandom_offset;
543 tp_vars->prerandom_offset += nbytes;
544 tp_vars->prerandom_offset %= sizeof(batadv_tp_prerandom);
545 spin_unlock_bh(&tp_vars->prerandom_lock);
561 * @tp_vars: the private TP meter data for this session
576 static int batadv_tp_send_msg(struct batadv_tp_vars *tp_vars, const u8 *src,
610 batadv_tp_fill_prerandom(tp_vars, data, data_len);
632 struct batadv_tp_vars *tp_vars;
643 /* find the tp_vars */
644 tp_vars = batadv_tp_list_find_session(bat_priv, icmp->orig,
646 if (unlikely(!tp_vars))
649 if (unlikely(atomic_read(&tp_vars->sending) == 0))
654 (u32)atomic_read(&tp_vars->last_acked)))
668 batadv_tp_update_rto(tp_vars, rtt);
671 batadv_tp_reset_sender_timer(tp_vars);
676 if (atomic_read(&tp_vars->last_acked) == recv_ack) {
677 atomic_inc(&tp_vars->dup_acks);
678 if (atomic_read(&tp_vars->dup_acks) != 3)
681 if (recv_ack >= tp_vars->recover)
685 batadv_tp_send_msg(tp_vars, primary_if->net_dev->dev_addr,
690 spin_lock_bh(&tp_vars->cwnd_lock);
693 tp_vars->fast_recovery = true;
697 tp_vars->recover = tp_vars->last_sent;
698 tp_vars->ss_threshold = tp_vars->cwnd >> 1;
701 tp_vars->cwnd, tp_vars->ss_threshold,
702 tp_vars->last_sent, recv_ack);
703 tp_vars->cwnd = batadv_tp_cwnd(tp_vars->ss_threshold, 3 * mss,
705 tp_vars->dec_cwnd = 0;
706 tp_vars->last_sent = recv_ack;
708 spin_unlock_bh(&tp_vars->cwnd_lock);
711 atomic64_add(recv_ack - atomic_read(&tp_vars->last_acked),
712 &tp_vars->tot_sent);
714 atomic_set(&tp_vars->dup_acks, 0);
716 if (tp_vars->fast_recovery) {
718 if (batadv_seq_before(recv_ack, tp_vars->recover)) {
724 batadv_tp_send_msg(tp_vars, dev_addr,
729 tp_vars->cwnd = batadv_tp_cwnd(tp_vars->cwnd,
732 tp_vars->fast_recovery = false;
737 cwnd = batadv_tp_cwnd(tp_vars->ss_threshold, 0,
739 tp_vars->cwnd = cwnd;
744 if (recv_ack - atomic_read(&tp_vars->last_acked) >= mss)
745 batadv_tp_update_cwnd(tp_vars, mss);
748 atomic_set(&tp_vars->last_acked, recv_ack);
751 wake_up(&tp_vars->more_bytes);
757 if (likely(tp_vars))
758 batadv_tp_vars_put(tp_vars);
763 * @tp_vars: the private data of the current TP meter session
768 static bool batadv_tp_avail(struct batadv_tp_vars *tp_vars,
773 win_limit = atomic_read(&tp_vars->last_acked) + tp_vars->cwnd;
774 win_left = win_limit - tp_vars->last_sent;
782 * @tp_vars: the private data of the current TP meter session
790 static int batadv_tp_wait_available(struct batadv_tp_vars *tp_vars, size_t plen)
794 ret = wait_event_interruptible_timeout(tp_vars->more_bytes,
795 batadv_tp_avail(tp_vars, plen),
803 * @arg: address of the related tp_vars
809 struct batadv_tp_vars *tp_vars = arg;
810 struct batadv_priv *bat_priv = tp_vars->bat_priv;
816 if (unlikely(tp_vars->role != BATADV_TP_SENDER)) {
818 tp_vars->reason = err;
822 orig_node = batadv_orig_hash_find(bat_priv, tp_vars->other_end);
825 tp_vars->reason = err;
832 tp_vars->reason = err;
845 batadv_tp_reset_sender_timer(tp_vars);
848 queue_delayed_work(batadv_event_workqueue, &tp_vars->finish_work,
849 msecs_to_jiffies(tp_vars->test_length));
851 while (atomic_read(&tp_vars->sending) != 0) {
852 if (unlikely(!batadv_tp_avail(tp_vars, payload_len))) {
853 batadv_tp_wait_available(tp_vars, payload_len);
862 err = batadv_tp_send_msg(tp_vars, primary_if->net_dev->dev_addr,
863 orig_node, tp_vars->last_sent,
865 tp_vars->session, tp_vars->icmp_uid,
874 if (atomic_dec_and_test(&tp_vars->sending))
875 tp_vars->reason = err;
881 tp_vars->last_sent += payload_len;
892 batadv_tp_sender_end(bat_priv, tp_vars);
893 batadv_tp_sender_cleanup(bat_priv, tp_vars);
895 batadv_tp_vars_put(tp_vars);
903 * @tp_vars: the private data of the current TP meter session
905 static void batadv_tp_start_kthread(struct batadv_tp_vars *tp_vars)
908 struct batadv_priv *bat_priv = tp_vars->bat_priv;
911 kref_get(&tp_vars->refcount);
912 kthread = kthread_create(batadv_tp_send, tp_vars, "kbatadv_tp_meter");
914 session_cookie = batadv_tp_session_cookie(tp_vars->session,
915 tp_vars->icmp_uid);
918 tp_vars->other_end,
922 batadv_tp_vars_put(tp_vars);
925 batadv_tp_sender_cleanup(bat_priv, tp_vars);
942 struct batadv_tp_vars *tp_vars;
954 tp_vars = batadv_tp_list_find(bat_priv, dst);
955 if (tp_vars) {
957 batadv_tp_vars_put(tp_vars);
974 tp_vars = kmalloc(sizeof(*tp_vars), GFP_ATOMIC);
975 if (!tp_vars) {
985 /* initialize tp_vars */
986 ether_addr_copy(tp_vars->other_end, dst);
987 kref_init(&tp_vars->refcount);
988 tp_vars->role = BATADV_TP_SENDER;
989 atomic_set(&tp_vars->sending, 1);
990 memcpy(tp_vars->session, session_id, sizeof(session_id));
991 tp_vars->icmp_uid = icmp_uid;
993 tp_vars->last_sent = BATADV_TP_FIRST_SEQ;
994 atomic_set(&tp_vars->last_acked, BATADV_TP_FIRST_SEQ);
995 tp_vars->fast_recovery = false;
996 tp_vars->recover = BATADV_TP_FIRST_SEQ;
1002 tp_vars->cwnd = BATADV_TP_PLEN * 3;
1006 tp_vars->ss_threshold = BATADV_TP_AWND;
1011 tp_vars->rto = 1000;
1012 tp_vars->srtt = 0;
1013 tp_vars->rttvar = 0;
1015 atomic64_set(&tp_vars->tot_sent, 0);
1017 kref_get(&tp_vars->refcount);
1018 timer_setup(&tp_vars->timer, batadv_tp_sender_timeout, 0);
1020 tp_vars->bat_priv = bat_priv;
1021 tp_vars->start_time = jiffies;
1023 init_waitqueue_head(&tp_vars->more_bytes);
1025 spin_lock_init(&tp_vars->unacked_lock);
1026 INIT_LIST_HEAD(&tp_vars->unacked_list);
1028 spin_lock_init(&tp_vars->cwnd_lock);
1030 tp_vars->prerandom_offset = 0;
1031 spin_lock_init(&tp_vars->prerandom_lock);
1033 kref_get(&tp_vars->refcount);
1034 hlist_add_head_rcu(&tp_vars->list, &bat_priv->tp_list);
1037 tp_vars->test_length = test_length;
1038 if (!tp_vars->test_length)
1039 tp_vars->test_length = BATADV_TP_DEF_TEST_LENGTH;
1046 INIT_DELAYED_WORK(&tp_vars->finish_work, batadv_tp_sender_finish);
1051 batadv_tp_start_kthread(tp_vars);
1053 /* don't return reference to new tp_vars */
1054 batadv_tp_vars_put(tp_vars);
1067 struct batadv_tp_vars *tp_vars;
1076 tp_vars = batadv_tp_list_find(bat_priv, orig_node->orig);
1077 if (!tp_vars) {
1083 batadv_tp_sender_shutdown(tp_vars, return_value);
1084 batadv_tp_vars_put(tp_vars);
1091 * @tp_vars: the private data of the current TP meter session
1095 static void batadv_tp_reset_receiver_timer(struct batadv_tp_vars *tp_vars)
1097 mod_timer(&tp_vars->timer,
1104 * @t: address to timer_list inside tp_vars
1108 struct batadv_tp_vars *tp_vars = from_timer(tp_vars, t, timer);
1112 bat_priv = tp_vars->bat_priv;
1115 if (!batadv_has_timed_out(tp_vars->last_recv_time,
1118 batadv_tp_reset_receiver_timer(tp_vars);
1124 BATADV_TP_RECV_TIMEOUT, tp_vars->other_end);
1126 spin_lock_bh(&tp_vars->bat_priv->tp_list_lock);
1127 hlist_del_rcu(&tp_vars->list);
1128 spin_unlock_bh(&tp_vars->bat_priv->tp_list_lock);
1131 batadv_tp_vars_put(tp_vars);
1135 spin_lock_bh(&tp_vars->unacked_lock);
1136 list_for_each_entry_safe(un, safe, &tp_vars->unacked_list, list) {
1140 spin_unlock_bh(&tp_vars->unacked_lock);
1143 batadv_tp_vars_put(tp_vars);
1220 * @tp_vars: the private data of the current TP meter session
1229 static bool batadv_tp_handle_out_of_order(struct batadv_tp_vars *tp_vars,
1247 spin_lock_bh(&tp_vars->unacked_lock);
1249 if (list_empty(&tp_vars->unacked_list)) {
1250 list_add(&new->list, &tp_vars->unacked_list);
1261 list_for_each_entry_reverse(un, &tp_vars->unacked_list, list) {
1286 list_add(&new->list, &tp_vars->unacked_list);
1289 spin_unlock_bh(&tp_vars->unacked_lock);
1297 * @tp_vars: the private data of the current TP meter session
1299 static void batadv_tp_ack_unordered(struct batadv_tp_vars *tp_vars)
1307 spin_lock_bh(&tp_vars->unacked_lock);
1308 list_for_each_entry_safe(un, safe, &tp_vars->unacked_list, list) {
1313 if (batadv_seq_before(tp_vars->last_recv, un->seqno))
1316 to_ack = un->seqno + un->len - tp_vars->last_recv;
1318 if (batadv_seq_before(tp_vars->last_recv, un->seqno + un->len))
1319 tp_vars->last_recv += to_ack;
1324 spin_unlock_bh(&tp_vars->unacked_lock);
1328 * batadv_tp_init_recv() - return matching or create new receiver tp_vars
1332 * Return: corresponding tp_vars or NULL on errors
1338 struct batadv_tp_vars *tp_vars;
1341 tp_vars = batadv_tp_list_find_session(bat_priv, icmp->orig,
1343 if (tp_vars)
1352 tp_vars = kmalloc(sizeof(*tp_vars), GFP_ATOMIC);
1353 if (!tp_vars)
1356 ether_addr_copy(tp_vars->other_end, icmp->orig);
1357 tp_vars->role = BATADV_TP_RECEIVER;
1358 memcpy(tp_vars->session, icmp->session, sizeof(tp_vars->session));
1359 tp_vars->last_recv = BATADV_TP_FIRST_SEQ;
1360 tp_vars->bat_priv = bat_priv;
1361 kref_init(&tp_vars->refcount);
1363 spin_lock_init(&tp_vars->unacked_lock);
1364 INIT_LIST_HEAD(&tp_vars->unacked_list);
1366 kref_get(&tp_vars->refcount);
1367 hlist_add_head_rcu(&tp_vars->list, &bat_priv->tp_list);
1369 kref_get(&tp_vars->refcount);
1370 timer_setup(&tp_vars->timer, batadv_tp_receiver_shutdown, 0);
1372 batadv_tp_reset_receiver_timer(tp_vars);
1377 return tp_vars;
1391 struct batadv_tp_vars *tp_vars;
1402 tp_vars = batadv_tp_init_recv(bat_priv, icmp);
1403 if (!tp_vars) {
1409 tp_vars = batadv_tp_list_find_session(bat_priv, icmp->orig,
1411 if (!tp_vars) {
1419 if (unlikely(tp_vars->role != BATADV_TP_RECEIVER)) {
1422 tp_vars->role);
1426 tp_vars->last_recv_time = jiffies;
1431 if (batadv_seq_before(seqno, tp_vars->last_recv))
1435 if (ntohl(icmp->seqno) != tp_vars->last_recv) {
1439 if (!batadv_tp_handle_out_of_order(tp_vars, skb))
1448 tp_vars->last_recv += packet_size;
1451 batadv_tp_ack_unordered(tp_vars);
1458 batadv_tp_send_ack(bat_priv, icmp->orig, tp_vars->last_recv,
1461 if (likely(tp_vars))
1462 batadv_tp_vars_put(tp_vars);