public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Faizal Rahim <faizal.abdul.rahim@linux.intel.com>
To: Vladimir Oltean <vladimir.oltean@nxp.com>,
	Vinicius Costa Gomes <vinicius.gomes@intel.com>,
	Jamal Hadi Salim <jhs@mojatatu.com>,
	Cong Wang <xiyou.wangcong@gmail.com>,
	Jiri Pirko <jiri@resnulli.us>,
	"David S . Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v3 net 2/4] net/sched: taprio: fix cycle time adjustment for next entry
Date: Tue, 19 Dec 2023 03:14:51 -0500	[thread overview]
Message-ID: <20231219081453.718489-3-faizal.abdul.rahim@linux.intel.com> (raw)
In-Reply-To: <20231219081453.718489-1-faizal.abdul.rahim@linux.intel.com>

According to IEEE Std. 802.1Q-2018 section Q.5 CycleTimeExtension:
"the Cycle Time Extension variable allows this extension of the last old
cycle to be done in a defined way. If the last complete old cycle would
normally end less than OperCycleTimeExtension nanoseconds before the new
base time, then the last complete cycle before AdminBaseTime is reached
is extended so that it ends at AdminBaseTime."

Fix cyle time modification logic for the next entry that includes the
following cases:
a) positive correction - cycle time extension
b) negative correction - cycle time truncation
c) zero correction - new admin base time aligns exactly with the old
cycle

Fixes: a3d43c0d56f1 ("taprio: Add support adding an admin schedule")
Signed-off-by: Faizal Rahim <faizal.abdul.rahim@linux.intel.com>
---
 net/sched/sch_taprio.c | 100 +++++++++++++++++++++++++----------------
 1 file changed, 62 insertions(+), 38 deletions(-)

diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
index bbcaf05d40ba..e70dc69c311f 100644
--- a/net/sched/sch_taprio.c
+++ b/net/sched/sch_taprio.c
@@ -893,38 +893,54 @@ static bool should_restart_cycle(const struct sched_gate_list *oper,
 	return false;
 }
 
-static bool should_change_schedules(const struct sched_gate_list *admin,
-				    const struct sched_gate_list *oper,
-				    ktime_t end_time)
-{
-	ktime_t next_base_time, extension_time;
-
-	if (!admin)
-		return false;
-
-	next_base_time = sched_base_time(admin);
-
-	/* This is the simple case, the end_time would fall after
-	 * the next schedule base_time.
-	 */
-	if (ktime_compare(next_base_time, end_time) <= 0)
-		return true;
-
-	/* This is the cycle_time_extension case, if the end_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(end_time, oper->cycle_time_extension);
+static bool should_extend_cycle(const struct sched_gate_list *oper,
+				ktime_t new_base_time,
+				ktime_t next_entry_end_time,
+				const struct sched_entry *next_entry)
+{
+	ktime_t next_cycle_end_time = ktime_add_ns(oper->cycle_end_time,
+						   oper->cycle_time);
+	bool extension_supported = oper->cycle_time_extension > 0;
+	s64 extension_limit = oper->cycle_time_extension;
+	s64 extension_duration = ktime_sub(new_base_time, next_entry_end_time);
+
+	return extension_supported &&
+	       list_is_last(&next_entry->list, &oper->entries) &&
+	       ktime_before(new_base_time, next_cycle_end_time) &&
+	       extension_duration < extension_limit;
+}
+
+static s64 get_cycle_time_correction(const struct sched_gate_list *oper,
+				     ktime_t new_base_time,
+				     ktime_t next_entry_end_time,
+				     const struct sched_entry *next_entry)
+{
+	s64 correction = CYCLE_TIME_CORRECTION_UNSPEC;
+
+	if (ktime_compare(new_base_time, next_entry_end_time) <= 0) {
+		/* Negative correction - The new admin base time starts earlier
+		 * than the next entry's end time.
+		 * Zero correction - The new admin base time aligns exactly
+		 * with the old cycle.
+		 */
+		correction = ktime_sub(new_base_time, next_entry_end_time);
 
-	/* 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;
+		/* Below is to hande potential issue where the negative correction
+		 * exceed the entry's interval. This typically shouldn't happen.
+		 * Setting to 0 enables schedule changes without altering cycle time.
+		 */
+		if (abs(correction) > next_entry->interval)
+			correction = 0;
+	} else if (ktime_after(new_base_time, next_entry_end_time) &&
+		   should_extend_cycle(oper, new_base_time,
+				       next_entry_end_time, next_entry)) {
+		/* Positive correction - The new admin base time starts after the
+		 * last entry end time and within the next cycle time of old oper.
+		 */
+		correction = ktime_sub(new_base_time, next_entry_end_time);
+	}
 
