Skip to content

Commit 27f91aa

Browse files
anambiarinkuba-moo
authored andcommitted
netdev-genl: Add netlink framework functions for napi
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 <amritha.nambiar@intel.com> Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com> Link: https://lore.kernel.org/r/170147333637.5260.14807433239805550815.stgit@anambiarhost.jf.intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent ff99914 commit 27f91aa

File tree

3 files changed

+122
-4
lines changed

3 files changed

+122
-4
lines changed

net/core/dev.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ static int netif_rx_internal(struct sk_buff *skb);
165165
static int call_netdevice_notifiers_extack(unsigned long val,
166166
struct net_device *dev,
167167
struct netlink_ext_ack *extack);
168-
static struct napi_struct *napi_by_id(unsigned int napi_id);
169168

170169
/*
171170
* The @dev_base_head list is protected by @dev_base_lock and the rtnl
@@ -6139,7 +6138,7 @@ bool napi_complete_done(struct napi_struct *n, int work_done)
61396138
EXPORT_SYMBOL(napi_complete_done);
61406139

61416140
/* must be called under rcu_read_lock(), as we dont take a reference */
6142-
static struct napi_struct *napi_by_id(unsigned int napi_id)
6141+
struct napi_struct *napi_by_id(unsigned int napi_id)
61436142
{
61446143
unsigned int hash = napi_id % HASH_SIZE(napi_hash);
61456144
struct napi_struct *napi;

net/core/dev.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,4 +145,6 @@ void xdp_do_check_flushed(struct napi_struct *napi);
145145
#else
146146
static inline void xdp_do_check_flushed(struct napi_struct *napi) { }
147147
#endif
148+
149+
struct napi_struct *napi_by_id(unsigned int napi_id);
148150
#endif

net/core/netdev-genl.c

Lines changed: 119 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,16 @@
88
#include <net/xdp.h>
99
#include <net/xdp_sock.h>
1010
#include <net/netdev_rx_queue.h>
11+
#include <net/busy_poll.h>
1112

1213
#include "netdev-genl-gen.h"
14+
#include "dev.h"
1315

1416
struct netdev_nl_dump_ctx {
1517
unsigned long ifindex;
1618
unsigned int rxq_idx;
1719
unsigned int txq_idx;
20+
unsigned int napi_id;
1821
};
1922

2023
static struct netdev_nl_dump_ctx *netdev_dump_ctx(struct netlink_callback *cb)
@@ -155,14 +158,128 @@ int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
155158
return skb->len;
156159
}
157160

161+
static int
162+
netdev_nl_napi_fill_one(struct sk_buff *rsp, struct napi_struct *napi,
163+
const struct genl_info *info)
164+
{
165+
void *hdr;
166+
167+
if (WARN_ON_ONCE(!napi->dev))
168+
return -EINVAL;
169+
if (!(napi->dev->flags & IFF_UP))
170+
return 0;
171+
172+
hdr = genlmsg_iput(rsp, info);
173+
if (!hdr)
174+
return -EMSGSIZE;
175+
176+
if (napi->napi_id >= MIN_NAPI_ID &&
177+
nla_put_u32(rsp, NETDEV_A_NAPI_ID, napi->napi_id))
178+
goto nla_put_failure;
179+
180+
if (nla_put_u32(rsp, NETDEV_A_NAPI_IFINDEX, napi->dev->ifindex))
181+
goto nla_put_failure;
182+
183+
genlmsg_end(rsp, hdr);
184+
return 0;
185+
186+
nla_put_failure:
187+
genlmsg_cancel(rsp, hdr);
188+
return -EMSGSIZE;
189+
}
190+
158191
int netdev_nl_napi_get_doit(struct sk_buff *skb, struct genl_info *info)
159192
{
160-
return -EOPNOTSUPP;
193+
struct napi_struct *napi;
194+
struct sk_buff *rsp;
195+
u32 napi_id;
196+
int err;
197+
198+
if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_NAPI_ID))
199+
return -EINVAL;
200+
201+
napi_id = nla_get_u32(info->attrs[NETDEV_A_NAPI_ID]);
202+
203+
rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
204+
if (!rsp)
205+
return -ENOMEM;
206+
207+
rtnl_lock();
208+
209+
napi = napi_by_id(napi_id);
210+
if (napi)
211+
err = netdev_nl_napi_fill_one(rsp, napi, info);
212+
else
213+
err = -EINVAL;
214+
215+
rtnl_unlock();
216+
217+
if (err)
218+
goto err_free_msg;
219+
220+
return genlmsg_reply(rsp, info);
221+
222+
err_free_msg:
223+
nlmsg_free(rsp);
224+
return err;
225+
}
226+
227+
static int
228+
netdev_nl_napi_dump_one(struct net_device *netdev, struct sk_buff *rsp,
229+
const struct genl_info *info,
230+
struct netdev_nl_dump_ctx *ctx)
231+
{
232+
struct napi_struct *napi;
233+
int err = 0;
234+
235+
if (!(netdev->flags & IFF_UP))
236+
return err;
237+
238+
list_for_each_entry(napi, &netdev->napi_list, dev_list) {
239+
if (ctx->napi_id && napi->napi_id >= ctx->napi_id)
240+
continue;
241+
242+
err = netdev_nl_napi_fill_one(rsp, napi, info);
243+
if (err)
244+
return err;
245+
ctx->napi_id = napi->napi_id;
246+
}
247+
return err;
161248
}
162249

163250
int netdev_nl_napi_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
164251
{
165-
return -EOPNOTSUPP;
252+
struct netdev_nl_dump_ctx *ctx = netdev_dump_ctx(cb);
253+
const struct genl_info *info = genl_info_dump(cb);
254+
struct net *net = sock_net(skb->sk);
255+
struct net_device *netdev;
256+
u32 ifindex = 0;
257+
int err = 0;
258+
259+
if (info->attrs[NETDEV_A_NAPI_IFINDEX])
260+
ifindex = nla_get_u32(info->attrs[NETDEV_A_NAPI_IFINDEX]);
261+
262+
rtnl_lock();
263+
if (ifindex) {
264+
netdev = __dev_get_by_index(net, ifindex);
265+
if (netdev)
266+
err = netdev_nl_napi_dump_one(netdev, skb, info, ctx);
267+
else
268+
err = -ENODEV;
269+
} else {
270+
for_each_netdev_dump(net, netdev, ctx->ifindex) {
271+
err = netdev_nl_napi_dump_one(netdev, skb, info, ctx);
272+
if (err < 0)
273+
break;
274+
ctx->napi_id = 0;
275+
}
276+
}
277+
rtnl_unlock();
278+
279+
if (err != -EMSGSIZE)
280+
return err;
281+
282+
return skb->len;
166283
}
167284

168285
static int

0 commit comments

Comments
 (0)