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

Commit 93be42f9 authored by Davide Caratti's avatar Davide Caratti Committed by David S. Miller
Browse files

net/sched: act_police: use per-cpu counters



use per-CPU counters, instead of sharing a single set of stats with all
cores. This removes the need of using spinlock when statistics are read
or updated.

Signed-off-by: default avatarDavide Caratti <dcaratti@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c3ec8bcc
Loading
Loading
Loading
Loading
+22 −24
Original line number Diff line number Diff line
@@ -110,7 +110,7 @@ static int tcf_police_init(struct net *net, struct nlattr *nla,

	if (!exists) {
		ret = tcf_idr_create(tn, parm->index, NULL, a,
				     &act_police_ops, bind, false);
				     &act_police_ops, bind, true);
		if (ret) {
			tcf_idr_cleanup(tn, parm->index);
			return ret;
@@ -137,7 +137,8 @@ static int tcf_police_init(struct net *net, struct nlattr *nla,
	}

	if (est) {
		err = gen_replace_estimator(&police->tcf_bstats, NULL,
		err = gen_replace_estimator(&police->tcf_bstats,
					    police->common.cpu_bstats,
					    &police->tcf_rate_est,
					    &police->tcf_lock,
					    NULL, est);
@@ -207,32 +208,27 @@ static int tcf_police_act(struct sk_buff *skb, const struct tc_action *a,
			  struct tcf_result *res)
{
	struct tcf_police *police = to_police(a);
	s64 now;
	s64 toks;
	s64 ptoks = 0;
	s64 now, toks, ptoks = 0;
	int ret;

	spin_lock(&police->tcf_lock);

	bstats_update(&police->tcf_bstats, skb);
	tcf_lastuse_update(&police->tcf_tm);
	bstats_cpu_update(this_cpu_ptr(police->common.cpu_bstats), skb);

	spin_lock(&police->tcf_lock);
	if (police->tcfp_ewma_rate) {
		struct gnet_stats_rate_est64 sample;

		if (!gen_estimator_read(&police->tcf_rate_est, &sample) ||
		    sample.bps >= police->tcfp_ewma_rate) {
			police->tcf_qstats.overlimits++;
			if (police->tcf_action == TC_ACT_SHOT)
				police->tcf_qstats.drops++;
			spin_unlock(&police->tcf_lock);
			return police->tcf_action;
			ret = police->tcf_action;
			goto inc_overlimits;
		}
	}

	if (qdisc_pkt_len(skb) <= police->tcfp_mtu) {
		if (!police->rate_present) {
			spin_unlock(&police->tcf_lock);
			return police->tcfp_result;
			ret = police->tcfp_result;
			goto unlock;
		}

		now = ktime_get_ns();
@@ -253,18 +249,20 @@ static int tcf_police_act(struct sk_buff *skb, const struct tc_action *a,
			police->tcfp_t_c = now;
			police->tcfp_toks = toks;
			police->tcfp_ptoks = ptoks;
			if (police->tcfp_result == TC_ACT_SHOT)
				police->tcf_qstats.drops++;
			spin_unlock(&police->tcf_lock);
			return police->tcfp_result;
			ret = police->tcfp_result;
			goto inc_drops;
		}
	}

	police->tcf_qstats.overlimits++;
	if (police->tcf_action == TC_ACT_SHOT)
		police->tcf_qstats.drops++;
	ret = police->tcf_action;

inc_overlimits:
	qstats_overlimit_inc(this_cpu_ptr(police->common.cpu_qstats));
inc_drops:
	if (ret == TC_ACT_SHOT)
		qstats_drop_inc(this_cpu_ptr(police->common.cpu_qstats));
unlock:
	spin_unlock(&police->tcf_lock);
	return police->tcf_action;
	return ret;
}

static int tcf_police_dump(struct sk_buff *skb, struct tc_action *a,