-	return false;
+	return correction;
 }
 
 static enum hrtimer_restart advance_sched(struct hrtimer *timer)
@@ -975,6 +991,22 @@ static enum hrtimer_restart advance_sched(struct hrtimer *timer)
 	end_time = ktime_add_ns(entry->end_time, next->interval);
 	end_time = min_t(ktime_t, end_time, oper->cycle_end_time);
 
+	if (admin) {
+		ktime_t new_base_time = sched_base_time(admin);
+
+		oper->cycle_time_correction =
+			get_cycle_time_correction(oper, new_base_time,
+						  end_time, next);
+
+		if (sched_switch_pending(oper)) {
+			/* The next entry is the last entry we will run from
+			 * oper, subsequent ones will take from the new admin
+			 */
+			oper->cycle_end_time = new_base_time;
+			end_time = new_base_time;
+		}
+	}
+
 	for (tc = 0; tc < num_tc; tc++) {
 		if (next->gate_duration[tc] == oper->cycle_time)
 			next->gate_close_time[tc] = KTIME_MAX;
@@ -983,14 +1015,6 @@ static enum hrtimer_restart advance_sched(struct hrtimer *timer)
 								 next->gate_duration[tc]);
 	}
 
-	if (should_change_schedules(admin, oper, end_time)) {
-		/* Set things so the next time this runs, the new
-		 * schedule runs.
-		 */
-		end_time = sched_base_time(admin);
-		oper->cycle_time_correction = 0;
-	}
-
 	next->end_time = end_time;
 	taprio_set_budgets(q, oper, next);
 
-- 
2.25.1


  parent reply	other threads:[~2023-12-19  8:17 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-19  8:14 [PATCH v3 net 0/4] qbv cycle time extension/truncation Faizal Rahim
2023-12-19  8:14 ` [PATCH v3 net 1/4] net/sched: taprio: fix too early schedules switching Faizal Rahim
2023-12-19  8:14 ` Faizal Rahim [this message]
2023-12-19  8:14 ` [PATCH v3 net 3/4] net/sched: taprio: fix impacted fields value during cycle time adjustment Faizal Rahim
2023-12-19  8:14 ` [PATCH v3 net 4/4] net/sched: taprio: get corrected value of cycle_time and interval Faizal Rahim
2023-12-19 16:56 ` [PATCH v3 net 0/4] qbv cycle time extension/truncation Vladimir Oltean
2023-12-20  3:25   ` Abdul Rahim, Faizal
2023-12-21 13:35     ` Vladimir Oltean
2023-12-29  2:15       ` Abdul Rahim, Faizal
2023-12-21  8:52   ` Paolo Abeni
2023-12-21 10:12     ` Abdul Rahim, Faizal
2023-12-19 17:02 ` Eric Dumazet
2023-12-21  5:57   ` Abdul Rahim, Faizal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231219081453.718489-3-faizal.abdul.rahim@linux.intel.com \
    --to=faizal.abdul.rahim@linux.intel.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=jhs@mojatatu.com \
    --cc=jiri@resnulli.us \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=vinicius.gomes@intel.com \
    --cc=vladimir.oltean@nxp.com \
    --cc=xiyou.wangcong@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox