From patchwork Tue Sep 19 22:27:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Nambiar, Amritha" X-Patchwork-Id: 13391970 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (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 2FE473B285 for ; Tue, 19 Sep 2023 22:15:19 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 13857D7 for ; Tue, 19 Sep 2023 15:14:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695161698; x=1726697698; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ejxsKZ2HAW0bDG6Czz9bEKBgJRSE/jwj3rHWsDb57Wk=; b=co5lHg+04puJapSXh0oBzd+AZc/A5ECoclXag0g+dT7FfjzVv2YR5wkk SFMEdgH24T4fz+nIX7mdBtPvzNtW1p/f1NN7aQrCmgPH7Xpis+i+N6Fyd SppMBYvdpszXnk1++CX4jBGQDCPWquBGhU62jgJQ55MK7Gm0d2MaFjQGO 0PxyeP/cFZ3Da1A25hJ8CuBYJxIu7SQnZNxN020Hs1V8Ajifb/M9JZikt 9vd1vu50Z/SzH0FYqx0Y5yG7AYMgq1xgRwmGYeYmzysfKC0kTnmb3luvD dvc6JNH8imb90ut0FJwoRcValpRlzIIrpEY5Z7Y+YHwStFMS/7B0m8DTj A==; X-IronPort-AV: E=McAfee;i="6600,9927,10838"; a="383904050" X-IronPort-AV: E=Sophos;i="6.02,160,1688454000"; d="scan'208";a="383904050" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Sep 2023 15:12:18 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10838"; a="696067059" X-IronPort-AV: E=Sophos;i="6.02,160,1688454000"; d="scan'208";a="696067059" Received: from anambiarhost.jf.intel.com ([10.166.29.163]) by orsmga003.jf.intel.com with ESMTP; 19 Sep 2023 15:12:18 -0700 Subject: [net-next PATCH v3 06/10] netdev-genl: Add netlink framework functions for napi From: Amritha Nambiar To: netdev@vger.kernel.org, kuba@kernel.org Cc: sridhar.samudrala@intel.com, amritha.nambiar@intel.com Date: Tue, 19 Sep 2023 15:27:47 -0700 Message-ID: <169516246697.7377.18105000910116179893.stgit@anambiarhost.jf.intel.com> In-Reply-To: <169516206704.7377.12938469824609831999.stgit@anambiarhost.jf.intel.com> References: <169516206704.7377.12938469824609831999.stgit@anambiarhost.jf.intel.com> User-Agent: StGit/unknown-version Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org Implement the netdev netlink framework functions for napi support. The netdev structure tracks all the napi instances and napi fields. The napi instances and associated parameters can be retrieved this way. Signed-off-by: Amritha Nambiar Reviewed-by: Sridhar Samudrala --- include/linux/netdevice.h | 2 + net/core/dev.c | 4 +- net/core/netdev-genl.c | 117 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 119 insertions(+), 4 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 69e363918e4b..e7321178dc1a 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -536,6 +536,8 @@ static inline bool napi_complete(struct napi_struct *n) return napi_complete_done(n, 0); } +struct napi_struct *napi_by_id(unsigned int napi_id); + int dev_set_threaded(struct net_device *dev, bool threaded); /** diff --git a/net/core/dev.c b/net/core/dev.c index 508b1d799681..ea6b3115ee8b 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -165,7 +165,6 @@ static int netif_rx_internal(struct sk_buff *skb); static int call_netdevice_notifiers_extack(unsigned long val, struct net_device *dev, struct netlink_ext_ack *extack); -static struct napi_struct *napi_by_id(unsigned int napi_id); /* * The @dev_base_head list is protected by @dev_base_lock and the rtnl @@ -6133,7 +6132,7 @@ bool napi_complete_done(struct napi_struct *n, int work_done) EXPORT_SYMBOL(napi_complete_done); /* must be called under rcu_read_lock(), as we dont take a reference */ -static struct napi_struct *napi_by_id(unsigned int napi_id) +struct napi_struct *napi_by_id(unsigned int napi_id) { unsigned int hash = napi_id % HASH_SIZE(napi_hash); struct napi_struct *napi; @@ -6144,6 +6143,7 @@ static struct napi_struct *napi_by_id(unsigned int napi_id) return NULL; } +EXPORT_SYMBOL(napi_by_id); #if defined(CONFIG_NET_RX_BUSY_POLL) diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c index 8609884fefe4..6f4ed21ebd15 100644 --- a/net/core/netdev-genl.c +++ b/net/core/netdev-genl.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "netdev-genl-gen.h" @@ -14,6 +15,7 @@ struct netdev_nl_dump_ctx { unsigned long ifindex; unsigned int rxq_idx; unsigned int txq_idx; + unsigned int napi_id; }; static inline struct netdev_nl_dump_ctx * @@ -145,14 +147,125 @@ int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb) return skb->len; } +static int +netdev_nl_napi_fill_one(struct sk_buff *rsp, struct napi_struct *napi, + const struct genl_info *info) +{ + void *hdr; + + if (WARN_ON_ONCE(!napi->dev)) + return -EINVAL; + + hdr = genlmsg_iput(rsp, info); + if (!hdr) + return -EMSGSIZE; + + if (napi->napi_id >= MIN_NAPI_ID && + nla_put_u32(rsp, NETDEV_A_NAPI_NAPI_ID, napi->napi_id)) + goto nla_put_failure; + + if (nla_put_u32(rsp, NETDEV_A_NAPI_IFINDEX, napi->dev->ifindex)) + goto nla_put_failure; + + genlmsg_end(rsp, hdr); + return 0; + +nla_put_failure: + genlmsg_cancel(rsp, hdr); + return -EMSGSIZE; +} + int netdev_nl_napi_get_doit(struct sk_buff *skb, struct genl_info *info) { - return -EOPNOTSUPP; + struct napi_struct *napi; + struct sk_buff *rsp; + u32 napi_id; + int err; + + if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_NAPI_NAPI_ID)) + return -EINVAL; + + napi_id = nla_get_u32(info->attrs[NETDEV_A_NAPI_NAPI_ID]); + + rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!rsp) + return -ENOMEM; + + rtnl_lock(); + + napi = napi_by_id(napi_id); + if (napi) + err = netdev_nl_napi_fill_one(rsp, napi, info); + else + err = -EINVAL; + + rtnl_unlock(); + + if (err) + goto err_free_msg; + + return genlmsg_reply(rsp, info); + +err_free_msg: + nlmsg_free(rsp); + return err; +} + +static int +netdev_nl_napi_dump_one(struct net_device *netdev, struct sk_buff *rsp, + const struct genl_info *info, unsigned int *start) +{ + struct napi_struct *napi; + int err = 0; + + list_for_each_entry_rcu(napi, &netdev->napi_list, dev_list) { + if (*start && napi->napi_id >= *start) + continue; + + err = netdev_nl_napi_fill_one(rsp, napi, info); + if (err) + break; + *start = napi->napi_id; + } + return err; } int netdev_nl_napi_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb) { - return -EOPNOTSUPP; + struct netdev_nl_dump_ctx *ctx = netdev_dump_ctx(cb); + const struct genl_info *info = genl_info_dump(cb); + struct net *net = sock_net(skb->sk); + unsigned int n_id = ctx->napi_id; + struct net_device *netdev; + u32 ifindex = 0; + int err = 0; + + if (info->attrs[NETDEV_A_NAPI_IFINDEX]) + ifindex = nla_get_u32(info->attrs[NETDEV_A_NAPI_IFINDEX]); + + rtnl_lock(); + if (ifindex) { + netdev = __dev_get_by_index(net, ifindex); + if (netdev) + err = netdev_nl_napi_dump_one(netdev, skb, info, &n_id); + else + err = -ENODEV; + } else { + for_each_netdev_dump(net, netdev, ctx->ifindex) { + err = netdev_nl_napi_dump_one(netdev, skb, info, &n_id); + if (err < 0) + break; + if (!err) + n_id = 0; + } + } + rtnl_unlock(); + + if (err != -EMSGSIZE) + return err; + + ctx->napi_id = n_id; + return skb->len; } static int