Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8e7999c4 authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by David S. Miller
Browse files

[INET]: Consolidate the xxx_evictor



The evictors collect some statistics for ipv4 and ipv6,
so make it return the number of evicted queues and account
them all at once in the caller.

The XXX_ADD_STATS_BH() macros are just for this case,
but maybe there are places in code, that can make use of
them as well.

Signed-off-by: default avatarPavel Emelyanov <xemul@openvz.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1e4b8287
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -49,5 +49,6 @@ void inet_frags_fini(struct inet_frags *);
void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f);
void inet_frag_destroy(struct inet_frag_queue *q,
				struct inet_frags *f, int *work);
int inet_frag_evictor(struct inet_frags *f);

#endif
+1 −0
Original line number Diff line number Diff line
@@ -160,6 +160,7 @@ DECLARE_SNMP_STAT(struct ipstats_mib, ip_statistics);
#define IP_INC_STATS(field)		SNMP_INC_STATS(ip_statistics, field)
#define IP_INC_STATS_BH(field)		SNMP_INC_STATS_BH(ip_statistics, field)
#define IP_INC_STATS_USER(field) 	SNMP_INC_STATS_USER(ip_statistics, field)
#define IP_ADD_STATS_BH(field, val)	SNMP_ADD_STATS_BH(ip_statistics, field, val)
DECLARE_SNMP_STAT(struct linux_mib, net_statistics);
#define NET_INC_STATS(field)		SNMP_INC_STATS(net_statistics, field)
#define NET_INC_STATS_BH(field)		SNMP_INC_STATS_BH(net_statistics, field)
+9 −0
Original line number Diff line number Diff line
@@ -120,12 +120,21 @@ extern int sysctl_mld_max_msf;
	SNMP_INC_STATS##modifier(statname##_statistics, (field));	\
})

#define _DEVADD(statname, modifier, idev, field, val)			\
({									\
	struct inet6_dev *_idev = (idev);				\
	if (likely(_idev != NULL))					\
		SNMP_ADD_STATS##modifier((_idev)->stats.statname, (field), (val)); \
	SNMP_ADD_STATS##modifier(statname##_statistics, (field), (val));\
})

/* MIBs */
DECLARE_SNMP_STAT(struct ipstats_mib, ipv6_statistics);

#define IP6_INC_STATS(idev,field)	_DEVINC(ipv6, , idev, field)
#define IP6_INC_STATS_BH(idev,field)	_DEVINC(ipv6, _BH, idev, field)
#define IP6_INC_STATS_USER(idev,field)	_DEVINC(ipv6, _USER, idev, field)
#define IP6_ADD_STATS_BH(idev,field,val) _DEVADD(ipv6, _BH, idev, field, val)

DECLARE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics);
DECLARE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg_statistics);
+32 −0
Original line number Diff line number Diff line
@@ -140,3 +140,35 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f,

}
EXPORT_SYMBOL(inet_frag_destroy);

int inet_frag_evictor(struct inet_frags *f)
{
	struct inet_frag_queue *q;
	int work, evicted = 0;

	work = atomic_read(&f->mem) - f->ctl->low_thresh;
	while (work > 0) {
		read_lock(&f->lock);
		if (list_empty(&f->lru_list)) {
			read_unlock(&f->lock);
			break;
		}

		q = list_first_entry(&f->lru_list,
				struct inet_frag_queue, lru_list);
		atomic_inc(&q->refcnt);
		read_unlock(&f->lock);

		spin_lock(&q->lock);
		if (!(q->last_in & COMPLETE))
			inet_frag_kill(q, f);
		spin_unlock(&q->lock);

		if (atomic_dec_and_test(&q->refcnt))
			inet_frag_destroy(q, f, &work);
		evicted++;
	}

	return evicted;
}
EXPORT_SYMBOL(inet_frag_evictor);
+4 −26
Original line number Diff line number Diff line
@@ -174,33 +174,11 @@ static void ipq_kill(struct ipq *ipq)
 */
static void ip_evictor(void)
{
	struct ipq *qp;
	struct list_head *tmp;
	int work;

	work = atomic_read(&ip4_frags.mem) - ip4_frags_ctl.low_thresh;
	if (work <= 0)
		return;

	while (work > 0) {
		read_lock(&ip4_frags.lock);
		if (list_empty(&ip4_frags.lru_list)) {
			read_unlock(&ip4_frags.lock);
			return;
		}
		tmp = ip4_frags.lru_list.next;
		qp = list_entry(tmp, struct ipq, q.lru_list);
		atomic_inc(&qp->q.refcnt);
		read_unlock(&ip4_frags.lock);
	int evicted;

		spin_lock(&qp->q.lock);
		if (!(qp->q.last_in&COMPLETE))
			ipq_kill(qp);
		spin_unlock(&qp->q.lock);

		ipq_put(qp, &work);
		IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);
	}
	evicted = inet_frag_evictor(&ip4_frags);
	if (evicted)
		IP_ADD_STATS_BH(IPSTATS_MIB_REASMFAILS, evicted);
}

/*
Loading