#define BATADV_TP_PLEN (BATADV_TP_PACKET_LEN - ETH_HLEN - \
sizeof(struct batadv_unicast_packet))
+/**
+ * BATADV_TP_MAX_UNACKED - maximum number of packets a receiver didn't yet ack
+ */
+#define BATADV_TP_MAX_UNACKED 100
+
static u8 batadv_tp_prerandom[4096] __read_mostly;
/**
list_for_each_entry_safe(un, safe, &tp_vars->common.unacked_list, list) {
list_del(&un->list);
kfree(un);
+ tp_vars->common.unacked_count--;
}
spin_unlock_bh(&tp_vars->common.unacked_lock);
/* if the list is empty immediately attach this new object */
if (list_empty(&tp_vars->common.unacked_list)) {
list_add(&new->list, &tp_vars->common.unacked_list);
+ tp_vars->common.unacked_count++;
goto out;
}
*/
list_add(&new->list, &un->list);
added = true;
+ tp_vars->common.unacked_count++;
break;
}
/* received packet with smallest seqno out of order; add it to front */
- if (!added)
+ if (!added) {
list_add(&new->list, &tp_vars->common.unacked_list);
+ tp_vars->common.unacked_count++;
+ }
+
+ /* remove the last (biggest) unacked seqno when list is too large */
+ if (tp_vars->common.unacked_count > BATADV_TP_MAX_UNACKED) {
+ un = list_last_entry(&tp_vars->common.unacked_list,
+ struct batadv_tp_unacked, list);
+ list_del(&un->list);
+ kfree(un);
+ tp_vars->common.unacked_count--;
+ }
out:
spin_unlock_bh(&tp_vars->common.unacked_lock);
list_del(&un->list);
kfree(un);
+ tp_vars->common.unacked_count--;
}
spin_unlock_bh(&tp_vars->common.unacked_lock);
}
spin_lock_init(&tp_vars->common.unacked_lock);
INIT_LIST_HEAD(&tp_vars->common.unacked_list);
+ tp_vars->common.unacked_count = 0;
kref_get(&tp_vars->common.refcount);
timer_setup(&tp_vars->common.timer, batadv_tp_receiver_shutdown, 0);