net: frag helper functions for mem limit tracking
This change is primarily a preparation to ease the extension of memory limit tracking. The change does reduce the number atomic operation, during freeing of a frag queue. This does introduce a some performance improvement, as these atomic operations are at the core of the performance problems seen on NUMA systems. Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
6e34a8b37a
commit
d433673e5f
@@ -122,7 +122,7 @@ int ip_frag_nqueues(struct net *net)
|
||||
|
||||
int ip_frag_mem(struct net *net)
|
||||
{
|
||||
return atomic_read(&net->ipv4.frags.mem);
|
||||
return sum_frag_mem_limit(&net->ipv4.frags);
|
||||
}
|
||||
|
||||
static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
|
||||
@@ -161,13 +161,6 @@ static bool ip4_frag_match(struct inet_frag_queue *q, void *a)
|
||||
qp->user == arg->user;
|
||||
}
|
||||
|
||||
/* Memory Tracking Functions. */
|
||||
static void frag_kfree_skb(struct netns_frags *nf, struct sk_buff *skb)
|
||||
{
|
||||
atomic_sub(skb->truesize, &nf->mem);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
static void ip4_frag_init(struct inet_frag_queue *q, void *a)
|
||||
{
|
||||
struct ipq *qp = container_of(q, struct ipq, q);
|
||||
@@ -340,6 +333,7 @@ static inline int ip_frag_too_far(struct ipq *qp)
|
||||
static int ip_frag_reinit(struct ipq *qp)
|
||||
{
|
||||
struct sk_buff *fp;
|
||||
unsigned int sum_truesize = 0;
|
||||
|
||||
if (!mod_timer(&qp->q.timer, jiffies + qp->q.net->timeout)) {
|
||||
atomic_inc(&qp->q.refcnt);
|
||||
@@ -349,9 +343,12 @@ static int ip_frag_reinit(struct ipq *qp)
|
||||
fp = qp->q.fragments;
|
||||
do {
|
||||
struct sk_buff *xp = fp->next;
|
||||
frag_kfree_skb(qp->q.net, fp);
|
||||
|
||||
sum_truesize += fp->truesize;
|
||||
kfree_skb(fp);
|
||||
fp = xp;
|
||||
} while (fp);
|
||||
sub_frag_mem_limit(&qp->q, sum_truesize);
|
||||
|
||||
qp->q.last_in = 0;
|
||||
qp->q.len = 0;
|
||||
@@ -496,7 +493,8 @@ found:
|
||||
qp->q.fragments = next;
|
||||
|
||||
qp->q.meat -= free_it->len;
|
||||
frag_kfree_skb(qp->q.net, free_it);
|
||||
sub_frag_mem_limit(&qp->q, free_it->truesize);
|
||||
kfree_skb(free_it);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -519,7 +517,7 @@ found:
|
||||
qp->q.stamp = skb->tstamp;
|
||||
qp->q.meat += skb->len;
|
||||
qp->ecn |= ecn;
|
||||
atomic_add(skb->truesize, &qp->q.net->mem);
|
||||
add_frag_mem_limit(&qp->q, skb->truesize);
|
||||
if (offset == 0)
|
||||
qp->q.last_in |= INET_FRAG_FIRST_IN;
|
||||
|
||||
@@ -617,7 +615,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
|
||||
head->len -= clone->len;
|
||||
clone->csum = 0;
|
||||
clone->ip_summed = head->ip_summed;
|
||||
atomic_add(clone->truesize, &qp->q.net->mem);
|
||||
add_frag_mem_limit(&qp->q, clone->truesize);
|
||||
}
|
||||
|
||||
skb_push(head, head->data - skb_network_header(head));
|
||||
@@ -645,7 +643,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
|
||||
}
|
||||
fp = next;
|
||||
}
|
||||
atomic_sub(sum_truesize, &qp->q.net->mem);
|
||||
sub_frag_mem_limit(&qp->q, sum_truesize);
|
||||
|
||||
head->next = NULL;
|
||||
head->dev = dev;
|
||||
|
Reference in New Issue
Block a user