From nobody Tue Dec 2 02:04:17 2025 Received: from PH8PR06CU001.outbound.protection.outlook.com (mail-westus3azon11012017.outbound.protection.outlook.com [40.107.209.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 921D1333755; Thu, 20 Nov 2025 13:14:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.209.17 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763644448; cv=fail; b=tuwnX8UH2aq1cE5rQxlbxTPTDgtXsJgc5Vbjbhjoz53tz29/8d/EHLHx++pMPFIX0IWTlxBMn21mzR8Yz5JIls3UhH/8bAoum0VzavomusigtOqHT74eFiKvJEGSd5007L98Lt6G720f/Xw2XLAsiQI7V3ezfwLwk2/ouC3gpG8= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763644448; c=relaxed/simple; bh=U2TYAyDQgwUfleqgjbj55T4WckZEKGbANv1FS+qIZG8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=sclpPDQOpaKKRnH8jx0+p/Spm4nxDp725k0jzrLReH/3KvZ7Lb0WNU8AKUtcFJxT+khx2JQlT61D36Eq1aze6QvQNQw8jMBxpn4380sfW1LBc0+akm5MESLtFmWLsGMbLh3BTvd5yffU5QhLoyuuv/9WexVbe3XjyyIsLNiJSkg= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com; spf=fail smtp.mailfrom=nvidia.com; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b=DkWLvdmP; arc=fail smtp.client-ip=40.107.209.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=nvidia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b="DkWLvdmP" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=H2aVvfaUibCId0Jvqi2B0HR64aaMnvhe3amdC/Fhl26o8ghUWDGLkdi2noD3Qd9qwkDIarGMDQ58h+a6G8oiMlWT5PnhbqKZy6QdbiHJIYns4QNK22kKyYKun0N+ebfAZs8GaFdnD1EZB+c9SteY6bF+sFkjs4Cfwkmmi03E729XNMfOQaeXgCKam9hpVZ1Ee5I0wKAZ/eSbxvJTskWgV2xeDDt00JNyvO7K0nNt9pD9R3VjtESlKZTYi+u4I0iDAf+/i4JNkIO7SljZRrThqc9q4/w61g/EKI7z5n5qr+A/Zi8sL8QxMAlqvkH4H881WqcQhBhkP1pDEAFnpP2f4g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=hZJP9aS/I2FNomzxPhrDzIBEkQ3Dah57Fn5YpEF2TI8=; b=Kl3RYaCKFOV7OAMSUN03sMarEkKZQQvewsyQK1mVyLhn6U6BWazCuqOy15U4VF2aQempoibimxuRIFIiEMBi62fu87ggCRREkZiM3B4eSAgK4wHXYPT4U2idB92PKDyVzScK4oN0Lx74Ef3Swst8NuO1yXkzytd2wLPug14+Opls2fR4+W4V3jv0LsogDb4DreZlpJqVsn8F4tXwXU7mFJIU34uPq5KuBLR4bzdJaRexqOaguH2p1ysUNiJPaiE/Uh1M4mlDsMAvnXDQvY+xZPyiSLmudyIu02fm/n+QxeS1MiZK4pSfU5wtvn+CHMYwh7u3Wumz7R+DajoFA5QMcA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.117.161) smtp.rcpttodomain=google.com smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=hZJP9aS/I2FNomzxPhrDzIBEkQ3Dah57Fn5YpEF2TI8=; b=DkWLvdmPpKjAyAmdm+WircvAlofF8oXwK6TGfsbBFDQuM+2Of4lLwhL+4CTniweg78ZprjJ5gBCWGKGXKoiDlutC2tAvnlbEnXxk4bitjFMFQGthqVxkMiacCf5RUokPQ9tnuOSHNFwqqaPagHOCV9fVfby93Wxon7EIYc6TxHedd49N2hf457+CGtm/1Vnjr+cE9ZjRgxhXNRe4VbA3cZlE4Suj0o98cUpWmg8sjL5iGpa4QnAyiDHwCja/zXrpt0L9kYSKDmq/L0RZSYorJ8cwPXQBc/90mboXWjsJWrTCSmate6UDVBpyseJeDN7b8qgzYAD8MMr6l8m3I96ZOQ== Received: from SA1P222CA0114.NAMP222.PROD.OUTLOOK.COM (2603:10b6:806:3c5::21) by MN2PR12MB4406.namprd12.prod.outlook.com (2603:10b6:208:268::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9343.11; Thu, 20 Nov 2025 13:13:59 +0000 Received: from SN1PEPF0002636E.namprd02.prod.outlook.com (2603:10b6:806:3c5:cafe::40) by SA1P222CA0114.outlook.office365.com (2603:10b6:806:3c5::21) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9343.11 via Frontend Transport; Thu, 20 Nov 2025 13:13:57 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.117.161) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.117.161 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.117.161; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (216.228.117.161) by SN1PEPF0002636E.mail.protection.outlook.com (10.167.241.139) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9320.13 via Frontend Transport; Thu, 20 Nov 2025 13:13:58 +0000 Received: from rnnvmail203.nvidia.com (10.129.68.9) by mail.nvidia.com (10.129.200.67) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.20; Thu, 20 Nov 2025 05:13:40 -0800 Received: from rnnvmail204.nvidia.com (10.129.68.6) by rnnvmail203.nvidia.com (10.129.68.9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.20; Thu, 20 Nov 2025 05:13:40 -0800 Received: from vdi.nvidia.com (10.127.8.10) by mail.nvidia.com (10.129.68.6) with Microsoft SMTP Server id 15.2.2562.20 via Frontend Transport; Thu, 20 Nov 2025 05:13:34 -0800 From: Tariq Toukan To: Eric Dumazet , Jakub Kicinski , Paolo Abeni , Andrew Lunn , "David S. Miller" CC: Donald Hunter , Jiri Pirko , Jonathan Corbet , Saeed Mahameed , "Leon Romanovsky" , Tariq Toukan , Mark Bloch , , , , , Gal Pressman , Moshe Shemesh , Carolina Jubran , Cosmin Ratiu , Jiri Pirko Subject: [PATCH net-next 05/14] devlink: Decouple rate storage from associated devlink object Date: Thu, 20 Nov 2025 15:09:17 +0200 Message-ID: <1763644166-1250608-6-git-send-email-tariqt@nvidia.com> X-Mailer: git-send-email 2.8.0 In-Reply-To: <1763644166-1250608-1-git-send-email-tariqt@nvidia.com> References: <1763644166-1250608-1-git-send-email-tariqt@nvidia.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-NV-OnPremToCloud: ExternallySecured X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SN1PEPF0002636E:EE_|MN2PR12MB4406:EE_ X-MS-Office365-Filtering-Correlation-Id: d8befb13-57e0-433f-7701-08de2836aa7b X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|36860700013|7416014|376014|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?3tX3opQW2EET2D3KJjiHVS7MEV0r6cizZUrxIYbxohqwh/5c+FFN0ypjLrRx?= =?us-ascii?Q?RXW1RvRKJj4CnyThOzFRERnYCJyRqxSGJ5vMBYCrQSx5nKQGBrycb6/rp7mQ?= =?us-ascii?Q?ji1ZeNQhtq7i1pSmWYxt2ytk3c3tTy1/5ijq5VZDBTtEBJ7MkZin4moUW++9?= =?us-ascii?Q?QDOvKyhz8S4Nixvt3RoezPcJW9AYjEYkpAblunvFRGGVItrFtLC+HbiWaFKv?= =?us-ascii?Q?9QyJpKWAAZdeHZ9Yynota32SZ6107FEzlOfkreovQBXFWZBnyKW2+TcU0qqD?= =?us-ascii?Q?iNMsicGso96OF43y8EITeShQXwXE5td2JC5ht5ZiNVjRYX3kff2u/GpnUeB5?= =?us-ascii?Q?zoJf/teL9U9lff0zpeixudYAjDa/Ib6i8ZQT6HeMtyGloyMuMbq8QS6SGGVf?= =?us-ascii?Q?N/YOuAi+q3Oo9huPkwvWS1dtwPOa6obxpnYHNEDztZqPkRzKWihCJRbyMkf4?= =?us-ascii?Q?wpLDOxBULbYkgxo52X+Nv7Q9Y5xWyWMZvhEEgtmiUx5uJLmkXHRP7K6lXxL4?= =?us-ascii?Q?x3ukoXZTTlvz+Ry2AbndyqJpxZFQ/4BMs4nlQ3LJ6cRc4umqSSMI5kl7wH57?= =?us-ascii?Q?kK51kHh/buGNg/MgkveDfEE1UJEtAQQ1TxF5LClJhB+UJCUtf6x+bkIt71D9?= =?us-ascii?Q?juSRlJg8h+qlzNhpMzw4JoMqytWukiO7lelxiYvg1KSLeb1T0U7sRJQvCXaO?= =?us-ascii?Q?PlzaJI/Kb6sv4xM7j/OMqY6efxS0KJ6L+irc5t5bFzbwBS2VRudpUFBaNGSs?= =?us-ascii?Q?X9SvTLnsT2+C1+x/WDiUVvD8LpVTNEAnW0fSPkdBwWXwEbPX4hffztb8VdLX?= =?us-ascii?Q?pwqoDvuyZRGjDap0QQMzmiaG0A1GzXGcAnzXW/oXc1JP/OZ4GgRibExP/a+z?= =?us-ascii?Q?hjb7GECg5ZeaSgrAE2ngdixhKcTK31hiixM1gbOjVECYhV34sfZMhEjJWCWK?= =?us-ascii?Q?lql6drSHVDoEnWKbSXiN7sVQ5UrG3NRjEzBo7/l2Xcf0wlEjoD/y+XAJolg5?= =?us-ascii?Q?L6q4s91NlroR/3QuCAFG1hlcscFf1WXke2Cc3YbLOLPDSnqK8+yej/+zZAAE?= =?us-ascii?Q?t2r/j3P8XbOZByfpJf9ImG41KcEkG47OEUt10SdO1BSmkiP0VWIkc53eLiMM?= =?us-ascii?Q?SQsXF5xkOyy9fY5/nEDfXNhyw+TZAN0k5xgHkEJ7Uk8KR0b/LsRT0CJ9a6Sg?= =?us-ascii?Q?bZolatGZ88zYv1tZM+1qceV9Rsw5pOT3aCyAHQ4rGWcL7vBw66/cXato7+j1?= =?us-ascii?Q?hac2ukYh0HUu75ZAkwROMSwNiM64dGp9F40aAZIFCYVZD9a0+ztVyWj8TpH+?= =?us-ascii?Q?DDqWu7nidBi0uaRO0kBdKGHUem35q/YdEb63EifLXSpFZNFDYJqwmRjxKTj1?= =?us-ascii?Q?fla136ZFjBatf9lXTajpeJmkxdSe88o9ZadGVYhBXqka0E3zMax2707gFMJa?= =?us-ascii?Q?4Q+kbYAlm5O9VW5CM+EaeTyUG9bcZvcjHQYIh4ZuIs6jut7EdM3wIt1XnbUu?= =?us-ascii?Q?HjL627UPGSkDiVC5OQ/VDLMBP1ZIah2yLryotEd/UbTxse8pVj9oMQwtHx/L?= =?us-ascii?Q?SRGCC/DIRzGl7g9A/9k=3D?= X-Forefront-Antispam-Report: CIP:216.228.117.161;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail.nvidia.com;PTR:dc6edge2.nvidia.com;CAT:NONE;SFS:(13230040)(82310400026)(36860700013)(7416014)(376014)(1800799024);DIR:OUT;SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Nov 2025 13:13:58.5287 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: d8befb13-57e0-433f-7701-08de2836aa7b X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a;Ip=[216.228.117.161];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: SN1PEPF0002636E.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4406 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Cosmin Ratiu Devlink rate leafs and nodes were stored in their respective devlink objects pointed to by devlink_rate->devlink. This patch removes that association by introducing the concept of 'rate node devlink', which is where all rates that could link to each other are stored. For now this is the same as devlink_rate->devlink. After this patch, the devlink rates stored in this devlink instance could potentially be from multiple other devlink instances. So all rate node manipulation code was updated to: - correctly compare the actual devlink object during iteration. - maybe acquire additional locks (noop for now). Signed-off-by: Cosmin Ratiu Reviewed-by: Carolina Jubran Signed-off-by: Tariq Toukan Reviewed-by: Jiri Pirko --- include/net/devlink.h | 2 + net/devlink/rate.c | 192 +++++++++++++++++++++++++++++++----------- 2 files changed, 144 insertions(+), 50 deletions(-) diff --git a/include/net/devlink.h b/include/net/devlink.h index d01046ef0577..7e7789098f0e 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -1771,6 +1771,8 @@ void devlink_port_attrs_pci_sf_set(struct devlink_por= t *devlink_port, bool external); int devl_port_fn_devlink_set(struct devlink_port *devlink_port, struct devlink *fn_devlink); +struct devlink *devl_rate_lock(struct devlink *devlink); +void devl_rate_unlock(struct devlink *devlink); struct devlink_rate * devl_rate_node_create(struct devlink *devlink, void *priv, char *node_name, struct devlink_rate *parent); diff --git a/net/devlink/rate.c b/net/devlink/rate.c index 0d68b5c477dc..ddbd0beec4b9 100644 --- a/net/devlink/rate.c +++ b/net/devlink/rate.c @@ -30,13 +30,31 @@ devlink_rate_leaf_get_from_info(struct devlink *devlink= , struct genl_info *info) return devlink_rate ?: ERR_PTR(-ENODEV); } =20 +struct devlink *devl_rate_lock(struct devlink *devlink) +{ + return devlink; +} + +static struct devlink * +devl_get_rate_node_instance_locked(struct devlink *devlink) +{ + return devlink; +} + +void devl_rate_unlock(struct devlink *devlink) +{ +} + static struct devlink_rate * devlink_rate_node_get_by_name(struct devlink *devlink, const char *node_na= me) { struct devlink_rate *devlink_rate; + struct devlink *rate_devlink; =20 - list_for_each_entry(devlink_rate, &devlink->rate_list, list) { - if (devlink_rate_is_node(devlink_rate) && + rate_devlink =3D devl_get_rate_node_instance_locked(devlink); + list_for_each_entry(devlink_rate, &rate_devlink->rate_list, list) { + if (devlink_rate->devlink =3D=3D devlink && + devlink_rate_is_node(devlink_rate) && !strcmp(node_name, devlink_rate->name)) return devlink_rate; } @@ -190,17 +208,25 @@ static void devlink_rate_notify(struct devlink_rate *= devlink_rate, void devlink_rates_notify_register(struct devlink *devlink) { struct devlink_rate *rate_node; + struct devlink *rate_devlink; =20 - list_for_each_entry(rate_node, &devlink->rate_list, list) - devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW); + rate_devlink =3D devl_rate_lock(devlink); + list_for_each_entry(rate_node, &rate_devlink->rate_list, list) + if (rate_node->devlink =3D=3D devlink) + devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW); + devl_rate_unlock(devlink); } =20 void devlink_rates_notify_unregister(struct devlink *devlink) { struct devlink_rate *rate_node; + struct devlink *rate_devlink; =20 - list_for_each_entry_reverse(rate_node, &devlink->rate_list, list) - devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL); + rate_devlink =3D devl_rate_lock(devlink); + list_for_each_entry_reverse(rate_node, &rate_devlink->rate_list, list) + if (rate_node->devlink =3D=3D devlink) + devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL); + devl_rate_unlock(devlink); } =20 static int @@ -209,10 +235,12 @@ devlink_nl_rate_get_dump_one(struct sk_buff *msg, str= uct devlink *devlink, { struct devlink_nl_dump_state *state =3D devlink_dump_state(cb); struct devlink_rate *devlink_rate; + struct devlink *rate_devlink; int idx =3D 0; int err =3D 0; =20 - list_for_each_entry(devlink_rate, &devlink->rate_list, list) { + rate_devlink =3D devl_rate_lock(devlink); + list_for_each_entry(devlink_rate, &rate_devlink->rate_list, list) { enum devlink_command cmd =3D DEVLINK_CMD_RATE_NEW; u32 id =3D NETLINK_CB(cb->skb).portid; =20 @@ -220,6 +248,9 @@ devlink_nl_rate_get_dump_one(struct sk_buff *msg, struc= t devlink *devlink, idx++; continue; } + if (devlink_rate->devlink !=3D devlink) + continue; + err =3D devlink_nl_rate_fill(msg, devlink_rate, cmd, id, cb->nlh->nlmsg_seq, flags, NULL); if (err) { @@ -228,6 +259,7 @@ devlink_nl_rate_get_dump_one(struct sk_buff *msg, struc= t devlink *devlink, } idx++; } + devl_rate_unlock(devlink); =20 return err; } @@ -244,23 +276,33 @@ int devlink_nl_rate_get_doit(struct sk_buff *skb, str= uct genl_info *info) struct sk_buff *msg; int err; =20 + devl_rate_lock(devlink); devlink_rate =3D devlink_rate_get_from_info(devlink, info); - if (IS_ERR(devlink_rate)) - return PTR_ERR(devlink_rate); + if (IS_ERR(devlink_rate)) { + err =3D PTR_ERR(devlink_rate); + goto unlock; + } =20 msg =3D nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!msg) - return -ENOMEM; + if (!msg) { + err =3D -ENOMEM; + goto unlock; + } =20 err =3D devlink_nl_rate_fill(msg, devlink_rate, DEVLINK_CMD_RATE_NEW, info->snd_portid, info->snd_seq, 0, info->extack); - if (err) { - nlmsg_free(msg); - return err; - } + if (err) + goto err_fill; =20 + devl_rate_unlock(devlink); return genlmsg_reply(msg, info); + +err_fill: + nlmsg_free(msg); +unlock: + devl_rate_unlock(devlink); + return err; } =20 static bool @@ -590,24 +632,32 @@ int devlink_nl_rate_set_doit(struct sk_buff *skb, str= uct genl_info *info) const struct devlink_ops *ops; int err; =20 + devl_rate_lock(devlink); devlink_rate =3D devlink_rate_get_from_info(devlink, info); - if (IS_ERR(devlink_rate)) - return PTR_ERR(devlink_rate); + if (IS_ERR(devlink_rate)) { + err =3D PTR_ERR(devlink_rate); + goto unlock; + } =20 ops =3D devlink->ops; - if (!ops || !devlink_rate_set_ops_supported(ops, info, devlink_rate->type= )) - return -EOPNOTSUPP; + if (!ops || + !devlink_rate_set_ops_supported(ops, info, devlink_rate->type)) { + err =3D -EOPNOTSUPP; + goto unlock; + } =20 err =3D devlink_nl_rate_set(devlink_rate, ops, info); =20 if (!err) devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW); +unlock: + devl_rate_unlock(devlink); return err; } =20 int devlink_nl_rate_new_doit(struct sk_buff *skb, struct genl_info *info) { - struct devlink *devlink =3D info->user_ptr[0]; + struct devlink *rate_devlink, *devlink =3D info->user_ptr[0]; struct devlink_rate *rate_node; const struct devlink_ops *ops; int err; @@ -621,15 +671,21 @@ int devlink_nl_rate_new_doit(struct sk_buff *skb, str= uct genl_info *info) if (!devlink_rate_set_ops_supported(ops, info, DEVLINK_RATE_TYPE_NODE)) return -EOPNOTSUPP; =20 + rate_devlink =3D devl_rate_lock(devlink); rate_node =3D devlink_rate_node_get_from_attrs(devlink, info->attrs); - if (!IS_ERR(rate_node)) - return -EEXIST; - else if (rate_node =3D=3D ERR_PTR(-EINVAL)) - return -EINVAL; + if (!IS_ERR(rate_node)) { + err =3D -EEXIST; + goto unlock; + } else if (rate_node =3D=3D ERR_PTR(-EINVAL)) { + err =3D -EINVAL; + goto unlock; + } =20 rate_node =3D kzalloc(sizeof(*rate_node), GFP_KERNEL); - if (!rate_node) - return -ENOMEM; + if (!rate_node) { + err =3D -ENOMEM; + goto unlock; + } =20 rate_node->devlink =3D devlink; rate_node->type =3D DEVLINK_RATE_TYPE_NODE; @@ -648,8 +704,9 @@ int devlink_nl_rate_new_doit(struct sk_buff *skb, struc= t genl_info *info) goto err_rate_set; =20 refcount_set(&rate_node->refcnt, 1); - list_add(&rate_node->list, &devlink->rate_list); + list_add(&rate_node->list, &rate_devlink->rate_list); devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW); + devl_rate_unlock(devlink); return 0; =20 err_rate_set: @@ -658,6 +715,8 @@ int devlink_nl_rate_new_doit(struct sk_buff *skb, struc= t genl_info *info) kfree(rate_node->name); err_strdup: kfree(rate_node); +unlock: + devl_rate_unlock(devlink); return err; } =20 @@ -667,13 +726,17 @@ int devlink_nl_rate_del_doit(struct sk_buff *skb, str= uct genl_info *info) struct devlink_rate *rate_node; int err; =20 + devl_rate_lock(devlink); rate_node =3D devlink_rate_node_get_from_info(devlink, info); - if (IS_ERR(rate_node)) - return PTR_ERR(rate_node); + if (IS_ERR(rate_node)) { + err =3D PTR_ERR(rate_node); + goto unlock; + } =20 if (refcount_read(&rate_node->refcnt) > 1) { NL_SET_ERR_MSG(info->extack, "Node has children. Cannot delete node."); - return -EBUSY; + err =3D -EBUSY; + goto unlock; } =20 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL); @@ -684,6 +747,8 @@ int devlink_nl_rate_del_doit(struct sk_buff *skb, struc= t genl_info *info) list_del(&rate_node->list); kfree(rate_node->name); kfree(rate_node); +unlock: + devl_rate_unlock(devlink); return err; } =20 @@ -692,14 +757,20 @@ int devlink_rates_check(struct devlink *devlink, struct netlink_ext_ack *extack) { struct devlink_rate *devlink_rate; + struct devlink *rate_devlink; + int err =3D 0; =20 - list_for_each_entry(devlink_rate, &devlink->rate_list, list) - if (!rate_filter || rate_filter(devlink_rate)) { + rate_devlink =3D devl_rate_lock(devlink); + list_for_each_entry(devlink_rate, &rate_devlink->rate_list, list) + if (devlink_rate->devlink =3D=3D devlink && + (!rate_filter || rate_filter(devlink_rate))) { if (extack) NL_SET_ERR_MSG(extack, "Rate node(s) exists."); - return -EBUSY; + err =3D -EBUSY; + break; } - return 0; + devl_rate_unlock(devlink); + return err; } =20 /** @@ -716,14 +787,20 @@ devl_rate_node_create(struct devlink *devlink, void *= priv, char *node_name, struct devlink_rate *parent) { struct devlink_rate *rate_node; + struct devlink *rate_devlink; =20 + rate_devlink =3D devl_rate_lock(devlink); rate_node =3D devlink_rate_node_get_by_name(devlink, node_name); - if (!IS_ERR(rate_node)) - return ERR_PTR(-EEXIST); + if (!IS_ERR(rate_node)) { + rate_node =3D ERR_PTR(-EEXIST); + goto unlock; + } =20 rate_node =3D kzalloc(sizeof(*rate_node), GFP_KERNEL); - if (!rate_node) - return ERR_PTR(-ENOMEM); + if (!rate_node) { + rate_node =3D ERR_PTR(-ENOMEM); + goto unlock; + } =20 if (parent) { rate_node->parent =3D parent; @@ -737,12 +814,15 @@ devl_rate_node_create(struct devlink *devlink, void *= priv, char *node_name, rate_node->name =3D kstrdup(node_name, GFP_KERNEL); if (!rate_node->name) { kfree(rate_node); - return ERR_PTR(-ENOMEM); + rate_node =3D ERR_PTR(-ENOMEM); + goto unlock; } =20 refcount_set(&rate_node->refcnt, 1); - list_add(&rate_node->list, &devlink->rate_list); + list_add(&rate_node->list, &rate_devlink->rate_list); devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW); +unlock: + devl_rate_unlock(devlink); return rate_node; } EXPORT_SYMBOL_GPL(devl_rate_node_create); @@ -758,10 +838,10 @@ EXPORT_SYMBOL_GPL(devl_rate_node_create); int devl_rate_leaf_create(struct devlink_port *devlink_port, void *priv, struct devlink_rate *parent) { - struct devlink *devlink =3D devlink_port->devlink; + struct devlink *rate_devlink, *devlink =3D devlink_port->devlink; struct devlink_rate *devlink_rate; =20 - devl_assert_locked(devlink_port->devlink); + devl_assert_locked(devlink); =20 if (WARN_ON(devlink_port->devlink_rate)) return -EBUSY; @@ -770,6 +850,7 @@ int devl_rate_leaf_create(struct devlink_port *devlink_= port, void *priv, if (!devlink_rate) return -ENOMEM; =20 + rate_devlink =3D devl_rate_lock(devlink); if (parent) { devlink_rate->parent =3D parent; refcount_inc(&devlink_rate->parent->refcnt); @@ -779,9 +860,10 @@ int devl_rate_leaf_create(struct devlink_port *devlink= _port, void *priv, devlink_rate->devlink =3D devlink; devlink_rate->devlink_port =3D devlink_port; devlink_rate->priv =3D priv; - list_add_tail(&devlink_rate->list, &devlink->rate_list); + list_add_tail(&devlink_rate->list, &rate_devlink->rate_list); devlink_port->devlink_rate =3D devlink_rate; devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW); + devl_rate_unlock(devlink); =20 return 0; } @@ -797,16 +879,19 @@ EXPORT_SYMBOL_GPL(devl_rate_leaf_create); void devl_rate_leaf_destroy(struct devlink_port *devlink_port) { struct devlink_rate *devlink_rate =3D devlink_port->devlink_rate; + struct devlink *devlink =3D devlink_port->devlink; =20 - devl_assert_locked(devlink_port->devlink); + devl_assert_locked(devlink); if (!devlink_rate) return; =20 + devl_rate_lock(devlink); devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_DEL); if (devlink_rate->parent) refcount_dec(&devlink_rate->parent->refcnt); list_del(&devlink_rate->list); devlink_port->devlink_rate =3D NULL; + devl_rate_unlock(devlink); kfree(devlink_rate); } EXPORT_SYMBOL_GPL(devl_rate_leaf_destroy); @@ -815,18 +900,22 @@ EXPORT_SYMBOL_GPL(devl_rate_leaf_destroy); * devl_rate_nodes_destroy - destroy all devlink rate nodes on device * @devlink: devlink instance * - * Unset parent for all rate objects and destroy all rate nodes - * on specified device. + * Unset parent for all rate objects involving this device and destroy all= rate + * nodes on it. */ void devl_rate_nodes_destroy(struct devlink *devlink) { const struct devlink_ops *ops =3D devlink->ops; struct devlink_rate *devlink_rate, *tmp; + struct devlink *rate_devlink; =20 devl_assert_locked(devlink); + rate_devlink =3D devl_rate_lock(devlink); =20 - list_for_each_entry(devlink_rate, &devlink->rate_list, list) { - if (!devlink_rate->parent) + list_for_each_entry(devlink_rate, &rate_devlink->rate_list, list) { + if (!devlink_rate->parent || + (devlink_rate->devlink !=3D devlink && + devlink_rate->parent->devlink !=3D devlink)) continue; =20 if (devlink_rate_is_leaf(devlink_rate)) @@ -839,13 +928,16 @@ void devl_rate_nodes_destroy(struct devlink *devlink) refcount_dec(&devlink_rate->parent->refcnt); devlink_rate->parent =3D NULL; } - list_for_each_entry_safe(devlink_rate, tmp, &devlink->rate_list, list) { - if (devlink_rate_is_node(devlink_rate)) { + list_for_each_entry_safe(devlink_rate, tmp, &rate_devlink->rate_list, + list) { + if (devlink_rate->devlink =3D=3D devlink && + devlink_rate_is_node(devlink_rate)) { ops->rate_node_del(devlink_rate, devlink_rate->priv, NULL); list_del(&devlink_rate->list); kfree(devlink_rate->name); kfree(devlink_rate); } } + devl_rate_unlock(devlink); } EXPORT_SYMBOL_GPL(devl_rate_nodes_destroy); --=20 2.31.1