Commit c25031e9 authored by Vinicius Costa Gomes's avatar Vinicius Costa Gomes Committed by David S. Miller

taprio: Add support for cycle-time-extension

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: default avatarVinicius Costa Gomes <vinicius.gomes@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6ca6a665
...@@ -1168,6 +1168,7 @@ enum { ...@@ -1168,6 +1168,7 @@ enum {
TCA_TAPRIO_PAD, TCA_TAPRIO_PAD,
TCA_TAPRIO_ATTR_ADMIN_SCHED, /* The admin sched, only used in dump */ 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, /* s64 */
TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME_EXTENSION, /* s64 */
__TCA_TAPRIO_ATTR_MAX, __TCA_TAPRIO_ATTR_MAX,
}; };
......
...@@ -48,6 +48,7 @@ struct sched_gate_list { ...@@ -48,6 +48,7 @@ struct sched_gate_list {
size_t num_entries; size_t num_entries;
ktime_t cycle_close_time; ktime_t cycle_close_time;
s64 cycle_time; s64 cycle_time;
s64 cycle_time_extension;
s64 base_time; s64 base_time;
}; };
...@@ -290,7 +291,7 @@ static bool should_change_schedules(const struct sched_gate_list *admin, ...@@ -290,7 +291,7 @@ static bool should_change_schedules(const struct sched_gate_list *admin,
const struct sched_gate_list *oper, const struct sched_gate_list *oper,
ktime_t close_time) ktime_t close_time)
{ {
ktime_t next_base_time; ktime_t next_base_time, extension_time;
if (!admin) if (!admin)
return false; return false;
...@@ -303,6 +304,20 @@ static bool should_change_schedules(const struct sched_gate_list *admin, ...@@ -303,6 +304,20 @@ static bool should_change_schedules(const struct sched_gate_list *admin,
if (ktime_compare(next_base_time, close_time) <= 0) if (ktime_compare(next_base_time, close_time) <= 0)
return true; 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; return false;
} }
...@@ -390,11 +405,12 @@ static const struct nla_policy taprio_policy[TCA_TAPRIO_ATTR_MAX + 1] = { ...@@ -390,11 +405,12 @@ static const struct nla_policy taprio_policy[TCA_TAPRIO_ATTR_MAX + 1] = {
[TCA_TAPRIO_ATTR_PRIOMAP] = { [TCA_TAPRIO_ATTR_PRIOMAP] = {
.len = sizeof(struct tc_mqprio_qopt) .len = sizeof(struct tc_mqprio_qopt)
}, },
[TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST] = { .type = NLA_NESTED }, [TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST] = { .type = NLA_NESTED },
[TCA_TAPRIO_ATTR_SCHED_BASE_TIME] = { .type = NLA_S64 }, [TCA_TAPRIO_ATTR_SCHED_BASE_TIME] = { .type = NLA_S64 },
[TCA_TAPRIO_ATTR_SCHED_SINGLE_ENTRY] = { .type = NLA_NESTED }, [TCA_TAPRIO_ATTR_SCHED_SINGLE_ENTRY] = { .type = NLA_NESTED },
[TCA_TAPRIO_ATTR_SCHED_CLOCKID] = { .type = NLA_S32 }, [TCA_TAPRIO_ATTR_SCHED_CLOCKID] = { .type = NLA_S32 },
[TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME] = { .type = NLA_S64 }, [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, static int fill_sched_entry(struct nlattr **tb, struct sched_entry *entry,
...@@ -496,6 +512,9 @@ static int parse_taprio_schedule(struct nlattr **tb, ...@@ -496,6 +512,9 @@ static int parse_taprio_schedule(struct nlattr **tb,
if (tb[TCA_TAPRIO_ATTR_SCHED_BASE_TIME]) if (tb[TCA_TAPRIO_ATTR_SCHED_BASE_TIME])
new->base_time = nla_get_s64(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]) if (tb[TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME])
new->cycle_time = nla_get_s64(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, ...@@ -1008,6 +1027,10 @@ static int dump_schedule(struct sk_buff *msg,
root->cycle_time, TCA_TAPRIO_PAD)) root->cycle_time, TCA_TAPRIO_PAD))
return -1; 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, entry_list = nla_nest_start_noflag(msg,
TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST); TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST);
if (!entry_list) if (!entry_list)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment