From patchwork Tue Nov 7 11:20:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Abdul Rahim, Faizal" X-Patchwork-Id: 13448529 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6F1A72D78D for ; Tue, 7 Nov 2023 11:21:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="bcmUsz5a" Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6014EDF; Tue, 7 Nov 2023 03:21:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1699356118; x=1730892118; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=bHImEZIJ0xShgJd/ZwUz1VFJC6sRPgJf9bhkur+fnmc=; b=bcmUsz5aE80nkZqKEgfgBFgg/8MYpvb7N9NFe2pFRj+2lQ/RD6S216Pt hSYGjf+PV70zPrsrSY/Z5z3NqB1qZIOOuOZ4ZlKgch8bAMSrlvAYYsKOl yTvPKekBRwTGjcnI8qXDgjYuULouuWue4+SvuKZ2HjBj239RFe0GPAcOz oPShqsUJNTkoaDf9nS8VYVRb6JiFfZfUi9S6c0wLkTVMjXyklp+bhvk0S 61BAzqBzPNLkwvA022oaOI31bNtg+0KjaJDUBzN0jADOdq2TSG5iBrpiZ Kr4uXIAGhNcPwKqKnVJ6JsIBjoM13etDEqphtr7ROFISEbpBmX1ZiQU2Q A==; X-IronPort-AV: E=McAfee;i="6600,9927,10886"; a="475727098" X-IronPort-AV: E=Sophos;i="6.03,283,1694761200"; d="scan'208";a="475727098" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Nov 2023 03:21:58 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10886"; a="828579783" X-IronPort-AV: E=Sophos;i="6.03,283,1694761200"; d="scan'208";a="828579783" Received: from linux.intel.com ([10.54.29.200]) by fmsmga008.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Nov 2023 03:21:57 -0800 Received: from mohdfai2-iLBPG12-1.png.intel.com (mohdfai2-iLBPG12-1.png.intel.com [10.88.227.73]) by linux.intel.com (Postfix) with ESMTP id BA4DE580D42; Tue, 7 Nov 2023 03:21:54 -0800 (PST) From: Faizal Rahim To: Vladimir Oltean , Vinicius Costa Gomes , Jamal Hadi Salim , Cong Wang , Jiri Pirko , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 net 1/7] net/sched: taprio: fix too early schedules switching Date: Tue, 7 Nov 2023 06:20:17 -0500 Message-Id: <20231107112023.676016-2-faizal.abdul.rahim@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231107112023.676016-1-faizal.abdul.rahim@linux.intel.com> References: <20231107112023.676016-1-faizal.abdul.rahim@linux.intel.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org In the current taprio code for dynamic schedule change, admin/oper schedule switching happens immediately when should_change_schedules() is true. Then the last entry of the old admin schedule stops being valid anymore from taprio_dequeue_from_txq’s perspective. To solve this, we have to delay the switch_schedules() call via the new cycle_time_correction variable. The variable serves 2 purposes: 1. Upon entering advance_sched(), if the value is set to a non-initialized value, it indicates that we need to change schedule. 2. Store the cycle time correction value which will be used for negative or positive correction. Fixes: a3d43c0d56f1 ("taprio: Add support adding an admin schedule") Signed-off-by: Faizal Rahim --- net/sched/sch_taprio.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index 2e1949de4171..dee103647823 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -41,6 +41,7 @@ static struct static_key_false taprio_have_working_mqprio; #define TXTIME_ASSIST_IS_ENABLED(flags) ((flags) & TCA_TAPRIO_ATTR_FLAG_TXTIME_ASSIST) #define FULL_OFFLOAD_IS_ENABLED(flags) ((flags) & TCA_TAPRIO_ATTR_FLAG_FULL_OFFLOAD) #define TAPRIO_FLAGS_INVALID U32_MAX +#define INIT_CYCLE_TIME_CORRECTION S64_MIN struct sched_entry { /* Durations between this GCL entry and the GCL entry where the @@ -75,6 +76,7 @@ struct sched_gate_list { ktime_t cycle_end_time; s64 cycle_time; s64 cycle_time_extension; + s64 cycle_time_correction; s64 base_time; }; @@ -940,8 +942,10 @@ static enum hrtimer_restart advance_sched(struct hrtimer *timer) admin = rcu_dereference_protected(q->admin_sched, lockdep_is_held(&q->current_entry_lock)); - if (!oper) + if (!oper || oper->cycle_time_correction != INIT_CYCLE_TIME_CORRECTION) { + oper->cycle_time_correction = INIT_CYCLE_TIME_CORRECTION; switch_schedules(q, &admin, &oper); + } /* This can happen in two cases: 1. this is the very first run * of this function (i.e. we weren't running any schedule @@ -981,7 +985,7 @@ static enum hrtimer_restart advance_sched(struct hrtimer *timer) * schedule runs. */ end_time = sched_base_time(admin); - switch_schedules(q, &admin, &oper); + oper->cycle_time_correction = 0; } next->end_time = end_time; @@ -1174,6 +1178,7 @@ static int parse_taprio_schedule(struct taprio_sched *q, struct nlattr **tb, } taprio_calculate_gate_durations(q, new); + new->cycle_time_correction = INIT_CYCLE_TIME_CORRECTION; return 0; } From patchwork Tue Nov 7 11:20:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Abdul Rahim, Faizal" X-Patchwork-Id: 13448530 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2F57E2D78D for ; Tue, 7 Nov 2023 11:22:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="kN5EZKwL" Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5F87BEA; Tue, 7 Nov 2023 03:22:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1699356121; x=1730892121; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=DwSdsZVrCeR+EOJgU0o0Z8bvvJ11nUwi8EXqw+a3IMY=; b=kN5EZKwLIrCQJ8OWxlFQNk4xWF/ulGdvhd3PrBD2pfW1Ig+4eVEx2yEQ 1gTXVZyYa+0YVM0Ah5a1IKUVlaZX9teo/fh73zlbXQ8AINLabANGKzj6i mi9JYNduw7GmoueeeW/kZXnDQMXToxg8oKWJHd4D2SJDiPFnBIuKAmYw7 I5bHXL99lded/mYwaxP8R74Ch1blCbGRhM5R1ZakQZVJ24smh+EP0VboE +kjjvfMeMi+9muEDPAI3tqm9x6Y9HJb/EmYHldNPvzbF7OaWDqP2U/Kix GBP6bjfNvrDCMWfsd+XRsBPQHl6cXZBRfzC+129Xin7ggYMdCFjD8NWzX A==; X-IronPort-AV: E=McAfee;i="6600,9927,10886"; a="475727114" X-IronPort-AV: E=Sophos;i="6.03,283,1694761200"; d="scan'208";a="475727114" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Nov 2023 03:22:01 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10886"; a="828579792" X-IronPort-AV: E=Sophos;i="6.03,283,1694761200"; d="scan'208";a="828579792" Received: from linux.intel.com ([10.54.29.200]) by fmsmga008.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Nov 2023 03:22:00 -0800 Received: from mohdfai2-iLBPG12-1.png.intel.com (mohdfai2-iLBPG12-1.png.intel.com [10.88.227.73]) by linux.intel.com (Postfix) with ESMTP id BE89D580D61; Tue, 7 Nov 2023 03:21:57 -0800 (PST) From: Faizal Rahim To: Vladimir Oltean , Vinicius Costa Gomes , Jamal Hadi Salim , Cong Wang , Jiri Pirko , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 net 2/7] net/sched: taprio: fix cycle time adjustment for next entry Date: Tue, 7 Nov 2023 06:20:18 -0500 Message-Id: <20231107112023.676016-3-faizal.abdul.rahim@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231107112023.676016-1-faizal.abdul.rahim@linux.intel.com> References: <20231107112023.676016-1-faizal.abdul.rahim@linux.intel.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org 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." The current taprio implementation does not extend the last old cycle in the defined manner specified in the Qbv Spec. This is part of the fix covered in this patch. Here are the changes made: 1. A new API, get_cycle_time_correction(), has been added to return the correction value. If it returns a non-initialize value, it indicates changes required for the next entry schedule, and upon the completion of the next entry's duration, entries will be loaded from the new admin schedule. 2. Store correction values in cycle_time_correction: a) Positive correction value/extension We calculate the correction between the last operational cycle and the new admin base time. Note that for positive correction to take place, the next entry should be the last entry from oper and the new admin base time falls within the next cycle time of old oper. b) Negative correction value The new admin base time starts earlier than the next entry's end time. c) Zero correction value The new admin base time aligns exactly with the old cycle. 3. When cycle_time_correction is set to a non-initialized value, it is used to: a) Indicate that cycle correction is active to trigger adjustments in affected fields like interval and cycle_time. A new API, cycle_corr_active(), has been created to help with this purpose. b) Transition to the new admin schedule at the beginning of advance_sched(). A new API, should_change_sched(), has been introduced for this purpose. 4. Remove the previous definition of should_change_scheds() API. A new should_change_sched() API has been introduced, but it serves a completely different purpose than the one that was removed. Fixes: a3d43c0d56f1 ("taprio: Add support adding an admin schedule") Signed-off-by: Faizal Rahim --- net/sched/sch_taprio.c | 105 +++++++++++++++++++++++++++-------------- 1 file changed, 70 insertions(+), 35 deletions(-) diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index dee103647823..ed32654b46f5 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -259,6 +259,14 @@ static int duration_to_length(struct taprio_sched *q, u64 duration) return div_u64(duration * PSEC_PER_NSEC, atomic64_read(&q->picos_per_byte)); } +static bool cycle_corr_active(s64 cycle_time_correction) +{ + if (cycle_time_correction == INIT_CYCLE_TIME_CORRECTION) + return false; + else + return true; +} + /* Sets sched->max_sdu[] and sched->max_frm_len[] to the minimum between the * q->max_sdu[] requested by the user and the max_sdu dynamically determined by * the maximum open gate durations at the given link speed. @@ -888,38 +896,59 @@ 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) +static bool should_change_sched(struct sched_gate_list *oper) { - ktime_t next_base_time, extension_time; + bool change_to_admin_sched = false; - if (!admin) - return false; + if (oper->cycle_time_correction != INIT_CYCLE_TIME_CORRECTION) { + /* The recent entry ran is the last one from oper */ + change_to_admin_sched = true; + oper->cycle_time_correction = INIT_CYCLE_TIME_CORRECTION; + } - next_base_time = sched_base_time(admin); + return change_to_admin_sched; +} - /* 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) +static bool should_extend_cycle(const struct sched_gate_list *oper, + ktime_t new_base_time, + ktime_t entry_end_time, + const struct sched_entry *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 ? true : false; + s64 extension_limit = oper->cycle_time_extension; + + if (extension_supported && + list_is_last(&entry->list, &oper->entries) && + ktime_before(new_base_time, next_cycle_end_time) && + ktime_sub(new_base_time, entry_end_time) < extension_limit) return true; + else + return false; +} - /* 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 s64 get_cycle_time_correction(const struct sched_gate_list *oper, + ktime_t new_base_time, + ktime_t entry_end_time, + const struct sched_entry *entry) +{ + s64 correction = INIT_CYCLE_TIME_CORRECTION; - /* 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; + if (!entry || !oper) + return correction; - return false; + if (ktime_compare(new_base_time, entry_end_time) <= 0) { + /* negative or zero correction */ + correction = ktime_sub(new_base_time, entry_end_time); + } else if (ktime_after(new_base_time, entry_end_time) && + should_extend_cycle(oper, new_base_time, + entry_end_time, entry)) { + /* positive correction */ + correction = ktime_sub(new_base_time, entry_end_time); + } + + return correction; } static enum hrtimer_restart advance_sched(struct hrtimer *timer) @@ -942,10 +971,8 @@ static enum hrtimer_restart advance_sched(struct hrtimer *timer) admin = rcu_dereference_protected(q->admin_sched, lockdep_is_held(&q->current_entry_lock)); - if (!oper || oper->cycle_time_correction != INIT_CYCLE_TIME_CORRECTION) { - oper->cycle_time_correction = INIT_CYCLE_TIME_CORRECTION; + if (!oper || should_change_sched(oper)) switch_schedules(q, &admin, &oper); - } /* This can happen in two cases: 1. this is the very first run * of this function (i.e. we weren't running any schedule @@ -972,6 +999,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 (cycle_corr_active(oper->cycle_time_correction)) { + /* 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; @@ -980,14 +1023,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); From patchwork Tue Nov 7 11:20:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Abdul Rahim, Faizal" X-Patchwork-Id: 13448531 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1B82E2D7AE for ; Tue, 7 Nov 2023 11:22:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="LxRK7ZcQ" Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 74EDD113; Tue, 7 Nov 2023 03:22:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1699356124; x=1730892124; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=cjQy5UhxJgB9eTPnA9Pr3M7tSlose1KGFKMwLXqwwPs=; b=LxRK7ZcQ9IUBb11HgDocBBtPFui3sx7r3f/iY8LemD3C7ovwtBqxEoYr uzftDDs0J740qGD/2HOw4UfpCnNWjKtjRregmR7wy7oVUGncAlhBnTPPZ fMdoWXichS4/PJ9x1ivDMxMn2n62yHPGcJTlxMw7dwWgMckPs5aEV3Gbm igAtwnoiNTwNAB+uMkYnZmqSVxBOJebRfV+Yr4DPOohpEc+qTV8bf/VCM ByTx2j5ubV87WqOEGR7AKfGXf+qcPz8Oa4B74Y/4Iq6OfMpOxFhA//D/l pyCNJl7ixe8UvqHofr+nY7FExaCBv9APGTIWI6zxbO3ILYYlIMJDgkwRs Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10886"; a="475727127" X-IronPort-AV: E=Sophos;i="6.03,283,1694761200"; d="scan'208";a="475727127" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Nov 2023 03:22:04 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10886"; a="828579811" X-IronPort-AV: E=Sophos;i="6.03,283,1694761200"; d="scan'208";a="828579811" Received: from linux.intel.com ([10.54.29.200]) by fmsmga008.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Nov 2023 03:22:03 -0800 Received: from mohdfai2-iLBPG12-1.png.intel.com (mohdfai2-iLBPG12-1.png.intel.com [10.88.227.73]) by linux.intel.com (Postfix) with ESMTP id E9FD4580D99; Tue, 7 Nov 2023 03:22:00 -0800 (PST) From: Faizal Rahim To: Vladimir Oltean , Vinicius Costa Gomes , Jamal Hadi Salim , Cong Wang , Jiri Pirko , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 net 3/7] net/sched: taprio: update impacted fields during cycle time adjustment Date: Tue, 7 Nov 2023 06:20:19 -0500 Message-Id: <20231107112023.676016-4-faizal.abdul.rahim@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231107112023.676016-1-faizal.abdul.rahim@linux.intel.com> References: <20231107112023.676016-1-faizal.abdul.rahim@linux.intel.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org Update impacted fields in advance_sched() if cycle_corr_active() is true, which indicates that the next entry is the last entry from oper that it will run. Update impacted fields: 1. gate_duration[tc], max_open_gate_duration[tc] Created a new API update_open_gate_duration().The API sets the duration based on the last remaining entry, the original value was based on consideration of multiple entries. 2. gate_close_time[tc] Update next entry gate close time according to the new admin base time 3. max_sdu[tc], budget[tc] Restrict from setting to max value because there's only a single entry left to run from oper before changing to the new admin schedule, so we shouldn't set to max. Signed-off-by: Faizal Rahim --- net/sched/sch_taprio.c | 49 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index ed32654b46f5..119dec3bbe88 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -288,7 +288,8 @@ static void taprio_update_queue_max_sdu(struct taprio_sched *q, /* TC gate never closes => keep the queueMaxSDU * selected by the user */ - if (sched->max_open_gate_duration[tc] == sched->cycle_time) { + if (sched->max_open_gate_duration[tc] == sched->cycle_time && + !cycle_corr_active(sched->cycle_time_correction)) { max_sdu_dynamic = U32_MAX; } else { u32 max_frm_len; @@ -684,7 +685,8 @@ static void taprio_set_budgets(struct taprio_sched *q, for (tc = 0; tc < num_tc; tc++) { /* Traffic classes which never close have infinite budget */ - if (entry->gate_duration[tc] == sched->cycle_time) + if (entry->gate_duration[tc] == sched->cycle_time && + !cycle_corr_active(sched->cycle_time_correction)) budget = INT_MAX; else budget = div64_u64((u64)entry->gate_duration[tc] * PSEC_PER_NSEC, @@ -896,6 +898,32 @@ static bool should_restart_cycle(const struct sched_gate_list *oper, return false; } +/* Open gate duration were calculated at the beginning with consideration of + * multiple entries. If cycle time correction is active, there's only a single + * remaining entry left from oper to run. + * Update open gate duration based on this last entry. + */ +static void update_open_gate_duration(struct sched_entry *entry, + struct sched_gate_list *oper, + int num_tc, + u64 open_gate_duration) +{ + int tc; + + if (!entry || !oper) + return; + + for (tc = 0; tc < num_tc; tc++) { + if (entry->gate_mask & BIT(tc)) { + entry->gate_duration[tc] = open_gate_duration; + oper->max_open_gate_duration[tc] = open_gate_duration; + } else { + entry->gate_duration[tc] = 0; + oper->max_open_gate_duration[tc] = 0; + } + } +} + static bool should_change_sched(struct sched_gate_list *oper) { bool change_to_admin_sched = false; @@ -1010,13 +1038,28 @@ static enum hrtimer_restart advance_sched(struct hrtimer *timer) /* The next entry is the last entry we will run from * oper, subsequent ones will take from the new admin */ + u64 new_gate_duration = + next->interval + oper->cycle_time_correction; + struct qdisc_size_table *stab = + rtnl_dereference(q->root->stab); + oper->cycle_end_time = new_base_time; end_time = new_base_time; + + update_open_gate_duration(next, oper, num_tc, + new_gate_duration); + taprio_update_queue_max_sdu(q, oper, stab); } } for (tc = 0; tc < num_tc; tc++) { - if (next->gate_duration[tc] == oper->cycle_time) + if (cycle_corr_active(oper->cycle_time_correction) && + (next->gate_mask & BIT(tc))) + /* Set to the new base time, ensuring a smooth transition + * to the new schedule when the next entry finishes. + */ + next->gate_close_time[tc] = end_time; + else if (next->gate_duration[tc] == oper->cycle_time) next->gate_close_time[tc] = KTIME_MAX; else next->gate_close_time[tc] = ktime_add_ns(entry->end_time, From patchwork Tue Nov 7 11:20:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Abdul Rahim, Faizal" X-Patchwork-Id: 13448532 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0EF852D79B for ; Tue, 7 Nov 2023 11:22:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Nw+Auw9g" Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EBB6CD76; Tue, 7 Nov 2023 03:22:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1699356129; x=1730892129; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=GYJFMseSRujrlOpQy9nErngkfh/08yp/LL0rLTrMXX8=; b=Nw+Auw9gW2dGUUuus6TzEmtVT8l/3GXveBXhiRhoLAtHh+IXAkclLPfz +6hRXbTATk3oDndL5/ldf5mMWC2tdSWR0DxXMqufC4LY6+VZBHm7HtIAQ C1V8JYB+KRGB3k7n+DE+oi2BpdKB7bfQoHB9qZ66Gqwsd6hE2yMABCe1C Q2EDV/2YFUGsuH/SFnMhHBjJ5VDESHDxKvpJjhPpMjqVQVjoyYfK8pbXc 2lpiJR5g22cjxTQ9SX3t33Dl0Zs5ALdEZGz6oyi1OGt2dTXsc+xkdwN3r Ll0qlsn8yBW1577igwQxLba2YQ0Q7Tcuf+MKbd/7sSNK5PssqIa+k3JFk w==; X-IronPort-AV: E=McAfee;i="6600,9927,10886"; a="393382961" X-IronPort-AV: E=Sophos;i="6.03,283,1694761200"; d="scan'208";a="393382961" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Nov 2023 03:22:07 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10886"; a="766285598" X-IronPort-AV: E=Sophos;i="6.03,283,1694761200"; d="scan'208";a="766285598" Received: from linux.intel.com ([10.54.29.200]) by fmsmga007.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Nov 2023 03:22:06 -0800 Received: from mohdfai2-iLBPG12-1.png.intel.com (mohdfai2-iLBPG12-1.png.intel.com [10.88.227.73]) by linux.intel.com (Postfix) with ESMTP id DC3CA580D42; Tue, 7 Nov 2023 03:22:03 -0800 (PST) From: Faizal Rahim To: Vladimir Oltean , Vinicius Costa Gomes , Jamal Hadi Salim , Cong Wang , Jiri Pirko , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 net 4/7] net/sched: taprio: get corrected value of cycle_time and interval Date: Tue, 7 Nov 2023 06:20:20 -0500 Message-Id: <20231107112023.676016-5-faizal.abdul.rahim@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231107112023.676016-1-faizal.abdul.rahim@linux.intel.com> References: <20231107112023.676016-1-faizal.abdul.rahim@linux.intel.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org Retrieve adjusted cycle_time and interval values through new APIs. Note that in some cases where the original values are required, such as in dump_schedule() and setup_first_end_time(), direct calls to cycle_time and interval are retained without using the new APIs. Added a new field, correction_active, in the sched_entry struct to determine the entry's correction state. This field is required due to specific flow like find_entry_to_transmit() -> get_interval_end_time() which retrieves the interval for each entry. During positive cycle time correction, it's known that the last entry interval requires correction. However, for negative correction, the affected entry is unknown, which is why this new field is necessary. Signed-off-by: Faizal Rahim --- net/sched/sch_taprio.c | 50 ++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index 119dec3bbe88..f18a5fe12f0c 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -61,6 +61,7 @@ struct sched_entry { u32 gate_mask; u32 interval; u8 command; + bool correction_active; }; struct sched_gate_list { @@ -215,6 +216,31 @@ static void switch_schedules(struct taprio_sched *q, *admin = NULL; } +static bool cycle_corr_active(s64 cycle_time_correction) +{ + if (cycle_time_correction == INIT_CYCLE_TIME_CORRECTION) + return false; + else + return true; +} + +u32 get_interval(const struct sched_entry *entry, + const struct sched_gate_list *oper) +{ + if (entry->correction_active) + return entry->interval + oper->cycle_time_correction; + else + return entry->interval; +} + +s64 get_cycle_time(const struct sched_gate_list *oper) +{ + if (cycle_corr_active(oper->cycle_time_correction)) + return oper->cycle_time + oper->cycle_time_correction; + else + return oper->cycle_time; +} + /* Get how much time has been already elapsed in the current cycle. */ static s32 get_cycle_time_elapsed(struct sched_gate_list *sched, ktime_t time) { @@ -222,7 +248,7 @@ static s32 get_cycle_time_elapsed(struct sched_gate_list *sched, ktime_t time) s32 time_elapsed; time_since_sched_start = ktime_sub(time, sched->base_time); - div_s64_rem(time_since_sched_start, sched->cycle_time, &time_elapsed); + div_s64_rem(time_since_sched_start, get_cycle_time(sched), &time_elapsed); return time_elapsed; } @@ -235,8 +261,9 @@ static ktime_t get_interval_end_time(struct sched_gate_list *sched, s32 cycle_elapsed = get_cycle_time_elapsed(sched, intv_start); ktime_t intv_end, cycle_ext_end, cycle_end; - cycle_end = ktime_add_ns(intv_start, sched->cycle_time - cycle_elapsed); - intv_end = ktime_add_ns(intv_start, entry->interval); + cycle_end = ktime_add_ns(intv_start, + get_cycle_time(sched) - cycle_elapsed); + intv_end = ktime_add_ns(intv_start, get_interval(entry, sched)); cycle_ext_end = ktime_add(cycle_end, sched->cycle_time_extension); if (ktime_before(intv_end, cycle_end)) @@ -259,14 +286,6 @@ static int duration_to_length(struct taprio_sched *q, u64 duration) return div_u64(duration * PSEC_PER_NSEC, atomic64_read(&q->picos_per_byte)); } -static bool cycle_corr_active(s64 cycle_time_correction) -{ - if (cycle_time_correction == INIT_CYCLE_TIME_CORRECTION) - return false; - else - return true; -} - /* Sets sched->max_sdu[] and sched->max_frm_len[] to the minimum between the * q->max_sdu[] requested by the user and the max_sdu dynamically determined by * the maximum open gate durations at the given link speed. @@ -351,7 +370,7 @@ static struct sched_entry *find_entry_to_transmit(struct sk_buff *skb, if (!sched) return NULL; - cycle = sched->cycle_time; + cycle = get_cycle_time(sched); cycle_elapsed = get_cycle_time_elapsed(sched, time); curr_intv_end = ktime_sub_ns(time, cycle_elapsed); cycle_end = ktime_add_ns(curr_intv_end, cycle); @@ -365,7 +384,7 @@ static struct sched_entry *find_entry_to_transmit(struct sk_buff *skb, break; if (!(entry->gate_mask & BIT(tc)) || - packet_transmit_time > entry->interval) + packet_transmit_time > get_interval(entry, sched)) continue; txtime = entry->next_txtime; @@ -543,7 +562,8 @@ static long get_packet_txtime(struct sk_buff *skb, struct Qdisc *sch) * interval starts. */ if (ktime_after(transmit_end_time, interval_end)) - entry->next_txtime = ktime_add(interval_start, sched->cycle_time); + entry->next_txtime = + ktime_add(interval_start, get_cycle_time(sched)); } while (sched_changed || ktime_after(transmit_end_time, interval_end)); entry->next_txtime = transmit_end_time; @@ -1045,6 +1065,7 @@ static enum hrtimer_restart advance_sched(struct hrtimer *timer) oper->cycle_end_time = new_base_time; end_time = new_base_time; + next->correction_active = true; update_open_gate_duration(next, oper, num_tc, new_gate_duration); @@ -1146,6 +1167,7 @@ static int fill_sched_entry(struct taprio_sched *q, struct nlattr **tb, } entry->interval = interval; + entry->correction_active = false; return 0; } From patchwork Tue Nov 7 11:20:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Abdul Rahim, Faizal" X-Patchwork-Id: 13448533 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 583362D7A7 for ; Tue, 7 Nov 2023 11:22:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="TMO5VeKS" Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 558AB10C6; Tue, 7 Nov 2023 03:22:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1699356130; x=1730892130; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=bvsXSr+H0OXz+tRvroL/Z/VRfDIrygnvWqBJ8snWfQQ=; b=TMO5VeKSiwfifm1LlFGCxbLJUJzYbl/zuapI0R+rT3VyInrGwS3bzkox vLr40PwlQ2wFD3BuxEgX6pXRScVG85zMISeqo6ubjNG2nWqcmjruchYND ygaJCkbS2w+V/QXP6aUUpCK+QpAL/F9dyIcHbD3H5f9zk/LvVBt2NxdD/ JHQ4dzUJevjnw67Xn0GCpIEYyQzZd9qZy451TtBGCaTdLHRQyewxqWVLS uursO/m2ZcMM1Zw2ql6J4VTgd448DMrEkNR8bVZtDMtOfovG28bsuybIP XdqHkKRGjmJfzHti8AC+A5ooJNI21ykwSZgpq7e1cQDi+noE8RwcXeXYc A==; X-IronPort-AV: E=McAfee;i="6600,9927,10886"; a="475727154" X-IronPort-AV: E=Sophos;i="6.03,283,1694761200"; d="scan'208";a="475727154" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Nov 2023 03:22:09 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10886"; a="828579830" X-IronPort-AV: E=Sophos;i="6.03,283,1694761200"; d="scan'208";a="828579830" Received: from linux.intel.com ([10.54.29.200]) by fmsmga008.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Nov 2023 03:22:09 -0800 Received: from mohdfai2-iLBPG12-1.png.intel.com (mohdfai2-iLBPG12-1.png.intel.com [10.88.227.73]) by linux.intel.com (Postfix) with ESMTP id D5251580DC7; Tue, 7 Nov 2023 03:22:06 -0800 (PST) From: Faizal Rahim To: Vladimir Oltean , Vinicius Costa Gomes , Jamal Hadi Salim , Cong Wang , Jiri Pirko , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 net 5/7] net/sched: taprio: fix delayed switching to new schedule after timer expiry Date: Tue, 7 Nov 2023 06:20:21 -0500 Message-Id: <20231107112023.676016-6-faizal.abdul.rahim@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231107112023.676016-1-faizal.abdul.rahim@linux.intel.com> References: <20231107112023.676016-1-faizal.abdul.rahim@linux.intel.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org If a new GCL is triggered and the new admin base time falls before the expiry of advance_timer (current running entry from oper), taprio_start_sched() resets the current advance_timer expiry to the new admin base time. However, upon expiry, advance_sched() doesn't immediately switch to the admin schedule. It continues running entries from the old oper schedule, and only switches to the new admin schedule much later. Ideally, if the advance_timer is shorten to align with the new admin base time, when the timer expires, advance_sched() should trigger switch_schedules() at the beginning. To resolve this issue, set the cycle_time_correction to a non-initialized value in taprio_start_sched(). advance_sched() will use it to initiate switch_schedules() at the beginning. Fixes: a3d43c0d56f1 ("taprio: Add support adding an admin schedule") Signed-off-by: Faizal Rahim --- net/sched/sch_taprio.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index f18a5fe12f0c..01b114edec30 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -1379,14 +1379,19 @@ static void setup_first_end_time(struct taprio_sched *q, } static void taprio_start_sched(struct Qdisc *sch, - ktime_t start, struct sched_gate_list *new) + ktime_t new_base_time, + struct sched_gate_list *new) { struct taprio_sched *q = qdisc_priv(sch); - ktime_t expires; + struct sched_gate_list *oper = NULL; + ktime_t expires, start; if (FULL_OFFLOAD_IS_ENABLED(q->flags)) return; + oper = rcu_dereference_protected(q->oper_sched, + lockdep_is_held(&q->current_entry_lock)); + expires = hrtimer_get_expires(&q->advance_timer); if (expires == 0) expires = KTIME_MAX; @@ -1395,7 +1400,17 @@ static void taprio_start_sched(struct Qdisc *sch, * reprogram it to the earliest one, so we change the admin * schedule to the operational one at the right time. */ - start = min_t(ktime_t, start, expires); + start = min_t(ktime_t, new_base_time, expires); + + if (expires != KTIME_MAX && + ktime_compare(start, new_base_time) == 0) { + /* Since timer was changed to align to the new admin schedule, + * setting the variable below to a non-initialized value will + * indicate to advance_sched() to call switch_schedules() after + * this timer expires. + */ + oper->cycle_time_correction = 0; + } hrtimer_start(&q->advance_timer, start, HRTIMER_MODE_ABS); } From patchwork Tue Nov 7 11:20:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Abdul Rahim, Faizal" X-Patchwork-Id: 13448534 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 893AE12E4F for ; Tue, 7 Nov 2023 11:22:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="auywIVi2" Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E0BB4ED; Tue, 7 Nov 2023 03:22:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1699356134; x=1730892134; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=tTJNmm6maYeBIBNzxeaSXpjj2cPTvW1Qy7oFWpBrI8M=; b=auywIVi2HFm3cqYdNE/C9pvqVjocLzhsBptAiZwCVqYNEjbfgYNCPsG5 md85ps8gCX8Fu5v8/XsN+XcBmcfk+2GCTvryrAoxxMPncvbvW9zTZXgqK INMA5KaKw1aXUspSrFn7e380L4b8DEaTuwVYHKHWveSz/djjiXjb19xxD xECseTfey3kfA0RNLVibWVNRylW+rPFJMMKUQVwsqowK6YRZoSZ1hCxf6 ssVsx62t4NnsWtcmg3Pdsg0VRjWIUsyvg4sHnZ5kcXMZyllVtWFE4fsSR hfLm9QsuwlPfbYAgTzVyd5VcaXSiRIvFBP6v/P+kNyJW7VlNNuIht/8vb g==; X-IronPort-AV: E=McAfee;i="6600,9927,10886"; a="393382991" X-IronPort-AV: E=Sophos;i="6.03,283,1694761200"; d="scan'208";a="393382991" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Nov 2023 03:22:13 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10886"; a="766285654" X-IronPort-AV: E=Sophos;i="6.03,283,1694761200"; d="scan'208";a="766285654" Received: from linux.intel.com ([10.54.29.200]) by fmsmga007.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Nov 2023 03:22:12 -0800 Received: from mohdfai2-iLBPG12-1.png.intel.com (mohdfai2-iLBPG12-1.png.intel.com [10.88.227.73]) by linux.intel.com (Postfix) with ESMTP id C8862580D61; Tue, 7 Nov 2023 03:22:09 -0800 (PST) From: Faizal Rahim To: Vladimir Oltean , Vinicius Costa Gomes , Jamal Hadi Salim , Cong Wang , Jiri Pirko , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 net 6/7] net/sched: taprio: fix q->current_entry is NULL before its expiry Date: Tue, 7 Nov 2023 06:20:22 -0500 Message-Id: <20231107112023.676016-7-faizal.abdul.rahim@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231107112023.676016-1-faizal.abdul.rahim@linux.intel.com> References: <20231107112023.676016-1-faizal.abdul.rahim@linux.intel.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org Fix the issue of prematurely setting q->current_entry to NULL in the setup_first_end_time() function when a new admin schedule arrives while the oper schedule is still running but hasn't transitioned yet. This premature setting causes problems because any reference to q->current_entry, such as in taprio_dequeue(), will result in NULL during this period, which is incorrect. q->current_entry should remain valid until the currently running entry expires. To address this issue, only set q->current_entry to NULL when there is no oper schedule currently running. Fixes: 5a781ccbd19e ("tc: Add support for configuring the taprio scheduler") Signed-off-by: Faizal Rahim --- net/sched/sch_taprio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index 01b114edec30..c60e9e7ac193 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -1375,7 +1375,8 @@ static void setup_first_end_time(struct taprio_sched *q, first->gate_close_time[tc] = ktime_add_ns(base, first->gate_duration[tc]); } - rcu_assign_pointer(q->current_entry, NULL); + if (!hrtimer_active(&q->advance_timer)) + rcu_assign_pointer(q->current_entry, NULL); } static void taprio_start_sched(struct Qdisc *sch, From patchwork Tue Nov 7 11:20:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Abdul Rahim, Faizal" X-Patchwork-Id: 13448535 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 90C152D797 for ; Tue, 7 Nov 2023 11:22:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="f5ptr/sy" Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 166A4102; Tue, 7 Nov 2023 03:22:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1699356137; x=1730892137; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=pMF+9nUTYtcxwogA5ZhYPefFB2v1RKbC8j7RIB/pdhg=; b=f5ptr/sy11mrBMmNnw8f9I3to9POOIt7PHhGzAOWYrmHGAxW70duPcze 1T/kWLj2mDw9TgavTnyZQogmKl05XREejgDoDx+V0wn56GyVopcHCmSNB KJsa76hU+w1MDPvkL0l0CSMYiXh2D+8JqSA3erEWsxc3CU1LU1JdkGDWF KwCrdugGnfeRpcoEbZFlYxWxOyMP/c2Hwi+Up517dT4HD4yO9FaAJJlM7 eSiiR0x9PC5PBcOMkZikeYrdjP1jQGRejS3bWuKrWU7D17pKn6MhKxpjh pw7b+iwNKwmgRIGUuhlG2tS28ItfBrHZrBGdpwV0D1Jrnj0plMOcyXu38 A==; X-IronPort-AV: E=McAfee;i="6600,9927,10886"; a="475727186" X-IronPort-AV: E=Sophos;i="6.03,283,1694761200"; d="scan'208";a="475727186" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Nov 2023 03:22:15 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10886"; a="828579865" X-IronPort-AV: E=Sophos;i="6.03,283,1694761200"; d="scan'208";a="828579865" Received: from linux.intel.com ([10.54.29.200]) by fmsmga008.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Nov 2023 03:22:15 -0800 Received: from mohdfai2-iLBPG12-1.png.intel.com (mohdfai2-iLBPG12-1.png.intel.com [10.88.227.73]) by linux.intel.com (Postfix) with ESMTP id BE5BC580D42; Tue, 7 Nov 2023 03:22:12 -0800 (PST) From: Faizal Rahim To: Vladimir Oltean , Vinicius Costa Gomes , Jamal Hadi Salim , Cong Wang , Jiri Pirko , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 net 7/7] net/sched: taprio: enable cycle time adjustment for current entry Date: Tue, 7 Nov 2023 06:20:23 -0500 Message-Id: <20231107112023.676016-8-faizal.abdul.rahim@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231107112023.676016-1-faizal.abdul.rahim@linux.intel.com> References: <20231107112023.676016-1-faizal.abdul.rahim@linux.intel.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org Handles cycle time adjustments for the current active entry when new admin base time occurs quickly, either within the current entry or the next one. Changes covers: 1. Negative cycle correction or truncation Occurs when the new admin base time falls before the expiry of the current running entry. 2. Positive cycle correction or extension Occurs when the new admin base time falls within the next entry, and the current entry is the cycle's last entry. In this case, the changes in taprio_start_sched() extends the schedule, preventing old oper schedule from resuming and getting truncated in the next advance_sched() call. 3. A new API, update_gate_close_time(), has been created to update the gate_close_time of the current entry in the event of cycle correction. Signed-off-by: Faizal Rahim --- net/sched/sch_taprio.c | 72 +++++++++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 19 deletions(-) diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index c60e9e7ac193..56743754d42e 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -1379,41 +1379,75 @@ static void setup_first_end_time(struct taprio_sched *q, rcu_assign_pointer(q->current_entry, NULL); } +static void update_gate_close_time(struct sched_entry *current_entry, + ktime_t new_end_time, + int num_tc) +{ + int tc; + + for (tc = 0; tc < num_tc; tc++) { + if (current_entry->gate_mask & BIT(tc)) + current_entry->gate_close_time[tc] = new_end_time; + } +} + static void taprio_start_sched(struct Qdisc *sch, ktime_t new_base_time, - struct sched_gate_list *new) + struct sched_gate_list *admin) { struct taprio_sched *q = qdisc_priv(sch); + ktime_t expires = hrtimer_get_expires(&q->advance_timer); + struct net_device *dev = qdisc_dev(q->root); + struct sched_entry *curr_entry = NULL; struct sched_gate_list *oper = NULL; - ktime_t expires, start; if (FULL_OFFLOAD_IS_ENABLED(q->flags)) return; oper = rcu_dereference_protected(q->oper_sched, lockdep_is_held(&q->current_entry_lock)); + curr_entry = rcu_dereference_protected(q->current_entry, + lockdep_is_held(&q->current_entry_lock)); - expires = hrtimer_get_expires(&q->advance_timer); - if (expires == 0) - expires = KTIME_MAX; + if (hrtimer_active(&q->advance_timer)) { + oper->cycle_time_correction = + get_cycle_time_correction(oper, new_base_time, + curr_entry->end_time, + curr_entry); - /* If the new schedule starts before the next expiration, we - * reprogram it to the earliest one, so we change the admin - * schedule to the operational one at the right time. - */ - start = min_t(ktime_t, new_base_time, expires); - - if (expires != KTIME_MAX && - ktime_compare(start, new_base_time) == 0) { - /* Since timer was changed to align to the new admin schedule, - * setting the variable below to a non-initialized value will - * indicate to advance_sched() to call switch_schedules() after - * this timer expires. + if (cycle_corr_active(oper->cycle_time_correction)) { + /* This is the last entry we are running from oper, + * subsequent entry will take from the new admin. + */ + ktime_t now = taprio_get_time(q); + u64 gate_duration_left = ktime_sub(new_base_time, now); + struct qdisc_size_table *stab = + rtnl_dereference(q->root->stab); + int num_tc = netdev_get_num_tc(dev); + + oper->cycle_end_time = new_base_time; + curr_entry->end_time = new_base_time; + curr_entry->correction_active = true; + + update_open_gate_duration(curr_entry, oper, num_tc, + gate_duration_left); + update_gate_close_time(curr_entry, new_base_time, num_tc); + taprio_update_queue_max_sdu(q, oper, stab); + taprio_set_budgets(q, oper, curr_entry); + } + } + + if (!hrtimer_active(&q->advance_timer) || + cycle_corr_active(oper->cycle_time_correction)) { + /* Use new admin base time if : + * 1. there's no active oper + * 2. there's active oper and we will change to the new admin + * schedule after the current entry from oper ends */ - oper->cycle_time_correction = 0; + expires = new_base_time; } - hrtimer_start(&q->advance_timer, start, HRTIMER_MODE_ABS); + hrtimer_start(&q->advance_timer, expires, HRTIMER_MODE_ABS); } static void taprio_set_picos_per_byte(struct net_device *dev,