From nobody Wed Dec 31 04:51:38 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 41241C4332F for ; Tue, 7 Nov 2023 11:22:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234241AbjKGLWD (ORCPT ); Tue, 7 Nov 2023 06:22:03 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45230 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233996AbjKGLWA (ORCPT ); Tue, 7 Nov 2023 06:22:00 -0500 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> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.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=E2=80=99s 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_TX= TIME_ASSIST) #define FULL_OFFLOAD_IS_ENABLED(flags) ((flags) & TCA_TAPRIO_ATTR_FLAG_FUL= L_OFFLOAD) #define TAPRIO_FLAGS_INVALID U32_MAX +#define INIT_CYCLE_TIME_CORRECTION S64_MIN =20 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; }; =20 @@ -940,8 +942,10 @@ static enum hrtimer_restart advance_sched(struct hrtim= er *timer) admin =3D rcu_dereference_protected(q->admin_sched, lockdep_is_held(&q->current_entry_lock)); =20 - if (!oper) + if (!oper || oper->cycle_time_correction !=3D INIT_CYCLE_TIME_CORRECTION)= { + oper->cycle_time_correction =3D INIT_CYCLE_TIME_CORRECTION; switch_schedules(q, &admin, &oper); + } =20 /* 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 hrtime= r *timer) * schedule runs. */ end_time =3D sched_base_time(admin); - switch_schedules(q, &admin, &oper); + oper->cycle_time_correction =3D 0; } =20 next->end_time =3D end_time; @@ -1174,6 +1178,7 @@ static int parse_taprio_schedule(struct taprio_sched = *q, struct nlattr **tb, } =20 taprio_calculate_gate_durations(q, new); + new->cycle_time_correction =3D INIT_CYCLE_TIME_CORRECTION; =20 return 0; } --=20 2.25.1 From nobody Wed Dec 31 04:51:38 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 96BA4C4167D for ; Tue, 7 Nov 2023 11:22:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234290AbjKGLWI (ORCPT ); Tue, 7 Nov 2023 06:22:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45238 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233996AbjKGLWE (ORCPT ); Tue, 7 Nov 2023 06:22:04 -0500 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> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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= )); } =20 +static bool cycle_corr_active(s64 cycle_time_correction) +{ + if (cycle_time_correction =3D=3D INIT_CYCLE_TIME_CORRECTION) + return false; + else + return true; +} + /* Sets sched->max_sdu[] and sched->max_frm_len[] to the minimum between t= he * q->max_sdu[] requested by the user and the max_sdu dynamically determin= ed by * the maximum open gate durations at the given link speed. @@ -888,38 +896,59 @@ static bool should_restart_cycle(const struct sched_g= ate_list *oper, return false; } =20 -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 =3D false; =20 - if (!admin) - return false; + if (oper->cycle_time_correction !=3D INIT_CYCLE_TIME_CORRECTION) { + /* The recent entry ran is the last one from oper */ + change_to_admin_sched =3D true; + oper->cycle_time_correction =3D INIT_CYCLE_TIME_CORRECTION; + } =20 - next_base_time =3D sched_base_time(admin); + return change_to_admin_sched; +} =20 - /* This is the simple case, the end_time would fall after - * the next schedule base_time. - */ - if (ktime_compare(next_base_time, end_time) <=3D 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 =3D ktime_add_ns(oper->cycle_end_time, + oper->cycle_time); + bool extension_supported =3D oper->cycle_time_extension > 0 ? true : fals= e; + s64 extension_limit =3D 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; +} =20 - /* 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 =3D 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 =3D INIT_CYCLE_TIME_CORRECTION; =20 - /* 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) <=3D 0) - return true; + if (!entry || !oper) + return correction; =20 - return false; + if (ktime_compare(new_base_time, entry_end_time) <=3D 0) { + /* negative or zero correction */ + correction =3D 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 =3D ktime_sub(new_base_time, entry_end_time); + } + + return correction; } =20 static enum hrtimer_restart advance_sched(struct hrtimer *timer) @@ -942,10 +971,8 @@ static enum hrtimer_restart advance_sched(struct hrtim= er *timer) admin =3D rcu_dereference_protected(q->admin_sched, lockdep_is_held(&q->current_entry_lock)); =20 - if (!oper || oper->cycle_time_correction !=3D INIT_CYCLE_TIME_CORRECTION)= { - oper->cycle_time_correction =3D INIT_CYCLE_TIME_CORRECTION; + if (!oper || should_change_sched(oper)) switch_schedules(q, &admin, &oper); - } =20 /* 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 hrtim= er *timer) end_time =3D ktime_add_ns(entry->end_time, next->interval); end_time =3D min_t(ktime_t, end_time, oper->cycle_end_time); =20 + if (admin) { + ktime_t new_base_time =3D sched_base_time(admin); + + oper->cycle_time_correction =3D + 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 =3D new_base_time; + end_time =3D new_base_time; + } + } + for (tc =3D 0; tc < num_tc; tc++) { if (next->gate_duration[tc] =3D=3D oper->cycle_time) next->gate_close_time[tc] =3D KTIME_MAX; @@ -980,14 +1023,6 @@ static enum hrtimer_restart advance_sched(struct hrti= mer *timer) next->gate_duration[tc]); } =20 - if (should_change_schedules(admin, oper, end_time)) { - /* Set things so the next time this runs, the new - * schedule runs. - */ - end_time =3D sched_base_time(admin); - oper->cycle_time_correction =3D 0; - } - next->end_time =3D end_time; taprio_set_budgets(q, oper, next); =20 --=20 2.25.1 From nobody Wed Dec 31 04:51:38 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7BDD4C4167B for ; Tue, 7 Nov 2023 11:22:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234176AbjKGLWJ (ORCPT ); Tue, 7 Nov 2023 06:22:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39632 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234288AbjKGLWH (ORCPT ); Tue, 7 Nov 2023 06:22:07 -0500 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> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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_s= ched *q, /* TC gate never closes =3D> keep the queueMaxSDU * selected by the user */ - if (sched->max_open_gate_duration[tc] =3D=3D sched->cycle_time) { + if (sched->max_open_gate_duration[tc] =3D=3D sched->cycle_time && + !cycle_corr_active(sched->cycle_time_correction)) { max_sdu_dynamic =3D U32_MAX; } else { u32 max_frm_len; @@ -684,7 +685,8 @@ static void taprio_set_budgets(struct taprio_sched *q, =20 for (tc =3D 0; tc < num_tc; tc++) { /* Traffic classes which never close have infinite budget */ - if (entry->gate_duration[tc] =3D=3D sched->cycle_time) + if (entry->gate_duration[tc] =3D=3D sched->cycle_time && + !cycle_corr_active(sched->cycle_time_correction)) budget =3D INT_MAX; else budget =3D div64_u64((u64)entry->gate_duration[tc] * PSEC_PER_NSEC, @@ -896,6 +898,32 @@ static bool should_restart_cycle(const struct sched_ga= te_list *oper, return false; } =20 +/* Open gate duration were calculated at the beginning with consideration = of + * multiple entries. If cycle time correction is active, there's only a si= ngle + * 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 =3D 0; tc < num_tc; tc++) { + if (entry->gate_mask & BIT(tc)) { + entry->gate_duration[tc] =3D open_gate_duration; + oper->max_open_gate_duration[tc] =3D open_gate_duration; + } else { + entry->gate_duration[tc] =3D 0; + oper->max_open_gate_duration[tc] =3D 0; + } + } +} + static bool should_change_sched(struct sched_gate_list *oper) { bool change_to_admin_sched =3D false; @@ -1010,13 +1038,28 @@ static enum hrtimer_restart advance_sched(struct hr= timer *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 =3D + next->interval + oper->cycle_time_correction; + struct qdisc_size_table *stab =3D + rtnl_dereference(q->root->stab); + oper->cycle_end_time =3D new_base_time; end_time =3D new_base_time; + + update_open_gate_duration(next, oper, num_tc, + new_gate_duration); + taprio_update_queue_max_sdu(q, oper, stab); } } =20 for (tc =3D 0; tc < num_tc; tc++) { - if (next->gate_duration[tc] =3D=3D 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] =3D end_time; + else if (next->gate_duration[tc] =3D=3D oper->cycle_time) next->gate_close_time[tc] =3D KTIME_MAX; else next->gate_close_time[tc] =3D ktime_add_ns(entry->end_time, --=20 2.25.1 From nobody Wed Dec 31 04:51:38 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 29F3AC4332F for ; Tue, 7 Nov 2023 11:22:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234339AbjKGLWW (ORCPT ); Tue, 7 Nov 2023 06:22:22 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39858 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234313AbjKGLWR (ORCPT ); Tue, 7 Nov 2023 06:22:17 -0500 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> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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; }; =20 struct sched_gate_list { @@ -215,6 +216,31 @@ static void switch_schedules(struct taprio_sched *q, *admin =3D NULL; } =20 +static bool cycle_corr_active(s64 cycle_time_correction) +{ + if (cycle_time_correction =3D=3D 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 t= ime) { @@ -222,7 +248,7 @@ static s32 get_cycle_time_elapsed(struct sched_gate_lis= t *sched, ktime_t time) s32 time_elapsed; =20 time_since_sched_start =3D 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); =20 return time_elapsed; } @@ -235,8 +261,9 @@ static ktime_t get_interval_end_time(struct sched_gate_= list *sched, s32 cycle_elapsed =3D get_cycle_time_elapsed(sched, intv_start); ktime_t intv_end, cycle_ext_end, cycle_end; =20 - cycle_end =3D ktime_add_ns(intv_start, sched->cycle_time - cycle_elapsed); - intv_end =3D ktime_add_ns(intv_start, entry->interval); + cycle_end =3D ktime_add_ns(intv_start, + get_cycle_time(sched) - cycle_elapsed); + intv_end =3D ktime_add_ns(intv_start, get_interval(entry, sched)); cycle_ext_end =3D ktime_add(cycle_end, sched->cycle_time_extension); =20 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= )); } =20 -static bool cycle_corr_active(s64 cycle_time_correction) -{ - if (cycle_time_correction =3D=3D INIT_CYCLE_TIME_CORRECTION) - return false; - else - return true; -} - /* Sets sched->max_sdu[] and sched->max_frm_len[] to the minimum between t= he * q->max_sdu[] requested by the user and the max_sdu dynamically determin= ed by * the maximum open gate durations at the given link speed. @@ -351,7 +370,7 @@ static struct sched_entry *find_entry_to_transmit(struc= t sk_buff *skb, if (!sched) return NULL; =20 - cycle =3D sched->cycle_time; + cycle =3D get_cycle_time(sched); cycle_elapsed =3D get_cycle_time_elapsed(sched, time); curr_intv_end =3D ktime_sub_ns(time, cycle_elapsed); cycle_end =3D ktime_add_ns(curr_intv_end, cycle); @@ -365,7 +384,7 @@ static struct sched_entry *find_entry_to_transmit(struc= t sk_buff *skb, break; =20 if (!(entry->gate_mask & BIT(tc)) || - packet_transmit_time > entry->interval) + packet_transmit_time > get_interval(entry, sched)) continue; =20 txtime =3D entry->next_txtime; @@ -543,7 +562,8 @@ static long get_packet_txtime(struct sk_buff *skb, stru= ct Qdisc *sch) * interval starts. */ if (ktime_after(transmit_end_time, interval_end)) - entry->next_txtime =3D ktime_add(interval_start, sched->cycle_time); + entry->next_txtime =3D + ktime_add(interval_start, get_cycle_time(sched)); } while (sched_changed || ktime_after(transmit_end_time, interval_end)); =20 entry->next_txtime =3D transmit_end_time; @@ -1045,6 +1065,7 @@ static enum hrtimer_restart advance_sched(struct hrti= mer *timer) =20 oper->cycle_end_time =3D new_base_time; end_time =3D new_base_time; + next->correction_active =3D true; =20 update_open_gate_duration(next, oper, num_tc, new_gate_duration); @@ -1146,6 +1167,7 @@ static int fill_sched_entry(struct taprio_sched *q, s= truct nlattr **tb, } =20 entry->interval =3D interval; + entry->correction_active =3D false; =20 return 0; } --=20 2.25.1 From nobody Wed Dec 31 04:51:38 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 504E9C4332F for ; Tue, 7 Nov 2023 11:22:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234300AbjKGLW0 (ORCPT ); Tue, 7 Nov 2023 06:22:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39828 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234303AbjKGLWR (ORCPT ); Tue, 7 Nov 2023 06:22:17 -0500 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> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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_sche= d *q, } =20 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 =3D qdisc_priv(sch); - ktime_t expires; + struct sched_gate_list *oper =3D NULL; + ktime_t expires, start; =20 if (FULL_OFFLOAD_IS_ENABLED(q->flags)) return; =20 + oper =3D rcu_dereference_protected(q->oper_sched, + lockdep_is_held(&q->current_entry_lock)); + expires =3D hrtimer_get_expires(&q->advance_timer); if (expires =3D=3D 0) expires =3D 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 =3D min_t(ktime_t, start, expires); + start =3D min_t(ktime_t, new_base_time, expires); + + if (expires !=3D KTIME_MAX && + ktime_compare(start, new_base_time) =3D=3D 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 =3D 0; + } =20 hrtimer_start(&q->advance_timer, start, HRTIMER_MODE_ABS); } --=20 2.25.1 From nobody Wed Dec 31 04:51:38 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 437BCC4332F for ; Tue, 7 Nov 2023 11:22:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234328AbjKGLWg (ORCPT ); Tue, 7 Nov 2023 06:22:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39850 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234325AbjKGLWW (ORCPT ); Tue, 7 Nov 2023 06:22:22 -0500 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> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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] =3D ktime_add_ns(base, first->gate_duration[= tc]); } =20 - rcu_assign_pointer(q->current_entry, NULL); + if (!hrtimer_active(&q->advance_timer)) + rcu_assign_pointer(q->current_entry, NULL); } =20 static void taprio_start_sched(struct Qdisc *sch, --=20 2.25.1 From nobody Wed Dec 31 04:51:38 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8794AC4332F for ; Tue, 7 Nov 2023 11:22:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234023AbjKGLWk (ORCPT ); Tue, 7 Nov 2023 06:22:40 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39812 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234244AbjKGLWb (ORCPT ); Tue, 7 Nov 2023 06:22:31 -0500 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> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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_sche= d *q, rcu_assign_pointer(q->current_entry, NULL); } =20 +static void update_gate_close_time(struct sched_entry *current_entry, + ktime_t new_end_time, + int num_tc) +{ + int tc; + + for (tc =3D 0; tc < num_tc; tc++) { + if (current_entry->gate_mask & BIT(tc)) + current_entry->gate_close_time[tc] =3D 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 =3D qdisc_priv(sch); + ktime_t expires =3D hrtimer_get_expires(&q->advance_timer); + struct net_device *dev =3D qdisc_dev(q->root); + struct sched_entry *curr_entry =3D NULL; struct sched_gate_list *oper =3D NULL; - ktime_t expires, start; =20 if (FULL_OFFLOAD_IS_ENABLED(q->flags)) return; =20 oper =3D rcu_dereference_protected(q->oper_sched, lockdep_is_held(&q->current_entry_lock)); + curr_entry =3D rcu_dereference_protected(q->current_entry, + lockdep_is_held(&q->current_entry_lock)); =20 - expires =3D hrtimer_get_expires(&q->advance_timer); - if (expires =3D=3D 0) - expires =3D KTIME_MAX; + if (hrtimer_active(&q->advance_timer)) { + oper->cycle_time_correction =3D + get_cycle_time_correction(oper, new_base_time, + curr_entry->end_time, + curr_entry); =20 - /* 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 =3D min_t(ktime_t, new_base_time, expires); - - if (expires !=3D KTIME_MAX && - ktime_compare(start, new_base_time) =3D=3D 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 =3D taprio_get_time(q); + u64 gate_duration_left =3D ktime_sub(new_base_time, now); + struct qdisc_size_table *stab =3D + rtnl_dereference(q->root->stab); + int num_tc =3D netdev_get_num_tc(dev); + + oper->cycle_end_time =3D new_base_time; + curr_entry->end_time =3D new_base_time; + curr_entry->correction_active =3D 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 =3D 0; + expires =3D new_base_time; } =20 - hrtimer_start(&q->advance_timer, start, HRTIMER_MODE_ABS); + hrtimer_start(&q->advance_timer, expires, HRTIMER_MODE_ABS); } =20 static void taprio_set_picos_per_byte(struct net_device *dev, --=20 2.25.1