Received: by 2002:a05:6359:c8b:b0:c7:702f:21d4 with SMTP id go11csp818240rwb; Mon, 26 Sep 2022 06:18:33 -0700 (PDT) X-Google-Smtp-Source: AMsMyM75vQ0kEUTz3JN+/II6b1IQfnt/8/oNSKf5bktmZr5OJp2bBGEUpwQCjJyXAlnKgAVfPVFd X-Received: by 2002:a63:585c:0:b0:439:61d5:17fc with SMTP id i28-20020a63585c000000b0043961d517fcmr19576573pgm.364.1664198313102; Mon, 26 Sep 2022 06:18:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1664198313; cv=none; d=google.com; s=arc-20160816; b=KXJ1bhmosKQ/wt8CqDCJn0xryHWq2PFXYuU3z3WXslZ/fwz/I2tZsfXLbelnflCqVw aLblzzjZfaUpqELip5LIZGcIMt372gGPp3ZqR+8ZavthJkmac6wiphT9E+BwXqxtMIoW w9ip9Di4xfpyto64bKbDyItFF/Nft819hfAL+iI+Z4/U7C8ryFLqvNoqZTb/4RROT4oz meqERi/dMZPubhsejs57Wm/AsBGYpJuI+ASqR+jDWoHZEhPj0WIni5+4CyBjKdePLLCD lhHRxnWvrQBv+eFCzEO68mBhZ9m57wJ5EeofWlo2omL0puGeCSjS/Fripd0q/ZhYAwgO GTfw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=CvLYAuWJ8MVVv/XBKUOO/nFzdOfwTy5fC43TGLz3RPA=; b=oDEKEp7HvMEvAng7ol5/zRanZvKwFD+PgeiU6OU+utWjxFpLd7BlI76gPySPACYWf9 KdRC4M+VPS3T3M3Gc+suBpXFj4QZtkWYzKi68oNPEdrg5YAu+y0OKb+P3/SNCeYe3097 jnZwh5R55tZ0wFj0pOmeBw5zwA5yJ0P9VuLYoX1qI3zmnl4x5XKcH+DVSWI9ixFxfp0c kfviHFgaYcN3zvdd6lqh0zLbWaqitPVClwIgOt3E2rFlOPMld26+mXcz33EIRFQ4YRv+ SeiTH1NVmPeN67S0xzx7YCPvNxd6CZ3zrFC6pvrRi/on2zb+rSg1gSfl870qkDuHvY6Y 1R6A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=nwMEdhd1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id e14-20020a63544e000000b0043447486c84si17283289pgm.875.2022.09.26.06.18.20; Mon, 26 Sep 2022 06:18:33 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=nwMEdhd1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239463AbiIZMJ5 (ORCPT + 99 others); Mon, 26 Sep 2022 08:09:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36204 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235281AbiIZMIH (ORCPT ); Mon, 26 Sep 2022 08:08:07 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 42AD47F27C; Mon, 26 Sep 2022 03:56:06 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id DC813B8091E; Mon, 26 Sep 2022 10:48:21 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5108AC433C1; Mon, 26 Sep 2022 10:48:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1664189300; bh=K/J5kmBBdxyWkb12VWV3kp/bZF5jclV6AW4g+Hsj/jY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nwMEdhd14B8lGPHR1LK3a69DG5yCc0XqHJjXCHgEl0z3hyVqN7ZuHKM3upn3Sepya THQIXu414XlBjmapueZBrIdBdGCw5pFz0FLxMT/lpH6ZsxX27F2uqswaufLAKv4xwo LTx3ZWfCY++fTVW3cZfL5ZjJ2XvEndLPrn8GQxT0= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Vladimir Oltean , Vinicius Costa Gomes , Jakub Kicinski , Sasha Levin Subject: [PATCH 5.19 133/207] net/sched: taprio: avoid disabling offload when it was never enabled Date: Mon, 26 Sep 2022 12:12:02 +0200 Message-Id: <20220926100812.477600795@linuxfoundation.org> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220926100806.522017616@linuxfoundation.org> References: <20220926100806.522017616@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.2 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Vladimir Oltean [ Upstream commit db46e3a88a09c5cf7e505664d01da7238cd56c92 ] In an incredibly strange API design decision, qdisc->destroy() gets called even if qdisc->init() never succeeded, not exclusively since commit 87b60cfacf9f ("net_sched: fix error recovery at qdisc creation"), but apparently also earlier (in the case of qdisc_create_dflt()). The taprio qdisc does not fully acknowledge this when it attempts full offload, because it starts off with q->flags = TAPRIO_FLAGS_INVALID in taprio_init(), then it replaces q->flags with TCA_TAPRIO_ATTR_FLAGS parsed from netlink (in taprio_change(), tail called from taprio_init()). But in taprio_destroy(), we call taprio_disable_offload(), and this determines what to do based on FULL_OFFLOAD_IS_ENABLED(q->flags). But looking at the implementation of FULL_OFFLOAD_IS_ENABLED() (a bitwise check of bit 1 in q->flags), it is invalid to call this macro on q->flags when it contains TAPRIO_FLAGS_INVALID, because that is set to U32_MAX, and therefore FULL_OFFLOAD_IS_ENABLED() will return true on an invalid set of flags. As a result, it is possible to crash the kernel if user space forces an error between setting q->flags = TAPRIO_FLAGS_INVALID, and the calling of taprio_enable_offload(). This is because drivers do not expect the offload to be disabled when it was never enabled. The error that we force here is to attach taprio as a non-root qdisc, but instead as child of an mqprio root qdisc: $ tc qdisc add dev swp0 root handle 1: \ mqprio num_tc 8 map 0 1 2 3 4 5 6 7 \ queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 hw 0 $ tc qdisc replace dev swp0 parent 1:1 \ taprio num_tc 8 map 0 1 2 3 4 5 6 7 \ queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 base-time 0 \ sched-entry S 0x7f 990000 sched-entry S 0x80 100000 \ flags 0x0 clockid CLOCK_TAI Unable to handle kernel paging request at virtual address fffffffffffffff8 [fffffffffffffff8] pgd=0000000000000000, p4d=0000000000000000 Internal error: Oops: 96000004 [#1] PREEMPT SMP Call trace: taprio_dump+0x27c/0x310 vsc9959_port_setup_tc+0x1f4/0x460 felix_port_setup_tc+0x24/0x3c dsa_slave_setup_tc+0x54/0x27c taprio_disable_offload.isra.0+0x58/0xe0 taprio_destroy+0x80/0x104 qdisc_create+0x240/0x470 tc_modify_qdisc+0x1fc/0x6b0 rtnetlink_rcv_msg+0x12c/0x390 netlink_rcv_skb+0x5c/0x130 rtnetlink_rcv+0x1c/0x2c Fix this by keeping track of the operations we made, and undo the offload only if we actually did it. I've added "bool offloaded" inside a 4 byte hole between "int clockid" and "atomic64_t picos_per_byte". Now the first cache line looks like below: $ pahole -C taprio_sched net/sched/sch_taprio.o struct taprio_sched { struct Qdisc * * qdiscs; /* 0 8 */ struct Qdisc * root; /* 8 8 */ u32 flags; /* 16 4 */ enum tk_offsets tk_offset; /* 20 4 */ int clockid; /* 24 4 */ bool offloaded; /* 28 1 */ /* XXX 3 bytes hole, try to pack */ atomic64_t picos_per_byte; /* 32 0 */ /* XXX 8 bytes hole, try to pack */ spinlock_t current_entry_lock; /* 40 0 */ /* XXX 8 bytes hole, try to pack */ struct sched_entry * current_entry; /* 48 8 */ struct sched_gate_list * oper_sched; /* 56 8 */ /* --- cacheline 1 boundary (64 bytes) --- */ Fixes: 9c66d1564676 ("taprio: Add support for hardware offloading") Signed-off-by: Vladimir Oltean Reviewed-by: Vinicius Costa Gomes Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/sched/sch_taprio.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index 0b941dd63d26..9bec73019f94 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -67,6 +67,7 @@ struct taprio_sched { u32 flags; enum tk_offsets tk_offset; int clockid; + bool offloaded; atomic64_t picos_per_byte; /* Using picoseconds because for 10Gbps+ * speeds it's sub-nanoseconds per byte */ @@ -1279,6 +1280,8 @@ static int taprio_enable_offload(struct net_device *dev, goto done; } + q->offloaded = true; + done: taprio_offload_free(offload); @@ -1293,12 +1296,9 @@ static int taprio_disable_offload(struct net_device *dev, struct tc_taprio_qopt_offload *offload; int err; - if (!FULL_OFFLOAD_IS_ENABLED(q->flags)) + if (!q->offloaded) return 0; - if (!ops->ndo_setup_tc) - return -EOPNOTSUPP; - offload = taprio_offload_alloc(0); if (!offload) { NL_SET_ERR_MSG(extack, @@ -1314,6 +1314,8 @@ static int taprio_disable_offload(struct net_device *dev, goto out; } + q->offloaded = false; + out: taprio_offload_free(offload); -- 2.35.1