netdev-genl.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. #include <linux/netdevice.h>
  3. #include <linux/notifier.h>
  4. #include <linux/rtnetlink.h>
  5. #include <net/busy_poll.h>
  6. #include <net/net_namespace.h>
  7. #include <net/netdev_queues.h>
  8. #include <net/netdev_rx_queue.h>
  9. #include <net/sock.h>
  10. #include <net/xdp.h>
  11. #include <net/xdp_sock.h>
  12. #include <net/page_pool/memory_provider.h>
  13. #include "dev.h"
  14. #include "devmem.h"
  15. #include "netdev-genl-gen.h"
  16. struct netdev_nl_dump_ctx {
  17. unsigned long ifindex;
  18. unsigned int rxq_idx;
  19. unsigned int txq_idx;
  20. unsigned int napi_id;
  21. };
  22. static struct netdev_nl_dump_ctx *netdev_dump_ctx(struct netlink_callback *cb)
  23. {
  24. NL_ASSERT_CTX_FITS(struct netdev_nl_dump_ctx);
  25. return (struct netdev_nl_dump_ctx *)cb->ctx;
  26. }
  27. static int
  28. netdev_nl_dev_fill(struct net_device *netdev, struct sk_buff *rsp,
  29. const struct genl_info *info)
  30. {
  31. u64 xsk_features = 0;
  32. u64 xdp_rx_meta = 0;
  33. void *hdr;
  34. netdev_assert_locked(netdev); /* note: rtnl_lock may not be held! */
  35. hdr = genlmsg_iput(rsp, info);
  36. if (!hdr)
  37. return -EMSGSIZE;
  38. #define XDP_METADATA_KFUNC(_, flag, __, xmo) \
  39. if (netdev->xdp_metadata_ops && netdev->xdp_metadata_ops->xmo) \
  40. xdp_rx_meta |= flag;
  41. XDP_METADATA_KFUNC_xxx
  42. #undef XDP_METADATA_KFUNC
  43. if (netdev->xsk_tx_metadata_ops) {
  44. if (netdev->xsk_tx_metadata_ops->tmo_fill_timestamp)
  45. xsk_features |= NETDEV_XSK_FLAGS_TX_TIMESTAMP;
  46. if (netdev->xsk_tx_metadata_ops->tmo_request_checksum)
  47. xsk_features |= NETDEV_XSK_FLAGS_TX_CHECKSUM;
  48. if (netdev->xsk_tx_metadata_ops->tmo_request_launch_time)
  49. xsk_features |= NETDEV_XSK_FLAGS_TX_LAUNCH_TIME_FIFO;
  50. }
  51. if (nla_put_u32(rsp, NETDEV_A_DEV_IFINDEX, netdev->ifindex) ||
  52. nla_put_u64_64bit(rsp, NETDEV_A_DEV_XDP_FEATURES,
  53. netdev->xdp_features, NETDEV_A_DEV_PAD) ||
  54. nla_put_u64_64bit(rsp, NETDEV_A_DEV_XDP_RX_METADATA_FEATURES,
  55. xdp_rx_meta, NETDEV_A_DEV_PAD) ||
  56. nla_put_u64_64bit(rsp, NETDEV_A_DEV_XSK_FEATURES,
  57. xsk_features, NETDEV_A_DEV_PAD))
  58. goto err_cancel_msg;
  59. if (netdev->xdp_features & NETDEV_XDP_ACT_XSK_ZEROCOPY) {
  60. if (nla_put_u32(rsp, NETDEV_A_DEV_XDP_ZC_MAX_SEGS,
  61. netdev->xdp_zc_max_segs))
  62. goto err_cancel_msg;
  63. }
  64. genlmsg_end(rsp, hdr);
  65. return 0;
  66. err_cancel_msg:
  67. genlmsg_cancel(rsp, hdr);
  68. return -EMSGSIZE;
  69. }
  70. static void
  71. netdev_genl_dev_notify(struct net_device *netdev, int cmd)
  72. {
  73. struct genl_info info;
  74. struct sk_buff *ntf;
  75. if (!genl_has_listeners(&netdev_nl_family, dev_net(netdev),
  76. NETDEV_NLGRP_MGMT))
  77. return;
  78. genl_info_init_ntf(&info, &netdev_nl_family, cmd);
  79. ntf = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
  80. if (!ntf)
  81. return;
  82. if (netdev_nl_dev_fill(netdev, ntf, &info)) {
  83. nlmsg_free(ntf);
  84. return;
  85. }
  86. genlmsg_multicast_netns(&netdev_nl_family, dev_net(netdev), ntf,
  87. 0, NETDEV_NLGRP_MGMT, GFP_KERNEL);
  88. }
  89. int netdev_nl_dev_get_doit(struct sk_buff *skb, struct genl_info *info)
  90. {
  91. struct net_device *netdev;
  92. struct sk_buff *rsp;
  93. u32 ifindex;
  94. int err;
  95. if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_DEV_IFINDEX))
  96. return -EINVAL;
  97. ifindex = nla_get_u32(info->attrs[NETDEV_A_DEV_IFINDEX]);
  98. rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
  99. if (!rsp)
  100. return -ENOMEM;
  101. netdev = netdev_get_by_index_lock(genl_info_net(info), ifindex);
  102. if (!netdev) {
  103. err = -ENODEV;
  104. goto err_free_msg;
  105. }
  106. err = netdev_nl_dev_fill(netdev, rsp, info);
  107. netdev_unlock(netdev);
  108. if (err)
  109. goto err_free_msg;
  110. return genlmsg_reply(rsp, info);
  111. err_free_msg:
  112. nlmsg_free(rsp);
  113. return err;
  114. }
  115. int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
  116. {
  117. struct netdev_nl_dump_ctx *ctx = netdev_dump_ctx(cb);
  118. struct net *net = sock_net(skb->sk);
  119. int err;
  120. for_each_netdev_lock_scoped(net, netdev, ctx->ifindex) {
  121. err = netdev_nl_dev_fill(netdev, skb, genl_info_dump(cb));
  122. if (err < 0)
  123. return err;
  124. }
  125. return 0;
  126. }
  127. static int
  128. netdev_nl_napi_fill_one(struct sk_buff *rsp, struct napi_struct *napi,
  129. const struct genl_info *info)
  130. {
  131. unsigned long irq_suspend_timeout;
  132. unsigned long gro_flush_timeout;
  133. u32 napi_defer_hard_irqs;
  134. void *hdr;
  135. pid_t pid;
  136. if (!napi->dev->up)
  137. return 0;
  138. hdr = genlmsg_iput(rsp, info);
  139. if (!hdr)
  140. return -EMSGSIZE;
  141. if (nla_put_u32(rsp, NETDEV_A_NAPI_ID, napi->napi_id))
  142. goto nla_put_failure;
  143. if (nla_put_u32(rsp, NETDEV_A_NAPI_IFINDEX, napi->dev->ifindex))
  144. goto nla_put_failure;
  145. if (napi->irq >= 0 && nla_put_u32(rsp, NETDEV_A_NAPI_IRQ, napi->irq))
  146. goto nla_put_failure;
  147. if (nla_put_uint(rsp, NETDEV_A_NAPI_THREADED,
  148. napi_get_threaded(napi)))
  149. goto nla_put_failure;
  150. if (napi->thread) {
  151. pid = task_pid_nr(napi->thread);
  152. if (nla_put_u32(rsp, NETDEV_A_NAPI_PID, pid))
  153. goto nla_put_failure;
  154. }
  155. napi_defer_hard_irqs = napi_get_defer_hard_irqs(napi);
  156. if (nla_put_s32(rsp, NETDEV_A_NAPI_DEFER_HARD_IRQS,
  157. napi_defer_hard_irqs))
  158. goto nla_put_failure;
  159. irq_suspend_timeout = napi_get_irq_suspend_timeout(napi);
  160. if (nla_put_uint(rsp, NETDEV_A_NAPI_IRQ_SUSPEND_TIMEOUT,
  161. irq_suspend_timeout))
  162. goto nla_put_failure;
  163. gro_flush_timeout = napi_get_gro_flush_timeout(napi);
  164. if (nla_put_uint(rsp, NETDEV_A_NAPI_GRO_FLUSH_TIMEOUT,
  165. gro_flush_timeout))
  166. goto nla_put_failure;
  167. genlmsg_end(rsp, hdr);
  168. return 0;
  169. nla_put_failure:
  170. genlmsg_cancel(rsp, hdr);
  171. return -EMSGSIZE;
  172. }
  173. int netdev_nl_napi_get_doit(struct sk_buff *skb, struct genl_info *info)
  174. {
  175. struct napi_struct *napi;
  176. struct sk_buff *rsp;
  177. u32 napi_id;
  178. int err;
  179. if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_NAPI_ID))
  180. return -EINVAL;
  181. napi_id = nla_get_u32(info->attrs[NETDEV_A_NAPI_ID]);
  182. rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
  183. if (!rsp)
  184. return -ENOMEM;
  185. napi = netdev_napi_by_id_lock(genl_info_net(info), napi_id);
  186. if (napi) {
  187. err = netdev_nl_napi_fill_one(rsp, napi, info);
  188. netdev_unlock(napi->dev);
  189. } else {
  190. NL_SET_BAD_ATTR(info->extack, info->attrs[NETDEV_A_NAPI_ID]);
  191. err = -ENOENT;
  192. }
  193. if (err) {
  194. goto err_free_msg;
  195. } else if (!rsp->len) {
  196. err = -ENOENT;
  197. goto err_free_msg;
  198. }
  199. return genlmsg_reply(rsp, info);
  200. err_free_msg:
  201. nlmsg_free(rsp);
  202. return err;
  203. }
  204. static int
  205. netdev_nl_napi_dump_one(struct net_device *netdev, struct sk_buff *rsp,
  206. const struct genl_info *info,
  207. struct netdev_nl_dump_ctx *ctx)
  208. {
  209. struct napi_struct *napi;
  210. unsigned int prev_id;
  211. int err = 0;
  212. if (!netdev->up)
  213. return err;
  214. prev_id = UINT_MAX;
  215. list_for_each_entry(napi, &netdev->napi_list, dev_list) {
  216. if (!napi_id_valid(napi->napi_id))
  217. continue;
  218. /* Dump continuation below depends on the list being sorted */
  219. WARN_ON_ONCE(napi->napi_id >= prev_id);
  220. prev_id = napi->napi_id;
  221. if (ctx->napi_id && napi->napi_id >= ctx->napi_id)
  222. continue;
  223. err = netdev_nl_napi_fill_one(rsp, napi, info);
  224. if (err)
  225. return err;
  226. ctx->napi_id = napi->napi_id;
  227. }
  228. return err;
  229. }
  230. int netdev_nl_napi_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
  231. {
  232. struct netdev_nl_dump_ctx *ctx = netdev_dump_ctx(cb);
  233. const struct genl_info *info = genl_info_dump(cb);
  234. struct net *net = sock_net(skb->sk);
  235. struct net_device *netdev;
  236. u32 ifindex = 0;
  237. int err = 0;
  238. if (info->attrs[NETDEV_A_NAPI_IFINDEX])
  239. ifindex = nla_get_u32(info->attrs[NETDEV_A_NAPI_IFINDEX]);
  240. if (ifindex) {
  241. netdev = netdev_get_by_index_lock(net, ifindex);
  242. if (netdev) {
  243. err = netdev_nl_napi_dump_one(netdev, skb, info, ctx);
  244. netdev_unlock(netdev);
  245. } else {
  246. err = -ENODEV;
  247. }
  248. } else {
  249. for_each_netdev_lock_scoped(net, netdev, ctx->ifindex) {
  250. err = netdev_nl_napi_dump_one(netdev, skb, info, ctx);
  251. if (err < 0)
  252. break;
  253. ctx->napi_id = 0;
  254. }
  255. }
  256. return err;
  257. }
  258. static int
  259. netdev_nl_napi_set_config(struct napi_struct *napi, struct genl_info *info)
  260. {
  261. u64 irq_suspend_timeout = 0;
  262. u64 gro_flush_timeout = 0;
  263. u8 threaded = 0;
  264. u32 defer = 0;
  265. if (info->attrs[NETDEV_A_NAPI_THREADED]) {
  266. int ret;
  267. threaded = nla_get_uint(info->attrs[NETDEV_A_NAPI_THREADED]);
  268. ret = napi_set_threaded(napi, threaded);
  269. if (ret)
  270. return ret;
  271. }
  272. if (info->attrs[NETDEV_A_NAPI_DEFER_HARD_IRQS]) {
  273. defer = nla_get_u32(info->attrs[NETDEV_A_NAPI_DEFER_HARD_IRQS]);
  274. napi_set_defer_hard_irqs(napi, defer);
  275. }
  276. if (info->attrs[NETDEV_A_NAPI_IRQ_SUSPEND_TIMEOUT]) {
  277. irq_suspend_timeout = nla_get_uint(info->attrs[NETDEV_A_NAPI_IRQ_SUSPEND_TIMEOUT]);
  278. napi_set_irq_suspend_timeout(napi, irq_suspend_timeout);
  279. }
  280. if (info->attrs[NETDEV_A_NAPI_GRO_FLUSH_TIMEOUT]) {
  281. gro_flush_timeout = nla_get_uint(info->attrs[NETDEV_A_NAPI_GRO_FLUSH_TIMEOUT]);
  282. napi_set_gro_flush_timeout(napi, gro_flush_timeout);
  283. }
  284. return 0;
  285. }
  286. int netdev_nl_napi_set_doit(struct sk_buff *skb, struct genl_info *info)
  287. {
  288. struct napi_struct *napi;
  289. unsigned int napi_id;
  290. int err;
  291. if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_NAPI_ID))
  292. return -EINVAL;
  293. napi_id = nla_get_u32(info->attrs[NETDEV_A_NAPI_ID]);
  294. napi = netdev_napi_by_id_lock(genl_info_net(info), napi_id);
  295. if (napi) {
  296. err = netdev_nl_napi_set_config(napi, info);
  297. netdev_unlock(napi->dev);
  298. } else {
  299. NL_SET_BAD_ATTR(info->extack, info->attrs[NETDEV_A_NAPI_ID]);
  300. err = -ENOENT;
  301. }
  302. return err;
  303. }
  304. static int nla_put_napi_id(struct sk_buff *skb, const struct napi_struct *napi)
  305. {
  306. if (napi && napi_id_valid(napi->napi_id))
  307. return nla_put_u32(skb, NETDEV_A_QUEUE_NAPI_ID, napi->napi_id);
  308. return 0;
  309. }
  310. static int
  311. netdev_nl_queue_fill_one(struct sk_buff *rsp, struct net_device *netdev,
  312. u32 q_idx, u32 q_type, const struct genl_info *info)
  313. {
  314. struct pp_memory_provider_params *params;
  315. struct netdev_rx_queue *rxq;
  316. struct netdev_queue *txq;
  317. void *hdr;
  318. hdr = genlmsg_iput(rsp, info);
  319. if (!hdr)
  320. return -EMSGSIZE;
  321. if (nla_put_u32(rsp, NETDEV_A_QUEUE_ID, q_idx) ||
  322. nla_put_u32(rsp, NETDEV_A_QUEUE_TYPE, q_type) ||
  323. nla_put_u32(rsp, NETDEV_A_QUEUE_IFINDEX, netdev->ifindex))
  324. goto nla_put_failure;
  325. switch (q_type) {
  326. case NETDEV_QUEUE_TYPE_RX:
  327. rxq = __netif_get_rx_queue(netdev, q_idx);
  328. if (nla_put_napi_id(rsp, rxq->napi))
  329. goto nla_put_failure;
  330. params = &rxq->mp_params;
  331. if (params->mp_ops &&
  332. params->mp_ops->nl_fill(params->mp_priv, rsp, rxq))
  333. goto nla_put_failure;
  334. #ifdef CONFIG_XDP_SOCKETS
  335. if (rxq->pool)
  336. if (nla_put_empty_nest(rsp, NETDEV_A_QUEUE_XSK))
  337. goto nla_put_failure;
  338. #endif
  339. break;
  340. case NETDEV_QUEUE_TYPE_TX:
  341. txq = netdev_get_tx_queue(netdev, q_idx);
  342. if (nla_put_napi_id(rsp, txq->napi))
  343. goto nla_put_failure;
  344. #ifdef CONFIG_XDP_SOCKETS
  345. if (txq->pool)
  346. if (nla_put_empty_nest(rsp, NETDEV_A_QUEUE_XSK))
  347. goto nla_put_failure;
  348. #endif
  349. break;
  350. }
  351. genlmsg_end(rsp, hdr);
  352. return 0;
  353. nla_put_failure:
  354. genlmsg_cancel(rsp, hdr);
  355. return -EMSGSIZE;
  356. }
  357. static int netdev_nl_queue_validate(struct net_device *netdev, u32 q_id,
  358. u32 q_type)
  359. {
  360. switch (q_type) {
  361. case NETDEV_QUEUE_TYPE_RX:
  362. if (q_id >= netdev->real_num_rx_queues)
  363. return -EINVAL;
  364. return 0;
  365. case NETDEV_QUEUE_TYPE_TX:
  366. if (q_id >= netdev->real_num_tx_queues)
  367. return -EINVAL;
  368. }
  369. return 0;
  370. }
  371. static int
  372. netdev_nl_queue_fill(struct sk_buff *rsp, struct net_device *netdev, u32 q_idx,
  373. u32 q_type, const struct genl_info *info)
  374. {
  375. int err;
  376. if (!netdev->up)
  377. return -ENOENT;
  378. err = netdev_nl_queue_validate(netdev, q_idx, q_type);
  379. if (err)
  380. return err;
  381. return netdev_nl_queue_fill_one(rsp, netdev, q_idx, q_type, info);
  382. }
  383. int netdev_nl_queue_get_doit(struct sk_buff *skb, struct genl_info *info)
  384. {
  385. u32 q_id, q_type, ifindex;
  386. struct net_device *netdev;
  387. struct sk_buff *rsp;
  388. int err;
  389. if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_QUEUE_ID) ||
  390. GENL_REQ_ATTR_CHECK(info, NETDEV_A_QUEUE_TYPE) ||
  391. GENL_REQ_ATTR_CHECK(info, NETDEV_A_QUEUE_IFINDEX))
  392. return -EINVAL;
  393. q_id = nla_get_u32(info->attrs[NETDEV_A_QUEUE_ID]);
  394. q_type = nla_get_u32(info->attrs[NETDEV_A_QUEUE_TYPE]);
  395. ifindex = nla_get_u32(info->attrs[NETDEV_A_QUEUE_IFINDEX]);
  396. rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
  397. if (!rsp)
  398. return -ENOMEM;
  399. netdev = netdev_get_by_index_lock_ops_compat(genl_info_net(info),
  400. ifindex);
  401. if (netdev) {
  402. err = netdev_nl_queue_fill(rsp, netdev, q_id, q_type, info);
  403. netdev_unlock_ops_compat(netdev);
  404. } else {
  405. err = -ENODEV;
  406. }
  407. if (err)
  408. goto err_free_msg;
  409. return genlmsg_reply(rsp, info);
  410. err_free_msg:
  411. nlmsg_free(rsp);
  412. return err;
  413. }
  414. static int
  415. netdev_nl_queue_dump_one(struct net_device *netdev, struct sk_buff *rsp,
  416. const struct genl_info *info,
  417. struct netdev_nl_dump_ctx *ctx)
  418. {
  419. int err = 0;
  420. if (!netdev->up)
  421. return err;
  422. for (; ctx->rxq_idx < netdev->real_num_rx_queues; ctx->rxq_idx++) {
  423. err = netdev_nl_queue_fill_one(rsp, netdev, ctx->rxq_idx,
  424. NETDEV_QUEUE_TYPE_RX, info);
  425. if (err)
  426. return err;
  427. }
  428. for (; ctx->txq_idx < netdev->real_num_tx_queues; ctx->txq_idx++) {
  429. err = netdev_nl_queue_fill_one(rsp, netdev, ctx->txq_idx,
  430. NETDEV_QUEUE_TYPE_TX, info);
  431. if (err)
  432. return err;
  433. }
  434. return err;
  435. }
  436. int netdev_nl_queue_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
  437. {
  438. struct netdev_nl_dump_ctx *ctx = netdev_dump_ctx(cb);
  439. const struct genl_info *info = genl_info_dump(cb);
  440. struct net *net = sock_net(skb->sk);
  441. struct net_device *netdev;
  442. u32 ifindex = 0;
  443. int err = 0;
  444. if (info->attrs[NETDEV_A_QUEUE_IFINDEX])
  445. ifindex = nla_get_u32(info->attrs[NETDEV_A_QUEUE_IFINDEX]);
  446. if (ifindex) {
  447. netdev = netdev_get_by_index_lock_ops_compat(net, ifindex);
  448. if (netdev) {
  449. err = netdev_nl_queue_dump_one(netdev, skb, info, ctx);
  450. netdev_unlock_ops_compat(netdev);
  451. } else {
  452. err = -ENODEV;
  453. }
  454. } else {
  455. for_each_netdev_lock_ops_compat_scoped(net, netdev,
  456. ctx->ifindex) {
  457. err = netdev_nl_queue_dump_one(netdev, skb, info, ctx);
  458. if (err < 0)
  459. break;
  460. ctx->rxq_idx = 0;
  461. ctx->txq_idx = 0;
  462. }
  463. }
  464. return err;
  465. }
  466. #define NETDEV_STAT_NOT_SET (~0ULL)
  467. static void netdev_nl_stats_add(void *_sum, const void *_add, size_t size)
  468. {
  469. const u64 *add = _add;
  470. u64 *sum = _sum;
  471. while (size) {
  472. if (*add != NETDEV_STAT_NOT_SET && *sum != NETDEV_STAT_NOT_SET)
  473. *sum += *add;
  474. sum++;
  475. add++;
  476. size -= 8;
  477. }
  478. }
  479. static int netdev_stat_put(struct sk_buff *rsp, unsigned int attr_id, u64 value)
  480. {
  481. if (value == NETDEV_STAT_NOT_SET)
  482. return 0;
  483. return nla_put_uint(rsp, attr_id, value);
  484. }
  485. static int
  486. netdev_nl_stats_write_rx(struct sk_buff *rsp, struct netdev_queue_stats_rx *rx)
  487. {
  488. if (netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_PACKETS, rx->packets) ||
  489. netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_BYTES, rx->bytes) ||
  490. netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_ALLOC_FAIL, rx->alloc_fail) ||
  491. netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_HW_DROPS, rx->hw_drops) ||
  492. netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_HW_DROP_OVERRUNS, rx->hw_drop_overruns) ||
  493. netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_CSUM_COMPLETE, rx->csum_complete) ||
  494. netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_CSUM_UNNECESSARY, rx->csum_unnecessary) ||
  495. netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_CSUM_NONE, rx->csum_none) ||
  496. netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_CSUM_BAD, rx->csum_bad) ||
  497. netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_HW_GRO_PACKETS, rx->hw_gro_packets) ||
  498. netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_HW_GRO_BYTES, rx->hw_gro_bytes) ||
  499. netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_HW_GRO_WIRE_PACKETS, rx->hw_gro_wire_packets) ||
  500. netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_HW_GRO_WIRE_BYTES, rx->hw_gro_wire_bytes) ||
  501. netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_HW_DROP_RATELIMITS, rx->hw_drop_ratelimits))
  502. return -EMSGSIZE;
  503. return 0;
  504. }
  505. static int
  506. netdev_nl_stats_write_tx(struct sk_buff *rsp, struct netdev_queue_stats_tx *tx)
  507. {
  508. if (netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_PACKETS, tx->packets) ||
  509. netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_BYTES, tx->bytes) ||
  510. netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_HW_DROPS, tx->hw_drops) ||
  511. netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_HW_DROP_ERRORS, tx->hw_drop_errors) ||
  512. netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_CSUM_NONE, tx->csum_none) ||
  513. netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_NEEDS_CSUM, tx->needs_csum) ||
  514. netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_HW_GSO_PACKETS, tx->hw_gso_packets) ||
  515. netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_HW_GSO_BYTES, tx->hw_gso_bytes) ||
  516. netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_HW_GSO_WIRE_PACKETS, tx->hw_gso_wire_packets) ||
  517. netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_HW_GSO_WIRE_BYTES, tx->hw_gso_wire_bytes) ||
  518. netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_HW_DROP_RATELIMITS, tx->hw_drop_ratelimits) ||
  519. netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_STOP, tx->stop) ||
  520. netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_WAKE, tx->wake))
  521. return -EMSGSIZE;
  522. return 0;
  523. }
  524. static int
  525. netdev_nl_stats_queue(struct net_device *netdev, struct sk_buff *rsp,
  526. u32 q_type, int i, const struct genl_info *info)
  527. {
  528. const struct netdev_stat_ops *ops = netdev->stat_ops;
  529. struct netdev_queue_stats_rx rx;
  530. struct netdev_queue_stats_tx tx;
  531. void *hdr;
  532. hdr = genlmsg_iput(rsp, info);
  533. if (!hdr)
  534. return -EMSGSIZE;
  535. if (nla_put_u32(rsp, NETDEV_A_QSTATS_IFINDEX, netdev->ifindex) ||
  536. nla_put_u32(rsp, NETDEV_A_QSTATS_QUEUE_TYPE, q_type) ||
  537. nla_put_u32(rsp, NETDEV_A_QSTATS_QUEUE_ID, i))
  538. goto nla_put_failure;
  539. switch (q_type) {
  540. case NETDEV_QUEUE_TYPE_RX:
  541. memset(&rx, 0xff, sizeof(rx));
  542. ops->get_queue_stats_rx(netdev, i, &rx);
  543. if (!memchr_inv(&rx, 0xff, sizeof(rx)))
  544. goto nla_cancel;
  545. if (netdev_nl_stats_write_rx(rsp, &rx))
  546. goto nla_put_failure;
  547. break;
  548. case NETDEV_QUEUE_TYPE_TX:
  549. memset(&tx, 0xff, sizeof(tx));
  550. ops->get_queue_stats_tx(netdev, i, &tx);
  551. if (!memchr_inv(&tx, 0xff, sizeof(tx)))
  552. goto nla_cancel;
  553. if (netdev_nl_stats_write_tx(rsp, &tx))
  554. goto nla_put_failure;
  555. break;
  556. }
  557. genlmsg_end(rsp, hdr);
  558. return 0;
  559. nla_cancel:
  560. genlmsg_cancel(rsp, hdr);
  561. return 0;
  562. nla_put_failure:
  563. genlmsg_cancel(rsp, hdr);
  564. return -EMSGSIZE;
  565. }
  566. static int
  567. netdev_nl_stats_by_queue(struct net_device *netdev, struct sk_buff *rsp,
  568. const struct genl_info *info,
  569. struct netdev_nl_dump_ctx *ctx)
  570. {
  571. const struct netdev_stat_ops *ops = netdev->stat_ops;
  572. int i, err;
  573. if (!(netdev->flags & IFF_UP))
  574. return 0;
  575. i = ctx->rxq_idx;
  576. while (ops->get_queue_stats_rx && i < netdev->real_num_rx_queues) {
  577. err = netdev_nl_stats_queue(netdev, rsp, NETDEV_QUEUE_TYPE_RX,
  578. i, info);
  579. if (err)
  580. return err;
  581. ctx->rxq_idx = ++i;
  582. }
  583. i = ctx->txq_idx;
  584. while (ops->get_queue_stats_tx && i < netdev->real_num_tx_queues) {
  585. err = netdev_nl_stats_queue(netdev, rsp, NETDEV_QUEUE_TYPE_TX,
  586. i, info);
  587. if (err)
  588. return err;
  589. ctx->txq_idx = ++i;
  590. }
  591. ctx->rxq_idx = 0;
  592. ctx->txq_idx = 0;
  593. return 0;
  594. }
  595. /**
  596. * netdev_stat_queue_sum() - add up queue stats from range of queues
  597. * @netdev: net_device
  598. * @rx_start: index of the first Rx queue to query
  599. * @rx_end: index after the last Rx queue (first *not* to query)
  600. * @rx_sum: output Rx stats, should be already initialized
  601. * @tx_start: index of the first Tx queue to query
  602. * @tx_end: index after the last Tx queue (first *not* to query)
  603. * @tx_sum: output Tx stats, should be already initialized
  604. *
  605. * Add stats from [start, end) range of queue IDs to *x_sum structs.
  606. * The sum structs must be already initialized. Usually this
  607. * helper is invoked from the .get_base_stats callbacks of drivers
  608. * to account for stats of disabled queues. In that case the ranges
  609. * are usually [netdev->real_num_*x_queues, netdev->num_*x_queues).
  610. */
  611. void netdev_stat_queue_sum(struct net_device *netdev,
  612. int rx_start, int rx_end,
  613. struct netdev_queue_stats_rx *rx_sum,
  614. int tx_start, int tx_end,
  615. struct netdev_queue_stats_tx *tx_sum)
  616. {
  617. const struct netdev_stat_ops *ops;
  618. struct netdev_queue_stats_rx rx;
  619. struct netdev_queue_stats_tx tx;
  620. int i;
  621. ops = netdev->stat_ops;
  622. for (i = rx_start; i < rx_end; i++) {
  623. memset(&rx, 0xff, sizeof(rx));
  624. if (ops->get_queue_stats_rx)
  625. ops->get_queue_stats_rx(netdev, i, &rx);
  626. netdev_nl_stats_add(rx_sum, &rx, sizeof(rx));
  627. }
  628. for (i = tx_start; i < tx_end; i++) {
  629. memset(&tx, 0xff, sizeof(tx));
  630. if (ops->get_queue_stats_tx)
  631. ops->get_queue_stats_tx(netdev, i, &tx);
  632. netdev_nl_stats_add(tx_sum, &tx, sizeof(tx));
  633. }
  634. }
  635. EXPORT_SYMBOL(netdev_stat_queue_sum);
  636. static int
  637. netdev_nl_stats_by_netdev(struct net_device *netdev, struct sk_buff *rsp,
  638. const struct genl_info *info)
  639. {
  640. struct netdev_queue_stats_rx rx_sum;
  641. struct netdev_queue_stats_tx tx_sum;
  642. void *hdr;
  643. /* Netdev can't guarantee any complete counters */
  644. if (!netdev->stat_ops->get_base_stats)
  645. return 0;
  646. memset(&rx_sum, 0xff, sizeof(rx_sum));
  647. memset(&tx_sum, 0xff, sizeof(tx_sum));
  648. netdev->stat_ops->get_base_stats(netdev, &rx_sum, &tx_sum);
  649. /* The op was there, but nothing reported, don't bother */
  650. if (!memchr_inv(&rx_sum, 0xff, sizeof(rx_sum)) &&
  651. !memchr_inv(&tx_sum, 0xff, sizeof(tx_sum)))
  652. return 0;
  653. hdr = genlmsg_iput(rsp, info);
  654. if (!hdr)
  655. return -EMSGSIZE;
  656. if (nla_put_u32(rsp, NETDEV_A_QSTATS_IFINDEX, netdev->ifindex))
  657. goto nla_put_failure;
  658. netdev_stat_queue_sum(netdev, 0, netdev->real_num_rx_queues, &rx_sum,
  659. 0, netdev->real_num_tx_queues, &tx_sum);
  660. if (netdev_nl_stats_write_rx(rsp, &rx_sum) ||
  661. netdev_nl_stats_write_tx(rsp, &tx_sum))
  662. goto nla_put_failure;
  663. genlmsg_end(rsp, hdr);
  664. return 0;
  665. nla_put_failure:
  666. genlmsg_cancel(rsp, hdr);
  667. return -EMSGSIZE;
  668. }
  669. static int
  670. netdev_nl_qstats_get_dump_one(struct net_device *netdev, unsigned int scope,
  671. struct sk_buff *skb, const struct genl_info *info,
  672. struct netdev_nl_dump_ctx *ctx)
  673. {
  674. if (!netdev->stat_ops)
  675. return 0;
  676. switch (scope) {
  677. case 0:
  678. return netdev_nl_stats_by_netdev(netdev, skb, info);
  679. case NETDEV_QSTATS_SCOPE_QUEUE:
  680. return netdev_nl_stats_by_queue(netdev, skb, info, ctx);
  681. }
  682. return -EINVAL; /* Should not happen, per netlink policy */
  683. }
  684. int netdev_nl_qstats_get_dumpit(struct sk_buff *skb,
  685. struct netlink_callback *cb)
  686. {
  687. struct netdev_nl_dump_ctx *ctx = netdev_dump_ctx(cb);
  688. const struct genl_info *info = genl_info_dump(cb);
  689. struct net *net = sock_net(skb->sk);
  690. struct net_device *netdev;
  691. unsigned int ifindex;
  692. unsigned int scope;
  693. int err = 0;
  694. scope = 0;
  695. if (info->attrs[NETDEV_A_QSTATS_SCOPE])
  696. scope = nla_get_uint(info->attrs[NETDEV_A_QSTATS_SCOPE]);
  697. ifindex = 0;
  698. if (info->attrs[NETDEV_A_QSTATS_IFINDEX])
  699. ifindex = nla_get_u32(info->attrs[NETDEV_A_QSTATS_IFINDEX]);
  700. if (ifindex) {
  701. netdev = netdev_get_by_index_lock_ops_compat(net, ifindex);
  702. if (!netdev) {
  703. NL_SET_BAD_ATTR(info->extack,
  704. info->attrs[NETDEV_A_QSTATS_IFINDEX]);
  705. return -ENODEV;
  706. }
  707. if (netdev->stat_ops) {
  708. err = netdev_nl_qstats_get_dump_one(netdev, scope, skb,
  709. info, ctx);
  710. } else {
  711. NL_SET_BAD_ATTR(info->extack,
  712. info->attrs[NETDEV_A_QSTATS_IFINDEX]);
  713. err = -EOPNOTSUPP;
  714. }
  715. netdev_unlock_ops_compat(netdev);
  716. return err;
  717. }
  718. for_each_netdev_lock_ops_compat_scoped(net, netdev, ctx->ifindex) {
  719. err = netdev_nl_qstats_get_dump_one(netdev, scope, skb,
  720. info, ctx);
  721. if (err < 0)
  722. break;
  723. }
  724. return err;
  725. }
  726. static int netdev_nl_read_rxq_bitmap(struct genl_info *info,
  727. u32 rxq_bitmap_len,
  728. unsigned long *rxq_bitmap)
  729. {
  730. const int maxtype = ARRAY_SIZE(netdev_queue_id_nl_policy) - 1;
  731. struct nlattr *tb[ARRAY_SIZE(netdev_queue_id_nl_policy)];
  732. struct nlattr *attr;
  733. int rem, err = 0;
  734. u32 rxq_idx;
  735. nla_for_each_attr_type(attr, NETDEV_A_DMABUF_QUEUES,
  736. genlmsg_data(info->genlhdr),
  737. genlmsg_len(info->genlhdr), rem) {
  738. err = nla_parse_nested(tb, maxtype, attr,
  739. netdev_queue_id_nl_policy, info->extack);
  740. if (err < 0)
  741. return err;
  742. if (NL_REQ_ATTR_CHECK(info->extack, attr, tb, NETDEV_A_QUEUE_ID) ||
  743. NL_REQ_ATTR_CHECK(info->extack, attr, tb, NETDEV_A_QUEUE_TYPE))
  744. return -EINVAL;
  745. if (nla_get_u32(tb[NETDEV_A_QUEUE_TYPE]) != NETDEV_QUEUE_TYPE_RX) {
  746. NL_SET_BAD_ATTR(info->extack, tb[NETDEV_A_QUEUE_TYPE]);
  747. return -EINVAL;
  748. }
  749. rxq_idx = nla_get_u32(tb[NETDEV_A_QUEUE_ID]);
  750. if (rxq_idx >= rxq_bitmap_len) {
  751. NL_SET_BAD_ATTR(info->extack, tb[NETDEV_A_QUEUE_ID]);
  752. return -EINVAL;
  753. }
  754. bitmap_set(rxq_bitmap, rxq_idx, 1);
  755. }
  756. return 0;
  757. }
  758. static struct device *
  759. netdev_nl_get_dma_dev(struct net_device *netdev, unsigned long *rxq_bitmap,
  760. struct netlink_ext_ack *extack)
  761. {
  762. struct device *dma_dev = NULL;
  763. u32 rxq_idx, prev_rxq_idx;
  764. for_each_set_bit(rxq_idx, rxq_bitmap, netdev->real_num_rx_queues) {
  765. struct device *rxq_dma_dev;
  766. rxq_dma_dev = netdev_queue_get_dma_dev(netdev, rxq_idx);
  767. if (dma_dev && rxq_dma_dev != dma_dev) {
  768. NL_SET_ERR_MSG_FMT(extack, "DMA device mismatch between queue %u and %u (multi-PF device?)",
  769. rxq_idx, prev_rxq_idx);
  770. return ERR_PTR(-EOPNOTSUPP);
  771. }
  772. dma_dev = rxq_dma_dev;
  773. prev_rxq_idx = rxq_idx;
  774. }
  775. return dma_dev;
  776. }
  777. int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
  778. {
  779. struct net_devmem_dmabuf_binding *binding;
  780. u32 ifindex, dmabuf_fd, rxq_idx;
  781. struct netdev_nl_sock *priv;
  782. struct net_device *netdev;
  783. unsigned long *rxq_bitmap;
  784. struct device *dma_dev;
  785. struct sk_buff *rsp;
  786. int err = 0;
  787. void *hdr;
  788. if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_DEV_IFINDEX) ||
  789. GENL_REQ_ATTR_CHECK(info, NETDEV_A_DMABUF_FD) ||
  790. GENL_REQ_ATTR_CHECK(info, NETDEV_A_DMABUF_QUEUES))
  791. return -EINVAL;
  792. ifindex = nla_get_u32(info->attrs[NETDEV_A_DEV_IFINDEX]);
  793. dmabuf_fd = nla_get_u32(info->attrs[NETDEV_A_DMABUF_FD]);
  794. priv = genl_sk_priv_get(&netdev_nl_family, NETLINK_CB(skb).sk);
  795. if (IS_ERR(priv))
  796. return PTR_ERR(priv);
  797. rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
  798. if (!rsp)
  799. return -ENOMEM;
  800. hdr = genlmsg_iput(rsp, info);
  801. if (!hdr) {
  802. err = -EMSGSIZE;
  803. goto err_genlmsg_free;
  804. }
  805. mutex_lock(&priv->lock);
  806. err = 0;
  807. netdev = netdev_get_by_index_lock(genl_info_net(info), ifindex);
  808. if (!netdev) {
  809. err = -ENODEV;
  810. goto err_unlock_sock;
  811. }
  812. if (!netif_device_present(netdev))
  813. err = -ENODEV;
  814. else if (!netdev_need_ops_lock(netdev))
  815. err = -EOPNOTSUPP;
  816. if (err) {
  817. NL_SET_BAD_ATTR(info->extack,
  818. info->attrs[NETDEV_A_DEV_IFINDEX]);
  819. goto err_unlock;
  820. }
  821. rxq_bitmap = bitmap_zalloc(netdev->real_num_rx_queues, GFP_KERNEL);
  822. if (!rxq_bitmap) {
  823. err = -ENOMEM;
  824. goto err_unlock;
  825. }
  826. err = netdev_nl_read_rxq_bitmap(info, netdev->real_num_rx_queues,
  827. rxq_bitmap);
  828. if (err)
  829. goto err_rxq_bitmap;
  830. dma_dev = netdev_nl_get_dma_dev(netdev, rxq_bitmap, info->extack);
  831. if (IS_ERR(dma_dev)) {
  832. err = PTR_ERR(dma_dev);
  833. goto err_rxq_bitmap;
  834. }
  835. binding = net_devmem_bind_dmabuf(netdev, dma_dev, DMA_FROM_DEVICE,
  836. dmabuf_fd, priv, info->extack);
  837. if (IS_ERR(binding)) {
  838. err = PTR_ERR(binding);
  839. goto err_rxq_bitmap;
  840. }
  841. for_each_set_bit(rxq_idx, rxq_bitmap, netdev->real_num_rx_queues) {
  842. err = net_devmem_bind_dmabuf_to_queue(netdev, rxq_idx, binding,
  843. info->extack);
  844. if (err)
  845. goto err_unbind;
  846. }
  847. nla_put_u32(rsp, NETDEV_A_DMABUF_ID, binding->id);
  848. genlmsg_end(rsp, hdr);
  849. err = genlmsg_reply(rsp, info);
  850. if (err)
  851. goto err_unbind;
  852. bitmap_free(rxq_bitmap);
  853. netdev_unlock(netdev);
  854. mutex_unlock(&priv->lock);
  855. return 0;
  856. err_unbind:
  857. net_devmem_unbind_dmabuf(binding);
  858. err_rxq_bitmap:
  859. bitmap_free(rxq_bitmap);
  860. err_unlock:
  861. netdev_unlock(netdev);
  862. err_unlock_sock:
  863. mutex_unlock(&priv->lock);
  864. err_genlmsg_free:
  865. nlmsg_free(rsp);
  866. return err;
  867. }
  868. int netdev_nl_bind_tx_doit(struct sk_buff *skb, struct genl_info *info)
  869. {
  870. struct net_devmem_dmabuf_binding *binding;
  871. struct netdev_nl_sock *priv;
  872. struct net_device *netdev;
  873. struct device *dma_dev;
  874. u32 ifindex, dmabuf_fd;
  875. struct sk_buff *rsp;
  876. int err = 0;
  877. void *hdr;
  878. if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_DEV_IFINDEX) ||
  879. GENL_REQ_ATTR_CHECK(info, NETDEV_A_DMABUF_FD))
  880. return -EINVAL;
  881. ifindex = nla_get_u32(info->attrs[NETDEV_A_DEV_IFINDEX]);
  882. dmabuf_fd = nla_get_u32(info->attrs[NETDEV_A_DMABUF_FD]);
  883. priv = genl_sk_priv_get(&netdev_nl_family, NETLINK_CB(skb).sk);
  884. if (IS_ERR(priv))
  885. return PTR_ERR(priv);
  886. rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
  887. if (!rsp)
  888. return -ENOMEM;
  889. hdr = genlmsg_iput(rsp, info);
  890. if (!hdr) {
  891. err = -EMSGSIZE;
  892. goto err_genlmsg_free;
  893. }
  894. mutex_lock(&priv->lock);
  895. netdev = netdev_get_by_index_lock(genl_info_net(info), ifindex);
  896. if (!netdev) {
  897. err = -ENODEV;
  898. goto err_unlock_sock;
  899. }
  900. if (!netif_device_present(netdev)) {
  901. err = -ENODEV;
  902. goto err_unlock_netdev;
  903. }
  904. if (!netdev->netmem_tx) {
  905. err = -EOPNOTSUPP;
  906. NL_SET_ERR_MSG(info->extack,
  907. "Driver does not support netmem TX");
  908. goto err_unlock_netdev;
  909. }
  910. dma_dev = netdev_queue_get_dma_dev(netdev, 0);
  911. binding = net_devmem_bind_dmabuf(netdev, dma_dev, DMA_TO_DEVICE,
  912. dmabuf_fd, priv, info->extack);
  913. if (IS_ERR(binding)) {
  914. err = PTR_ERR(binding);
  915. goto err_unlock_netdev;
  916. }
  917. nla_put_u32(rsp, NETDEV_A_DMABUF_ID, binding->id);
  918. genlmsg_end(rsp, hdr);
  919. netdev_unlock(netdev);
  920. mutex_unlock(&priv->lock);
  921. return genlmsg_reply(rsp, info);
  922. err_unlock_netdev:
  923. netdev_unlock(netdev);
  924. err_unlock_sock:
  925. mutex_unlock(&priv->lock);
  926. err_genlmsg_free:
  927. nlmsg_free(rsp);
  928. return err;
  929. }
  930. void netdev_nl_sock_priv_init(struct netdev_nl_sock *priv)
  931. {
  932. INIT_LIST_HEAD(&priv->bindings);
  933. mutex_init(&priv->lock);
  934. }
  935. void netdev_nl_sock_priv_destroy(struct netdev_nl_sock *priv)
  936. {
  937. struct net_devmem_dmabuf_binding *binding;
  938. struct net_devmem_dmabuf_binding *temp;
  939. netdevice_tracker dev_tracker;
  940. struct net_device *dev;
  941. mutex_lock(&priv->lock);
  942. list_for_each_entry_safe(binding, temp, &priv->bindings, list) {
  943. mutex_lock(&binding->lock);
  944. dev = binding->dev;
  945. if (!dev) {
  946. mutex_unlock(&binding->lock);
  947. net_devmem_unbind_dmabuf(binding);
  948. continue;
  949. }
  950. netdev_hold(dev, &dev_tracker, GFP_KERNEL);
  951. mutex_unlock(&binding->lock);
  952. netdev_lock(dev);
  953. net_devmem_unbind_dmabuf(binding);
  954. netdev_unlock(dev);
  955. netdev_put(dev, &dev_tracker);
  956. }
  957. mutex_unlock(&priv->lock);
  958. }
  959. static int netdev_genl_netdevice_event(struct notifier_block *nb,
  960. unsigned long event, void *ptr)
  961. {
  962. struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
  963. switch (event) {
  964. case NETDEV_REGISTER:
  965. netdev_lock_ops_to_full(netdev);
  966. netdev_genl_dev_notify(netdev, NETDEV_CMD_DEV_ADD_NTF);
  967. netdev_unlock_full_to_ops(netdev);
  968. break;
  969. case NETDEV_UNREGISTER:
  970. netdev_lock(netdev);
  971. netdev_genl_dev_notify(netdev, NETDEV_CMD_DEV_DEL_NTF);
  972. netdev_unlock(netdev);
  973. break;
  974. case NETDEV_XDP_FEAT_CHANGE:
  975. netdev_genl_dev_notify(netdev, NETDEV_CMD_DEV_CHANGE_NTF);
  976. break;
  977. }
  978. return NOTIFY_OK;
  979. }
  980. static struct notifier_block netdev_genl_nb = {
  981. .notifier_call = netdev_genl_netdevice_event,
  982. };
  983. static int __init netdev_genl_init(void)
  984. {
  985. int err;
  986. err = register_netdevice_notifier(&netdev_genl_nb);
  987. if (err)
  988. return err;
  989. err = genl_register_family(&netdev_nl_family);
  990. if (err)
  991. goto err_unreg_ntf;
  992. return 0;
  993. err_unreg_ntf:
  994. unregister_netdevice_notifier(&netdev_genl_nb);
  995. return err;
  996. }
  997. subsys_initcall(netdev_genl_init);