Received: by 2002:a05:6359:c8b:b0:c7:702f:21d4 with SMTP id go11csp900324rwb; Mon, 26 Sep 2022 07:16:04 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6Sb0Kon/tYl0PQ4JL0iYvV5dV7VwZDp7xIpYAmIE6Mc4JLzbt/avplSTq77mwyc8sTc1vc X-Received: by 2002:aa7:c382:0:b0:454:9591:79fe with SMTP id k2-20020aa7c382000000b00454959179femr23276351edq.253.1664201764553; Mon, 26 Sep 2022 07:16:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1664201764; cv=none; d=google.com; s=arc-20160816; b=wthjXobhajUfp/4w55VaZBjk561JTwD+P9vAHqr4Gl0mvMrmUXin4ZnpSYgjuKSyWj pILxw2f78sgiYBNe3AEsQUZAb2ctW2PtemJn4YvPp334AxshyjW+ggb65PXZQC2A8zBq zGn88YvvpvWzFcpOaTPevrzsC0fKRDusmrpzZQ6+geOqhUncher494Up2b2l9S8vDf9H RnZK7MxrwpsRiuoOEVKC79Mgb5e4hZ9Xzq78hw1W5P+blWr8CWB5RbJ6AriUu/bmmYD6 Rofkxj4i2L69nRcR6qDMlbhNIVn+IY8zcf0pUnaVoRjQww0rzbSqWT98PZKMWlxp6Phz u+GA== 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=mb35t/5otN83EfSHMV5MAz1SNC+CFzit9ZGwPEpcTr8=; b=kQnh0w9igBmEmhVWM2NUzTHohfxPI3pD2uAIlEpB0V9RhWJSgyIW6O79Tw+2NKKxfu 77fgUHoNBU19lPhA+9K7JSEecolMHJ0wPbeWmJRkL5nojPINWfmBP5UBKnGLJHwu649G gKwFJezx4XmnFbsl4Wx3C7rWY6yyZLKCpt5R6ddbSqBODd/Eq3QBiVXjxPzfp4WGubl0 Let0RyuElzTnasqm5pJAsbPBxSWv9hD/W91q9eVGH8I4bclDii+ZVGn3JykSW6oPnNgn isCNX+dNFYB8zeeUbX0U/BILiyQSbNwxlh20xg9bmVAUmIwMU8Wybx6ocod3Ta9zS9lp g0Hg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="o35ex/6m"; 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 z27-20020a1709060adb00b0073de493b83esi18429ejf.147.2022.09.26.07.15.32; Mon, 26 Sep 2022 07:16:04 -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="o35ex/6m"; 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 S237767AbiIZLU1 (ORCPT + 99 others); Mon, 26 Sep 2022 07:20:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40568 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237779AbiIZLS6 (ORCPT ); Mon, 26 Sep 2022 07:18:58 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 383D152DEE; Mon, 26 Sep 2022 03:38:34 -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 dfw.source.kernel.org (Postfix) with ESMTPS id C3A1460B4A; Mon, 26 Sep 2022 10:38:33 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D2688C433D6; Mon, 26 Sep 2022 10:38:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1664188713; bh=InA7AL+nzmeiCg6Z8JU8GFP6nWWkPiSO9VNG2nPkU8I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=o35ex/6m3KXaNOXoZ3Cw7sX3/Lb3VzyEbEitvdd3aZylzA465sQfkhGQLIxnZSgL2 DoB96Tvh+AH2suKd5qSOCfKLALPEpg0D8YpDOZBy3f0W1f7I+LYMtA4LEGtIhgpDzx gsNWbgKDM3gpTcoXZ5NsTi/LpIZkBwuVjdqkLGdk= 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.15 098/148] net/sched: taprio: avoid disabling offload when it was never enabled Date: Mon, 26 Sep 2022 12:12:12 +0200 Message-Id: <20220926100759.754048008@linuxfoundation.org> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220926100756.074519146@linuxfoundation.org> References: <20220926100756.074519146@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 474ba4db5de2..bb424f6264dd 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -66,6 +66,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 */ @@ -1278,6 +1279,8 @@ static int taprio_enable_offload(struct net_device *dev, goto done; } + q->offloaded = true; + done: taprio_offload_free(offload); @@ -1292,12 +1295,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, @@ -1313,6 +1313,8 @@ static int taprio_disable_offload(struct net_device *dev, goto out; } + q->offloaded = false; + out: taprio_offload_free(offload); -- 2.35.1