From patchwork Fri Feb 14 15:34:34 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 13975128 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-pl1-f170.google.com (mail-pl1-f170.google.com [209.85.214.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6A4C12673A4 for ; Fri, 14 Feb 2025 15:34:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739547291; cv=none; b=ipptCvG4LhRGF25j4qCkg8XBrmkbaq1K0PQAvw0Fkkg+OzyKkR7lwNo3G1AEvbe6gHziTP7je40VzjZ7jTtdcJwAk69+gAFy9qFGOhDmP+3nMcEcJ/BMIGWE3enSXjMO2cNXX3xapwo0Y99DFIFIHxKWj5Q+2CRTcay+kxzV8Ek= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739547291; c=relaxed/simple; bh=Vp5r0RcHCxpj9W1YQNHscphYMJ3k+JzzEl4+WKuw3X4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Y0YKt7rXbtalPY/wzCYbsWZb2ffJg8zh1OM0gtG/qBXv1bYEBkmCSLe6a2FqSy3TvR8hQGzdxWcRX+X24XnuZsqaqMiP+adgU61kRm73T76ycA4L6zlnLnzRXMtZaLQ2aESwtMZAP8c/jKfcqydoAHAIZ1OYOfqlKZVGn+ClDpY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=fomichev.me; spf=pass smtp.mailfrom=gmail.com; arc=none smtp.client-ip=209.85.214.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=fomichev.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-pl1-f170.google.com with SMTP id d9443c01a7336-220d39a5627so32925415ad.1 for ; Fri, 14 Feb 2025 07:34:49 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739547288; x=1740152088; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=2LwdXMfdE4P3bCB/PRY/rzygCHghOFC3NN+3o0+j7/U=; b=GBkfRJos7GXxRm7aL2HZ593Et50DigZV4NyaaAS/7NkyWOokO+RQyjM6ux/ngsJooA QnKeNERCl5nqAa15xnV414Hn6v6GFQ3f9UmwYmvPrt4KUm0gJMlzdc87D928rzm1HTKF eGRO25qBvE3TFq6wR9DuzZ4Mr4fgMhk/tydAYTBQsYkyUJxwfdvjRlQP0ifbDDjEIBpv +SStY6iSdmqI9BNXYvLxFX76X6SXaFztuVmc5PERzsXZSqnRKSONHu1hILldWIueLtjD fEDbBXshNzQC73ZnvsXW29BkbYXx+Igyzso6nO1ifJRuHk6dLGFH4OUUBvfuCxxeIsgN C+KA== X-Gm-Message-State: AOJu0Yxb6jR9AcB4fIOdp/0U02NvGYGyYJS/nOeUG6hI+3Nuy9iq9hIy c+lx2KNwisGXkJ+zF6C9JgfsWQ6JBE4cvV1HPPHX327o1HSgV9vr0Glg X-Gm-Gg: ASbGnctH4PMdH2v5QdsGQn6TblYuPxplUEsvVg0xWP9NTp5ZYlkWf53fRVym8fLlPbQ Hrfm3XPO9N1NHUsPzSZSA988Low7Ri+n2CqijvrVYKBmy+Flw/+WdtBRQ6TAQ67WlmEwNMQzKSs AVD/rMf27v4AAIxfCqxOGheAM+qQkvFfSc9aiczjH86mihpmXYhq6JMq3mVFB7ISjeueffqAGRC HaulRKTpCrU4YpnakB99SzIrFxLM/b11F5Xz3LJf280/XjQKmGcrhqB0ZxQhry+pLsNp5hRu1wr zaAkBvpd8Vkapcc= X-Google-Smtp-Source: AGHT+IEvzsCAvAAGIMC/Zzlh77446Koxgnk3HRfBS2UKxq5bJLW2iUTGNpc6FC7DJV0+KVuSF3diXQ== X-Received: by 2002:a17:902:ebc2:b0:216:3466:7414 with SMTP id d9443c01a7336-220be0035c3mr209772295ad.44.1739547288120; Fri, 14 Feb 2025 07:34:48 -0800 (PST) Received: from localhost ([2601:646:9e00:f56e:2844:3d8f:bf3e:12cc]) by smtp.gmail.com with UTF8SMTPSA id d9443c01a7336-220d5366984sm30413055ad.60.2025.02.14.07.34.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Feb 2025 07:34:47 -0800 (PST) From: Stanislav Fomichev To: netdev@vger.kernel.org Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, Saeed Mahameed Subject: [PATCH net-next v2 05/11] net: hold netdev instance lock during ioctl operations Date: Fri, 14 Feb 2025 07:34:34 -0800 Message-ID: <20250214153440.1994910-6-sdf@fomichev.me> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250214153440.1994910-1-sdf@fomichev.me> References: <20250214153440.1994910-1-sdf@fomichev.me> 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 Convert all ndo_eth_ioctl invocations to dev_eth_ioctl which does the locking. Reflow some of the dev_siocxxx to drop else clause. Cc: Saeed Mahameed Signed-off-by: Stanislav Fomichev --- drivers/net/bonding/bond_main.c | 9 ++--- include/linux/netdevice.h | 3 ++ net/8021q/vlan_dev.c | 4 +- net/core/dev.c | 4 +- net/core/dev_api.c | 30 +++++++++++++++ net/core/dev_ioctl.c | 67 ++++++++++++++++++++------------- 6 files changed, 80 insertions(+), 37 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index f6d0628a36d9..19775e9d7341 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -855,7 +855,6 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_dev, int reporting) { const struct net_device_ops *slave_ops = slave_dev->netdev_ops; - int (*ioctl)(struct net_device *, struct ifreq *, int); struct ifreq ifr; struct mii_ioctl_data *mii; @@ -871,8 +870,7 @@ static int bond_check_dev_link(struct bonding *bond, BMSR_LSTATUS : 0; /* Ethtool can't be used, fallback to MII ioctls. */ - ioctl = slave_ops->ndo_eth_ioctl; - if (ioctl) { + if (slave_ops->ndo_eth_ioctl) { /* TODO: set pointer to correct ioctl on a per team member * bases to make this more efficient. that is, once * we determine the correct ioctl, we will always @@ -888,9 +886,10 @@ static int bond_check_dev_link(struct bonding *bond, /* Yes, the mii is overlaid on the ifreq.ifr_ifru */ strscpy_pad(ifr.ifr_name, slave_dev->name, IFNAMSIZ); mii = if_mii(&ifr); - if (ioctl(slave_dev, &ifr, SIOCGMIIPHY) == 0) { + + if (dev_eth_ioctl(slave_dev, &ifr, SIOCGMIIPHY) == 0) { mii->reg_num = MII_BMSR; - if (ioctl(slave_dev, &ifr, SIOCGMIIREG) == 0) + if (dev_eth_ioctl(slave_dev, &ifr, SIOCGMIIREG) == 0) return mii->val_out & BMSR_LSTATUS; } } diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 0f22da1dfdbc..67d6417fbb39 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -4174,6 +4174,8 @@ int put_user_ifreq(struct ifreq *ifr, void __user *arg); int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr, void __user *data, bool *need_copyout); int dev_ifconf(struct net *net, struct ifconf __user *ifc); +int dev_eth_ioctl(struct net_device *dev, + struct ifreq *ifr, unsigned int cmd); int generic_hwtstamp_get_lower(struct net_device *dev, struct kernel_hwtstamp_config *kernel_cfg); int generic_hwtstamp_set_lower(struct net_device *dev, @@ -4195,6 +4197,7 @@ int netif_change_net_namespace(struct net_device *dev, struct net *net, int dev_change_net_namespace(struct net_device *dev, struct net *net, const char *pat); int __dev_set_mtu(struct net_device *, int); +int netif_set_mtu(struct net_device *dev, int new_mtu); int dev_set_mtu(struct net_device *, int); int dev_pre_changeaddr_notify(struct net_device *dev, const char *addr, struct netlink_ext_ack *extack); diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 91d134961357..ee3283400716 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -377,7 +377,6 @@ static int vlan_hwtstamp_set(struct net_device *dev, static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; - const struct net_device_ops *ops = real_dev->netdev_ops; struct ifreq ifrr; int err = -EOPNOTSUPP; @@ -388,8 +387,7 @@ static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) case SIOCGMIIPHY: case SIOCGMIIREG: case SIOCSMIIREG: - if (netif_device_present(real_dev) && ops->ndo_eth_ioctl) - err = ops->ndo_eth_ioctl(real_dev, &ifrr, cmd); + err = dev_eth_ioctl(real_dev, &ifrr, cmd); break; } diff --git a/net/core/dev.c b/net/core/dev.c index 1fe233fc0eb8..2aaed0baba45 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -9309,7 +9309,7 @@ int netif_set_mtu_ext(struct net_device *dev, int new_mtu, return err; } -int dev_set_mtu(struct net_device *dev, int new_mtu) +int netif_set_mtu(struct net_device *dev, int new_mtu) { struct netlink_ext_ack extack; int err; @@ -9320,7 +9320,7 @@ int dev_set_mtu(struct net_device *dev, int new_mtu) net_err_ratelimited("%s: %s\n", dev->name, extack._msg); return err; } -EXPORT_SYMBOL(dev_set_mtu); +EXPORT_SYMBOL(netif_set_mtu); int netif_change_tx_queue_len(struct net_device *dev, unsigned long new_len) { diff --git a/net/core/dev_api.c b/net/core/dev_api.c index ce3a38c8e326..7dae30781411 100644 --- a/net/core/dev_api.c +++ b/net/core/dev_api.c @@ -222,3 +222,33 @@ void dev_close(struct net_device *dev) netdev_unlock_ops(dev); } EXPORT_SYMBOL(dev_close); + +int dev_eth_ioctl(struct net_device *dev, + struct ifreq *ifr, unsigned int cmd) +{ + const struct net_device_ops *ops = dev->netdev_ops; + int ret = -ENODEV; + + if (!ops->ndo_eth_ioctl) + return -EOPNOTSUPP; + + netdev_lock_ops(dev); + if (netif_device_present(dev)) + ret = ops->ndo_eth_ioctl(dev, ifr, cmd); + netdev_unlock_ops(dev); + + return ret; +} +EXPORT_SYMBOL(dev_eth_ioctl); + +int dev_set_mtu(struct net_device *dev, int new_mtu) +{ + int ret; + + netdev_lock_ops(dev); + ret = netif_set_mtu(dev, new_mtu); + netdev_unlock_ops(dev); + + return ret; +} +EXPORT_SYMBOL(dev_set_mtu); diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c index 4c2098ac9d72..d9f350593121 100644 --- a/net/core/dev_ioctl.c +++ b/net/core/dev_ioctl.c @@ -110,7 +110,7 @@ static int dev_getifmap(struct net_device *dev, struct ifreq *ifr) return 0; } -static int dev_setifmap(struct net_device *dev, struct ifreq *ifr) +static int netif_setifmap(struct net_device *dev, struct ifreq *ifr) { struct compat_ifmap *cifmap = (struct compat_ifmap *)&ifr->ifr_map; @@ -240,20 +240,6 @@ int net_hwtstamp_validate(const struct kernel_hwtstamp_config *cfg) return 0; } -static int dev_eth_ioctl(struct net_device *dev, - struct ifreq *ifr, unsigned int cmd) -{ - const struct net_device_ops *ops = dev->netdev_ops; - - if (!ops->ndo_eth_ioctl) - return -EOPNOTSUPP; - - if (!netif_device_present(dev)) - return -ENODEV; - - return ops->ndo_eth_ioctl(dev, ifr, cmd); -} - /** * dev_get_hwtstamp_phylib() - Get hardware timestamping settings of NIC * or of attached phylib PHY @@ -305,7 +291,9 @@ static int dev_get_hwtstamp(struct net_device *dev, struct ifreq *ifr) return -ENODEV; kernel_cfg.ifr = ifr; + netdev_lock_ops(dev); err = dev_get_hwtstamp_phylib(dev, &kernel_cfg); + netdev_unlock_ops(dev); if (err) return err; @@ -429,7 +417,9 @@ static int dev_set_hwtstamp(struct net_device *dev, struct ifreq *ifr) if (!netif_device_present(dev)) return -ENODEV; + netdev_lock_ops(dev); err = dev_set_hwtstamp_phylib(dev, &kernel_cfg, &extack); + netdev_unlock_ops(dev); if (err) return err; @@ -504,10 +494,14 @@ static int dev_siocbond(struct net_device *dev, const struct net_device_ops *ops = dev->netdev_ops; if (ops->ndo_siocbond) { + int ret = -ENODEV; + + netdev_lock_ops(dev); if (netif_device_present(dev)) - return ops->ndo_siocbond(dev, ifr, cmd); - else - return -ENODEV; + ret = ops->ndo_siocbond(dev, ifr, cmd); + netdev_unlock_ops(dev); + + return ret; } return -EOPNOTSUPP; @@ -519,10 +513,14 @@ static int dev_siocdevprivate(struct net_device *dev, struct ifreq *ifr, const struct net_device_ops *ops = dev->netdev_ops; if (ops->ndo_siocdevprivate) { + int ret = -ENODEV; + + netdev_lock_ops(dev); if (netif_device_present(dev)) - return ops->ndo_siocdevprivate(dev, ifr, data, cmd); - else - return -ENODEV; + ret = ops->ndo_siocdevprivate(dev, ifr, data, cmd); + netdev_unlock_ops(dev); + + return ret; } return -EOPNOTSUPP; @@ -533,10 +531,14 @@ static int dev_siocwandev(struct net_device *dev, struct if_settings *ifs) const struct net_device_ops *ops = dev->netdev_ops; if (ops->ndo_siocwandev) { + int ret = -ENODEV; + + netdev_lock_ops(dev); if (netif_device_present(dev)) - return ops->ndo_siocwandev(dev, ifs); - else - return -ENODEV; + ret = ops->ndo_siocwandev(dev, ifs); + netdev_unlock_ops(dev); + + return ret; } return -EOPNOTSUPP; @@ -580,11 +582,16 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data, memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data, min(sizeof(ifr->ifr_hwaddr.sa_data_min), (size_t)dev->addr_len)); + netdev_lock_ops(dev); call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); + netdev_unlock_ops(dev); return 0; case SIOCSIFMAP: - return dev_setifmap(dev, ifr); + netdev_lock_ops(dev); + err = netif_setifmap(dev, ifr); + netdev_unlock_ops(dev); + return err; case SIOCADDMULTI: if (!ops->ndo_set_rx_mode || @@ -592,7 +599,10 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data, return -EINVAL; if (!netif_device_present(dev)) return -ENODEV; - return dev_mc_add_global(dev, ifr->ifr_hwaddr.sa_data); + netdev_lock_ops(dev); + err = dev_mc_add_global(dev, ifr->ifr_hwaddr.sa_data); + netdev_unlock_ops(dev); + return err; case SIOCDELMULTI: if (!ops->ndo_set_rx_mode || @@ -600,7 +610,10 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data, return -EINVAL; if (!netif_device_present(dev)) return -ENODEV; - return dev_mc_del_global(dev, ifr->ifr_hwaddr.sa_data); + netdev_lock_ops(dev); + err = dev_mc_del_global(dev, ifr->ifr_hwaddr.sa_data); + netdev_unlock_ops(dev); + return err; case SIOCSIFTXQLEN: if (ifr->ifr_qlen < 0)