OSDN Git Service

taprio: Add support for cycle-time-extension
authorVinicius Costa Gomes <vinicius.gomes@intel.com>
Mon, 29 Apr 2019 22:48:33 +0000 (15:48 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 1 May 2019 15:58:51 +0000 (11:58 -0400)
IEEE 802.1Q-2018 defines the concept of a cycle-time-extension, so the
last entry of a schedule before the start of a new schedule can be
extended, so "too-short" entries can be avoided.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/uapi/linux/pkt_sched.h
net/sched/sch_taprio.c

index 7a32276..8b2f993 100644 (file)
@@ -1168,6 +1168,7 @@ enum {
        TCA_TAPRIO_PAD,
        TCA_TAPRIO_ATTR_ADMIN_SCHED, /* The admin sched, only used in dump */
        TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME, /* s64 */
+       TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME_EXTENSION, /* s64 */
        __TCA_TAPRIO_ATTR_MAX,
 };
 
index 6b37ffd..5396771 100644 (file)
@@ -48,6 +48,7 @@ struct sched_gate_list {
        size_t num_entries;
        ktime_t cycle_close_time;
        s64 cycle_time;
+       s64 cycle_time_extension;
        s64 base_time;
 };
 
@@ -290,7 +291,7 @@ static bool should_change_schedules(const struct sched_gate_list *admin,
                                    const struct sched_gate_list *oper,
                                    ktime_t close_time)
 {
-       ktime_t next_base_time;
+       ktime_t next_base_time, extension_time;
 
        if (!admin)
                return false;
@@ -303,6 +304,20 @@ static bool should_change_schedules(const struct sched_gate_list *admin,
        if (ktime_compare(next_base_time, close_time) <= 0)
                return true;
 
+       /* This is the cycle_time_extension case, if the close_time
+        * plus the amount that can be extended would fall after the
+        * next schedule base_time, we can extend the current schedule
+        * for that amount.
+        */
+       extension_time = ktime_add_ns(close_time, oper->cycle_time_extension);
+
+       /* FIXME: the IEEE 802.1Q-2018 Specification isn't clear about
+        * how precisely the extension should be made. So after
+        * conformance testing, this logic may change.
+        */
+       if (ktime_compare(next_base_time, extension_time) <= 0)
+               return true;
+
        return false;
 }
 
@@ -390,11 +405,12 @@ static const struct nla_policy taprio_policy[TCA_TAPRIO_ATTR_MAX + 1] = {
        [TCA_TAPRIO_ATTR_PRIOMAP]              = {
                .len = sizeof(struct tc_mqprio_qopt)
        },
-       [TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST]     = { .type = NLA_NESTED },
-       [TCA_TAPRIO_ATTR_SCHED_BASE_TIME]      = { .type = NLA_S64 },
-       [TCA_TAPRIO_ATTR_SCHED_SINGLE_ENTRY]   = { .type = NLA_NESTED },
-       [TCA_TAPRIO_ATTR_SCHED_CLOCKID]        = { .type = NLA_S32 },
-       [TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME]     = { .type = NLA_S64 },
+       [TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST]           = { .type = NLA_NESTED },
+       [TCA_TAPRIO_ATTR_SCHED_BASE_TIME]            = { .type = NLA_S64 },
+       [TCA_TAPRIO_ATTR_SCHED_SINGLE_ENTRY]         = { .type = NLA_NESTED },
+       [TCA_TAPRIO_ATTR_SCHED_CLOCKID]              = { .type = NLA_S32 },
+       [TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME]           = { .type = NLA_S64 },
+       [TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME_EXTENSION] = { .type = NLA_S64 },
 };
 
 static int fill_sched_entry(struct nlattr **tb, struct sched_entry *entry,
@@ -496,6 +512,9 @@ static int parse_taprio_schedule(struct nlattr **tb,
        if (tb[TCA_TAPRIO_ATTR_SCHED_BASE_TIME])
                new->base_time = nla_get_s64(tb[TCA_TAPRIO_ATTR_SCHED_BASE_TIME]);
 
+       if (tb[TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME_EXTENSION])
+               new->cycle_time_extension = nla_get_s64(tb[TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME_EXTENSION]);
+
        if (tb[TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME])
                new->cycle_time = nla_get_s64(tb[TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME]);
 
@@ -1008,6 +1027,10 @@ static int dump_schedule(struct sk_buff *msg,
                        root->cycle_time, TCA_TAPRIO_PAD))
                return -1;
 
+       if (nla_put_s64(msg, TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME_EXTENSION,
+                       root->cycle_time_extension, TCA_TAPRIO_PAD))
+               return -1;
+
        entry_list = nla_nest_start_noflag(msg,
                                           TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST);
        if (!entry_list)