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
Unified · Split
| @@ -943,12 +943,15 @@ enum { · 942 unmodified lines | |||
| 943 | 943 | ||
| 944 | TCA_FQ_PRIOMAP, /* prio2band */ | 944 | TCA_FQ_PRIOMAP, /* prio2band */ |
| 945 | 945 | ||
| 946 | TCA_FQ_WEIGHTS, /* Weights for each band */ | ||
| 947 | |||
| 946 | __TCA_FQ_MAX | 948 | __TCA_FQ_MAX |
| 947 | }; | 949 | }; |
| 948 | 950 | ||
| 949 | #define TCA_FQ_MAX (__TCA_FQ_MAX - 1) | 951 | #define TCA_FQ_MAX (__TCA_FQ_MAX - 1) |
| 950 | 952 | ||
| 951 | #define FQ_BANDS 3 | 953 | #define FQ_BANDS 3 |
| 954 | #define FQ_MIN_WEIGHT 16384 | ||
| 952 | 955 | ||
| 953 | struct tc_fq_qd_stats { | 956 | struct tc_fq_qd_stats { |
| 954 | __u64 gc_flows; | 957 | __u64 gc_flows; |
| @@ -919,6 +919,10 @@ static const struct nla_policy fq_policy[TCA_FQ_MAX + 1] = { · 918 unmodified lines | |||
| 919 | .type = NLA_BINARY, | 919 | .type = NLA_BINARY, |
| 920 | .len = sizeof(struct tc_prio_qopt), | 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 | /* compress a u8 array with all elems <= 3 to an array of 2-bit fields */ | 928 | /* compress a u8 array with all elems <= 3 to an array of 2-bit fields */ |
| @@ -941,6 +945,25 @@ static void fq_prio2band_decompress_crumb(const u8 *in, u8 *out) · 16 unmodified lines | |||
| 941 | out[i] = fq_prio2band(in, i); | 945 | out[i] = fq_prio2band(in, i); |
| 942 | } | 946 | } |
| 943 | 947 | ||
| 948 | static int fq_load_weights(struct fq_sched_data *q, | ||
| 949 | const struct nlattr *attr, | ||
| 950 | struct netlink_ext_ack *extack) | ||
| 951 | { | ||
| 952 | s32 *weights = nla_data(attr); | ||
| 953 | int i; | ||
| 954 | |||
| 955 | for (i = 0; i < FQ_BANDS; i++) { | ||
| 956 | if (weights[i] < FQ_MIN_WEIGHT) { | ||
| 957 | NL_SET_ERR_MSG_FMT_MOD(extack, "Weight %d less that minimum allowed %d", | ||
| 958 | weights[i], FQ_MIN_WEIGHT); | ||
| 959 | return -EINVAL; | ||
| 960 | } | ||
| 961 | } | ||
| 962 | for (i = 0; i < FQ_BANDS; i++) | ||
| 963 | q->band_flows[i].quantum = weights[i]; | ||
| 964 | return 0; | ||
| 965 | } | ||
| 966 | |||
| 944 | static int fq_load_priomap(struct fq_sched_data *q, | 967 | static int fq_load_priomap(struct fq_sched_data *q, |
| 945 | const struct nlattr *attr, | 968 | const struct nlattr *attr, |
| 946 | struct netlink_ext_ack *extack) | 969 | struct netlink_ext_ack *extack) |
| @@ -1040,6 +1063,9 @@ static int fq_change(struct Qdisc *sch, struct nlattr *opt, · 93 unmodified lines | |||
| 1040 | if (!err && tb[TCA_FQ_PRIOMAP]) | 1063 | if (!err && tb[TCA_FQ_PRIOMAP]) |
| 1041 | err = fq_load_priomap(q, tb[TCA_FQ_PRIOMAP], extack); | 1064 | err = fq_load_priomap(q, tb[TCA_FQ_PRIOMAP], extack); |
| 1042 | 1065 | ||
| 1066 | if (!err && tb[TCA_FQ_WEIGHTS]) | ||
| 1067 | err = fq_load_weights(q, tb[TCA_FQ_WEIGHTS], extack); | ||
| 1068 | |||
| 1043 | if (tb[TCA_FQ_ORPHAN_MASK]) | 1069 | if (tb[TCA_FQ_ORPHAN_MASK]) |
| 1044 | q->orphan_mask = nla_get_u32(tb[TCA_FQ_ORPHAN_MASK]); | 1070 | q->orphan_mask = nla_get_u32(tb[TCA_FQ_ORPHAN_MASK]); |
| 1045 | 1071 | ||
| @@ -1142,6 +1168,7 @@ static int fq_dump(struct Qdisc *sch, struct sk_buff *skb) · 96 unmodified lines | |||
| 1142 | }; | 1168 | }; |
| 1143 | u64 horizon = q->horizon; | 1169 | u64 horizon = q->horizon; |
| 1144 | struct nlattr *opts; | 1170 | struct nlattr *opts; |
| 1171 | s32 weights[3]; | ||
| 1145 | 1172 | ||
| 1146 | opts = nla_nest_start_noflag(skb, TCA_OPTIONS); | 1173 | opts = nla_nest_start_noflag(skb, TCA_OPTIONS); |
| 1147 | if (opts == NULL) | 1174 | if (opts == NULL) |
| @@ -1175,6 +1202,12 @@ static int fq_dump(struct Qdisc *sch, struct sk_buff *skb) · 27 unmodified lines | |||
| 1175 | if (nla_put(skb, TCA_FQ_PRIOMAP, sizeof(prio), &prio)) | 1202 | if (nla_put(skb, TCA_FQ_PRIOMAP, sizeof(prio), &prio)) |
| 1176 | goto nla_put_failure; | 1203 | goto nla_put_failure; |
| 1177 | 1204 | ||
| 1205 | weights[0] = q->band_flows[0].quantum; | ||
| 1206 | weights[1] = q->band_flows[1].quantum; | ||
| 1207 | weights[2] = q->band_flows[2].quantum; | ||
| 1208 | if (nla_put(skb, TCA_FQ_WEIGHTS, sizeof(weights), &weights)) | ||
| 1209 | goto nla_put_failure; | ||
| 1210 | |||
| 1178 | return nla_nest_end(skb, opts); | 1211 | return nla_nest_end(skb, opts); |
| 1179 | 1212 | ||
| 1180 | nla_put_failure: | 1213 | nla_put_failure: |