Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net_sched: sch_fq: add TCA_FQ_WEIGHTS attribute

This attribute can be used to tune the per band weight
and report them in "tc qdisc show" output:

qdisc fq 802f: parent 1:9 limit 100000p flow_limit 500p buckets 1024 orphan_mask 1023
quantum 8364b initial_quantum 41820b low_rate_threshold 550Kbit
refill_delay 40ms timer_slack 10us horizon 10s horizon_drop
bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1 weights 589824 196608 65536
Sent 236460814 bytes 792991 pkt (dropped 0, overlimits 0 requeues 0)
rate 25816bit 10pps backlog 0b 0p requeues 0
flows 4 (inactive 4 throttled 0)
gc 0 throttled 19 latency 17.6us fastpath 773882

Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Dave Taht <dave.taht@gmail.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Eric Dumazet and committed by
Paolo Abeni
49e7265f 29f834aa

+36
+3
include/uapi/linux/pkt_sched.h
··· 943 943 944 944 TCA_FQ_PRIOMAP, /* prio2band */ 945 945 946 + TCA_FQ_WEIGHTS, /* Weights for each band */ 947 + 946 948 __TCA_FQ_MAX 947 949 }; 948 950 949 951 #define TCA_FQ_MAX (__TCA_FQ_MAX - 1) 950 952 951 953 #define FQ_BANDS 3 954 + #define FQ_MIN_WEIGHT 16384 952 955 953 956 struct tc_fq_qd_stats { 954 957 __u64 gc_flows;
+33
net/sched/sch_fq.c
··· 919 919 .type = NLA_BINARY, 920 920 .len = sizeof(struct tc_prio_qopt), 921 921 }, 922 + [TCA_FQ_WEIGHTS] = { 923 + .type = NLA_BINARY, 924 + .len = FQ_BANDS * sizeof(s32), 925 + }, 922 926 }; 923 927 924 928 /* compress a u8 array with all elems <= 3 to an array of 2-bit fields */ ··· 943 939 944 940 for (i = 0; i < num_elems; i++) 945 941 out[i] = fq_prio2band(in, i); 942 + } 943 + 944 + static int fq_load_weights(struct fq_sched_data *q, 945 + const struct nlattr *attr, 946 + struct netlink_ext_ack *extack) 947 + { 948 + s32 *weights = nla_data(attr); 949 + int i; 950 + 951 + for (i = 0; i < FQ_BANDS; i++) { 952 + if (weights[i] < FQ_MIN_WEIGHT) { 953 + NL_SET_ERR_MSG_FMT_MOD(extack, "Weight %d less that minimum allowed %d", 954 + weights[i], FQ_MIN_WEIGHT); 955 + return -EINVAL; 956 + } 957 + } 958 + for (i = 0; i < FQ_BANDS; i++) 959 + q->band_flows[i].quantum = weights[i]; 960 + return 0; 946 961 } 947 962 948 963 static int fq_load_priomap(struct fq_sched_data *q, ··· 1062 1039 1063 1040 if (!err && tb[TCA_FQ_PRIOMAP]) 1064 1041 err = fq_load_priomap(q, tb[TCA_FQ_PRIOMAP], extack); 1042 + 1043 + if (!err && tb[TCA_FQ_WEIGHTS]) 1044 + err = fq_load_weights(q, tb[TCA_FQ_WEIGHTS], extack); 1065 1045 1066 1046 if (tb[TCA_FQ_ORPHAN_MASK]) 1067 1047 q->orphan_mask = nla_get_u32(tb[TCA_FQ_ORPHAN_MASK]); ··· 1168 1142 }; 1169 1143 u64 horizon = q->horizon; 1170 1144 struct nlattr *opts; 1145 + s32 weights[3]; 1171 1146 1172 1147 opts = nla_nest_start_noflag(skb, TCA_OPTIONS); 1173 1148 if (opts == NULL) ··· 1200 1173 1201 1174 fq_prio2band_decompress_crumb(q->prio2band, prio.priomap); 1202 1175 if (nla_put(skb, TCA_FQ_PRIOMAP, sizeof(prio), &prio)) 1176 + goto nla_put_failure; 1177 + 1178 + weights[0] = q->band_flows[0].quantum; 1179 + weights[1] = q->band_flows[1].quantum; 1180 + weights[2] = q->band_flows[2].quantum; 1181 + if (nla_put(skb, TCA_FQ_WEIGHTS, sizeof(weights), &weights)) 1203 1182 goto nla_put_failure; 1204 1183 1205 1184 return nla_nest_end(skb, opts);