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: Davide Caratti <dcaratti@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
c3ec8bcceb
Коммит
93be42f917
|
@ -110,7 +110,7 @@ static int tcf_police_init(struct net *net, struct nlattr *nla,
|
||||||
|
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
ret = tcf_idr_create(tn, parm->index, NULL, a,
|
ret = tcf_idr_create(tn, parm->index, NULL, a,
|
||||||
&act_police_ops, bind, false);
|
&act_police_ops, bind, true);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
tcf_idr_cleanup(tn, parm->index);
|
tcf_idr_cleanup(tn, parm->index);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -137,7 +137,8 @@ static int tcf_police_init(struct net *net, struct nlattr *nla,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (est) {
|
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_rate_est,
|
||||||
&police->tcf_lock,
|
&police->tcf_lock,
|
||||||
NULL, est);
|
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_result *res)
|
||||||
{
|
{
|
||||||
struct tcf_police *police = to_police(a);
|
struct tcf_police *police = to_police(a);
|
||||||
s64 now;
|
s64 now, toks, ptoks = 0;
|
||||||
s64 toks;
|
int ret;
|
||||||
s64 ptoks = 0;
|
|
||||||
|
tcf_lastuse_update(&police->tcf_tm);
|
||||||
|
bstats_cpu_update(this_cpu_ptr(police->common.cpu_bstats), skb);
|
||||||
|
|
||||||
spin_lock(&police->tcf_lock);
|
spin_lock(&police->tcf_lock);
|
||||||
|
|
||||||
bstats_update(&police->tcf_bstats, skb);
|
|
||||||
tcf_lastuse_update(&police->tcf_tm);
|
|
||||||
|
|
||||||
if (police->tcfp_ewma_rate) {
|
if (police->tcfp_ewma_rate) {
|
||||||
struct gnet_stats_rate_est64 sample;
|
struct gnet_stats_rate_est64 sample;
|
||||||
|
|
||||||
if (!gen_estimator_read(&police->tcf_rate_est, &sample) ||
|
if (!gen_estimator_read(&police->tcf_rate_est, &sample) ||
|
||||||
sample.bps >= police->tcfp_ewma_rate) {
|
sample.bps >= police->tcfp_ewma_rate) {
|
||||||
police->tcf_qstats.overlimits++;
|
ret = police->tcf_action;
|
||||||
if (police->tcf_action == TC_ACT_SHOT)
|
goto inc_overlimits;
|
||||||
police->tcf_qstats.drops++;
|
|
||||||
spin_unlock(&police->tcf_lock);
|
|
||||||
return police->tcf_action;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qdisc_pkt_len(skb) <= police->tcfp_mtu) {
|
if (qdisc_pkt_len(skb) <= police->tcfp_mtu) {
|
||||||
if (!police->rate_present) {
|
if (!police->rate_present) {
|
||||||
spin_unlock(&police->tcf_lock);
|
ret = police->tcfp_result;
|
||||||
return police->tcfp_result;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
now = ktime_get_ns();
|
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_t_c = now;
|
||||||
police->tcfp_toks = toks;
|
police->tcfp_toks = toks;
|
||||||
police->tcfp_ptoks = ptoks;
|
police->tcfp_ptoks = ptoks;
|
||||||
if (police->tcfp_result == TC_ACT_SHOT)
|
ret = police->tcfp_result;
|
||||||
police->tcf_qstats.drops++;
|
goto inc_drops;
|
||||||
spin_unlock(&police->tcf_lock);
|
|
||||||
return police->tcfp_result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ret = police->tcf_action;
|
||||||
|
|
||||||
police->tcf_qstats.overlimits++;
|
inc_overlimits:
|
||||||
if (police->tcf_action == TC_ACT_SHOT)
|
qstats_overlimit_inc(this_cpu_ptr(police->common.cpu_qstats));
|
||||||
police->tcf_qstats.drops++;
|
inc_drops:
|
||||||
|
if (ret == TC_ACT_SHOT)
|
||||||
|
qstats_drop_inc(this_cpu_ptr(police->common.cpu_qstats));
|
||||||
|
unlock:
|
||||||
spin_unlock(&police->tcf_lock);
|
spin_unlock(&police->tcf_lock);
|
||||||
return police->tcf_action;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tcf_police_dump(struct sk_buff *skb, struct tc_action *a,
|
static int tcf_police_dump(struct sk_buff *skb, struct tc_action *a,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче