Received: by 2002:ac0:e34a:0:0:0:0:0 with SMTP id g10csp481469imn; Wed, 27 Jul 2022 11:24:46 -0700 (PDT) X-Google-Smtp-Source: AGRyM1tiDQLvve2KscR5kOyw4zNby/8Ulti3f5CWNUHXUH3LsswNe+/cdxjs19wjTkd/fzm9+RGY X-Received: by 2002:a17:902:9005:b0:16d:1ffd:cf56 with SMTP id a5-20020a170902900500b0016d1ffdcf56mr22702675plp.119.1658946285976; Wed, 27 Jul 2022 11:24:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1658946285; cv=none; d=google.com; s=arc-20160816; b=owCGKZQqnXt62KUb9+CUFPfCZaADapaugIX7NcJ5qz3kwoZ+9lt8aGE9ODYQRskFu4 tHzEYHW1gSAGSz4Z3Tc7YNnU64VNtlRjVdULxega2XZGGNBUI3aHeHBnX2YK9mNXT3MN ltCE/zirADSgV05eTKeL595bBGbP1EP8UiflnE3h0XUBOd8+DuV+oMDp183c6k1n6qs2 adyB08mXJOJ3c2PZX4+6N78DFd76Cchpwwgq1QmeUfbLeekh7o/b+pnlufdo+/ysk+Xp xGmseWAgTq93Oit73L2xckHo9Vt7fl02IPIvN+NYW7jOFhUs7Gw78pSedEE5klwTZCnE l4vw== 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=H5ksTzGikYUGGISDjQQFG6sctKdUDYFWrpctKOqKybM=; b=pVNIKlYVnqbMKWDWqi1wUpilqGQ3ZspQuctQkkzkCZpUlDmDKn4zNczTQ+cyouXDRs FTWSzvds6TjS3hfk3HUACVVR98qqt1Fzi5SYoR0gbMWspcKQUO/HEJOG38zzKjH3fC0H +yG94BDmZ2ywV+WoL02X6ukxSm5VytHNJQywFRZaqk7yy1a2bFf8gkL+IxhUq4pYdm1e gZ+ExxjaeYLrfz6PEsOM89KV/Icad7g0flhSTdcFf2K1VNytBTKyRg8CHM2vklaZadsO LytRa0UdJxRk378QoTbzsJ7g1EWftQ6pSy3pUcM902+Gx4ofLpRlie7dM0BQ8Oc2ICxA kAJg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=V6apZ4cr; 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 j16-20020aa79290000000b0052b88948d54si14574417pfa.342.2022.07.27.11.24.31; Wed, 27 Jul 2022 11:24:45 -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=V6apZ4cr; 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 S240134AbiG0Qrx (ORCPT + 99 others); Wed, 27 Jul 2022 12:47:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44870 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240058AbiG0Qq7 (ORCPT ); Wed, 27 Jul 2022 12:46:59 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5AE3852DFD; Wed, 27 Jul 2022 09:32:00 -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 14E1AB821BA; Wed, 27 Jul 2022 16:31:59 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 62F5DC433D6; Wed, 27 Jul 2022 16:31:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1658939517; bh=htyf8dAJwRiQSesYEE98VZHxac6Wn8C8lGyj2NnpPXs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=V6apZ4crY5cQCt0bJ4N3PUwk7XBT98FL/ho28gE+2DHOrZxEZ2P2KmtZ9KcyZ18P4 pO7NlrxZaFix0aCUhSdfa++EXaEn3jMuRM1CIepuYtjaLlvAxbi69Ouj81+v7iyB3W a9bVghNeeQhmiS0lP5Fgy6FhhYn3mFcLwd0lOLvY= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jakub Kicinski , Fedor Pchelkin Subject: [PATCH 5.10 010/105] net: make free_netdev() more lenient with unregistering devices Date: Wed, 27 Jul 2022 18:09:56 +0200 Message-Id: <20220727161012.480155559@linuxfoundation.org> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220727161012.056867467@linuxfoundation.org> References: <20220727161012.056867467@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.7 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: Fedor Pchelkin From: Jakub Kicinski commit c269a24ce057abfc31130960e96ab197ef6ab196 upstream. There are two flavors of handling netdev registration: - ones called without holding rtnl_lock: register_netdev() and unregister_netdev(); and - those called with rtnl_lock held: register_netdevice() and unregister_netdevice(). While the semantics of the former are pretty clear, the same can't be said about the latter. The netdev_todo mechanism is utilized to perform some of the device unregistering tasks and it hooks into rtnl_unlock() so the locked variants can't actually finish the work. In general free_netdev() does not mix well with locked calls. Most drivers operating under rtnl_lock set dev->needs_free_netdev to true and expect core to make the free_netdev() call some time later. The part where this becomes most problematic is error paths. There is no way to unwind the state cleanly after a call to register_netdevice(), since unreg can't be performed fully without dropping locks. Make free_netdev() more lenient, and defer the freeing if device is being unregistered. This allows error paths to simply call free_netdev() both after register_netdevice() failed, and after a call to unregister_netdevice() but before dropping rtnl_lock. Simplify the error paths which are currently doing gymnastics around free_netdev() handling. Signed-off-by: Jakub Kicinski Signed-off-by: Fedor Pchelkin Signed-off-by: Greg Kroah-Hartman --- net/8021q/vlan.c | 4 +--- net/core/dev.c | 11 +++++++++++ net/core/rtnetlink.c | 23 ++++++----------------- 3 files changed, 18 insertions(+), 20 deletions(-) --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -278,9 +278,7 @@ static int register_vlan_device(struct n return 0; out_free_newdev: - if (new_dev->reg_state == NETREG_UNINITIALIZED || - new_dev->reg_state == NETREG_UNREGISTERED) - free_netdev(new_dev); + free_netdev(new_dev); return err; } --- a/net/core/dev.c +++ b/net/core/dev.c @@ -10683,6 +10683,17 @@ void free_netdev(struct net_device *dev) struct napi_struct *p, *n; might_sleep(); + + /* When called immediately after register_netdevice() failed the unwind + * handling may still be dismantling the device. Handle that case by + * deferring the free. + */ + if (dev->reg_state == NETREG_UNREGISTERING) { + ASSERT_RTNL(); + dev->needs_free_netdev = true; + return; + } + netif_free_tx_queues(dev); netif_free_rx_queues(dev); --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -3442,26 +3442,15 @@ replay: dev->ifindex = ifm->ifi_index; - if (ops->newlink) { + if (ops->newlink) err = ops->newlink(link_net ? : net, dev, tb, data, extack); - /* Drivers should set dev->needs_free_netdev - * and unregister it on failure after registration - * so that device could be finally freed in rtnl_unlock. - */ - if (err < 0) { - /* If device is not registered at all, free it now */ - if (dev->reg_state == NETREG_UNINITIALIZED || - dev->reg_state == NETREG_UNREGISTERED) - free_netdev(dev); - goto out; - } - } else { + else err = register_netdevice(dev); - if (err < 0) { - free_netdev(dev); - goto out; - } + if (err < 0) { + free_netdev(dev); + goto out; } + err = rtnl_configure_link(dev, ifm); if (err < 0) goto out_unregister;