xsk_buff_pool.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/netdevice.h>
  3. #include <net/netdev_lock.h>
  4. #include <net/xsk_buff_pool.h>
  5. #include <net/xdp_sock.h>
  6. #include <net/xdp_sock_drv.h>
  7. #include "xsk_queue.h"
  8. #include "xdp_umem.h"
  9. #include "xsk.h"
  10. #define ETH_PAD_LEN (ETH_HLEN + 2 * VLAN_HLEN + ETH_FCS_LEN)
  11. void xp_add_xsk(struct xsk_buff_pool *pool, struct xdp_sock *xs)
  12. {
  13. if (!xs->tx)
  14. return;
  15. spin_lock(&pool->xsk_tx_list_lock);
  16. list_add_rcu(&xs->tx_list, &pool->xsk_tx_list);
  17. spin_unlock(&pool->xsk_tx_list_lock);
  18. }
  19. void xp_del_xsk(struct xsk_buff_pool *pool, struct xdp_sock *xs)
  20. {
  21. if (!xs->tx)
  22. return;
  23. spin_lock(&pool->xsk_tx_list_lock);
  24. list_del_rcu(&xs->tx_list);
  25. spin_unlock(&pool->xsk_tx_list_lock);
  26. }
  27. void xp_destroy(struct xsk_buff_pool *pool)
  28. {
  29. if (!pool)
  30. return;
  31. kvfree(pool->tx_descs);
  32. kvfree(pool->heads);
  33. kvfree(pool);
  34. }
  35. int xp_alloc_tx_descs(struct xsk_buff_pool *pool, struct xdp_sock *xs)
  36. {
  37. pool->tx_descs = kvzalloc_objs(*pool->tx_descs, xs->tx->nentries);
  38. if (!pool->tx_descs)
  39. return -ENOMEM;
  40. return 0;
  41. }
  42. struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs,
  43. struct xdp_umem *umem)
  44. {
  45. bool unaligned = umem->flags & XDP_UMEM_UNALIGNED_CHUNK_FLAG;
  46. struct xsk_buff_pool *pool;
  47. struct xdp_buff_xsk *xskb;
  48. u32 i, entries;
  49. entries = unaligned ? umem->chunks : 0;
  50. pool = kvzalloc_flex(*pool, free_heads, entries);
  51. if (!pool)
  52. goto out;
  53. pool->heads = kvzalloc_objs(*pool->heads, umem->chunks);
  54. if (!pool->heads)
  55. goto out;
  56. if (xs->tx)
  57. if (xp_alloc_tx_descs(pool, xs))
  58. goto out;
  59. pool->chunk_mask = ~((u64)umem->chunk_size - 1);
  60. pool->addrs_cnt = umem->size;
  61. pool->heads_cnt = umem->chunks;
  62. pool->free_heads_cnt = umem->chunks;
  63. pool->headroom = umem->headroom;
  64. pool->chunk_size = umem->chunk_size;
  65. pool->chunk_shift = ffs(umem->chunk_size) - 1;
  66. pool->unaligned = unaligned;
  67. pool->frame_len = umem->chunk_size - umem->headroom -
  68. XDP_PACKET_HEADROOM;
  69. pool->umem = umem;
  70. pool->addrs = umem->addrs;
  71. pool->tx_metadata_len = umem->tx_metadata_len;
  72. pool->tx_sw_csum = umem->flags & XDP_UMEM_TX_SW_CSUM;
  73. spin_lock_init(&pool->rx_lock);
  74. INIT_LIST_HEAD(&pool->free_list);
  75. INIT_LIST_HEAD(&pool->xskb_list);
  76. INIT_LIST_HEAD(&pool->xsk_tx_list);
  77. spin_lock_init(&pool->xsk_tx_list_lock);
  78. spin_lock_init(&pool->cq_prod_lock);
  79. spin_lock_init(&xs->cq_tmp->cq_cached_prod_lock);
  80. refcount_set(&pool->users, 1);
  81. pool->fq = xs->fq_tmp;
  82. pool->cq = xs->cq_tmp;
  83. for (i = 0; i < pool->free_heads_cnt; i++) {
  84. xskb = &pool->heads[i];
  85. xskb->pool = pool;
  86. xskb->xdp.frame_sz = umem->chunk_size - umem->headroom;
  87. INIT_LIST_HEAD(&xskb->list_node);
  88. if (pool->unaligned)
  89. pool->free_heads[i] = xskb;
  90. else
  91. xp_init_xskb_addr(xskb, pool, (u64)i * pool->chunk_size);
  92. }
  93. return pool;
  94. out:
  95. xp_destroy(pool);
  96. return NULL;
  97. }
  98. void xp_set_rxq_info(struct xsk_buff_pool *pool, struct xdp_rxq_info *rxq)
  99. {
  100. u32 i;
  101. for (i = 0; i < pool->heads_cnt; i++)
  102. pool->heads[i].xdp.rxq = rxq;
  103. }
  104. EXPORT_SYMBOL(xp_set_rxq_info);
  105. void xp_fill_cb(struct xsk_buff_pool *pool, struct xsk_cb_desc *desc)
  106. {
  107. u32 i;
  108. for (i = 0; i < pool->heads_cnt; i++) {
  109. struct xdp_buff_xsk *xskb = &pool->heads[i];
  110. memcpy(xskb->cb + desc->off, desc->src, desc->bytes);
  111. }
  112. }
  113. EXPORT_SYMBOL(xp_fill_cb);
  114. static void xp_disable_drv_zc(struct xsk_buff_pool *pool)
  115. {
  116. struct netdev_bpf bpf;
  117. int err;
  118. ASSERT_RTNL();
  119. if (pool->umem->zc) {
  120. bpf.command = XDP_SETUP_XSK_POOL;
  121. bpf.xsk.pool = NULL;
  122. bpf.xsk.queue_id = pool->queue_id;
  123. err = pool->netdev->netdev_ops->ndo_bpf(pool->netdev, &bpf);
  124. if (err)
  125. WARN(1, "Failed to disable zero-copy!\n");
  126. }
  127. }
  128. int xp_assign_dev(struct xsk_buff_pool *pool,
  129. struct net_device *netdev, u16 queue_id, u16 flags)
  130. {
  131. u32 needed = netdev->mtu + ETH_PAD_LEN;
  132. u32 segs = netdev->xdp_zc_max_segs;
  133. bool mbuf = flags & XDP_USE_SG;
  134. bool force_zc, force_copy;
  135. struct netdev_bpf bpf;
  136. u32 frame_size;
  137. int err = 0;
  138. ASSERT_RTNL();
  139. force_zc = flags & XDP_ZEROCOPY;
  140. force_copy = flags & XDP_COPY;
  141. if (force_zc && force_copy)
  142. return -EINVAL;
  143. if (xsk_get_pool_from_qid(netdev, queue_id))
  144. return -EBUSY;
  145. pool->netdev = netdev;
  146. pool->queue_id = queue_id;
  147. err = xsk_reg_pool_at_qid(netdev, pool, queue_id);
  148. if (err)
  149. return err;
  150. if (mbuf)
  151. pool->umem->flags |= XDP_UMEM_SG_FLAG;
  152. if (flags & XDP_USE_NEED_WAKEUP)
  153. pool->uses_need_wakeup = true;
  154. /* Tx needs to be explicitly woken up the first time. Also
  155. * for supporting drivers that do not implement this
  156. * feature. They will always have to call sendto() or poll().
  157. */
  158. pool->cached_need_wakeup = XDP_WAKEUP_TX;
  159. dev_hold(netdev);
  160. if (force_copy)
  161. /* For copy-mode, we are done. */
  162. return 0;
  163. if ((netdev->xdp_features & NETDEV_XDP_ACT_XSK) != NETDEV_XDP_ACT_XSK) {
  164. err = -EOPNOTSUPP;
  165. goto err_unreg_pool;
  166. }
  167. if (mbuf) {
  168. if (segs == 1) {
  169. err = -EOPNOTSUPP;
  170. goto err_unreg_pool;
  171. }
  172. } else {
  173. segs = 1;
  174. }
  175. /* open-code xsk_pool_get_rx_frame_size() as pool->dev is not
  176. * set yet at this point; we are before getting down to driver
  177. */
  178. frame_size = __xsk_pool_get_rx_frame_size(pool) -
  179. xsk_pool_get_tailroom(mbuf);
  180. frame_size = ALIGN_DOWN(frame_size, 128);
  181. if (needed > frame_size * segs) {
  182. err = -EINVAL;
  183. goto err_unreg_pool;
  184. }
  185. if (dev_get_min_mp_channel_count(netdev)) {
  186. err = -EBUSY;
  187. goto err_unreg_pool;
  188. }
  189. bpf.command = XDP_SETUP_XSK_POOL;
  190. bpf.xsk.pool = pool;
  191. bpf.xsk.queue_id = queue_id;
  192. netdev_ops_assert_locked(netdev);
  193. err = netdev->netdev_ops->ndo_bpf(netdev, &bpf);
  194. if (err)
  195. goto err_unreg_pool;
  196. if (!pool->dma_pages) {
  197. WARN(1, "Driver did not DMA map zero-copy buffers");
  198. err = -EINVAL;
  199. goto err_unreg_xsk;
  200. }
  201. pool->umem->zc = true;
  202. pool->xdp_zc_max_segs = netdev->xdp_zc_max_segs;
  203. return 0;
  204. err_unreg_xsk:
  205. xp_disable_drv_zc(pool);
  206. err_unreg_pool:
  207. if (!force_zc)
  208. err = 0; /* fallback to copy mode */
  209. if (err) {
  210. xsk_clear_pool_at_qid(netdev, queue_id);
  211. dev_put(netdev);
  212. }
  213. return err;
  214. }
  215. int xp_assign_dev_shared(struct xsk_buff_pool *pool, struct xdp_sock *umem_xs,
  216. struct net_device *dev, u16 queue_id)
  217. {
  218. u16 flags;
  219. struct xdp_umem *umem = umem_xs->umem;
  220. flags = umem->zc ? XDP_ZEROCOPY : XDP_COPY;
  221. if (umem->flags & XDP_UMEM_SG_FLAG)
  222. flags |= XDP_USE_SG;
  223. if (umem_xs->pool->uses_need_wakeup)
  224. flags |= XDP_USE_NEED_WAKEUP;
  225. return xp_assign_dev(pool, dev, queue_id, flags);
  226. }
  227. void xp_clear_dev(struct xsk_buff_pool *pool)
  228. {
  229. struct net_device *netdev = pool->netdev;
  230. if (!pool->netdev)
  231. return;
  232. netdev_lock_ops(netdev);
  233. xp_disable_drv_zc(pool);
  234. xsk_clear_pool_at_qid(pool->netdev, pool->queue_id);
  235. pool->netdev = NULL;
  236. netdev_unlock_ops(netdev);
  237. dev_put(netdev);
  238. }
  239. static void xp_release_deferred(struct work_struct *work)
  240. {
  241. struct xsk_buff_pool *pool = container_of(work, struct xsk_buff_pool,
  242. work);
  243. rtnl_lock();
  244. xp_clear_dev(pool);
  245. rtnl_unlock();
  246. if (pool->fq) {
  247. xskq_destroy(pool->fq);
  248. pool->fq = NULL;
  249. }
  250. if (pool->cq) {
  251. xskq_destroy(pool->cq);
  252. pool->cq = NULL;
  253. }
  254. xdp_put_umem(pool->umem, false);
  255. xp_destroy(pool);
  256. }
  257. void xp_get_pool(struct xsk_buff_pool *pool)
  258. {
  259. refcount_inc(&pool->users);
  260. }
  261. bool xp_put_pool(struct xsk_buff_pool *pool)
  262. {
  263. if (!pool)
  264. return false;
  265. if (refcount_dec_and_test(&pool->users)) {
  266. INIT_WORK(&pool->work, xp_release_deferred);
  267. schedule_work(&pool->work);
  268. return true;
  269. }
  270. return false;
  271. }
  272. static struct xsk_dma_map *xp_find_dma_map(struct xsk_buff_pool *pool)
  273. {
  274. struct xsk_dma_map *dma_map;
  275. list_for_each_entry(dma_map, &pool->umem->xsk_dma_list, list) {
  276. if (dma_map->netdev == pool->netdev)
  277. return dma_map;
  278. }
  279. return NULL;
  280. }
  281. static struct xsk_dma_map *xp_create_dma_map(struct device *dev, struct net_device *netdev,
  282. u32 nr_pages, struct xdp_umem *umem)
  283. {
  284. struct xsk_dma_map *dma_map;
  285. dma_map = kzalloc_obj(*dma_map);
  286. if (!dma_map)
  287. return NULL;
  288. dma_map->dma_pages = kvzalloc_objs(*dma_map->dma_pages, nr_pages);
  289. if (!dma_map->dma_pages) {
  290. kfree(dma_map);
  291. return NULL;
  292. }
  293. dma_map->netdev = netdev;
  294. dma_map->dev = dev;
  295. dma_map->dma_pages_cnt = nr_pages;
  296. refcount_set(&dma_map->users, 1);
  297. list_add(&dma_map->list, &umem->xsk_dma_list);
  298. return dma_map;
  299. }
  300. static void xp_destroy_dma_map(struct xsk_dma_map *dma_map)
  301. {
  302. list_del(&dma_map->list);
  303. kvfree(dma_map->dma_pages);
  304. kfree(dma_map);
  305. }
  306. static void __xp_dma_unmap(struct xsk_dma_map *dma_map, unsigned long attrs)
  307. {
  308. dma_addr_t *dma;
  309. u32 i;
  310. for (i = 0; i < dma_map->dma_pages_cnt; i++) {
  311. dma = &dma_map->dma_pages[i];
  312. if (*dma) {
  313. *dma &= ~XSK_NEXT_PG_CONTIG_MASK;
  314. dma_unmap_page_attrs(dma_map->dev, *dma, PAGE_SIZE,
  315. DMA_BIDIRECTIONAL, attrs);
  316. *dma = 0;
  317. }
  318. }
  319. xp_destroy_dma_map(dma_map);
  320. }
  321. void xp_dma_unmap(struct xsk_buff_pool *pool, unsigned long attrs)
  322. {
  323. struct xsk_dma_map *dma_map;
  324. if (!pool->dma_pages)
  325. return;
  326. dma_map = xp_find_dma_map(pool);
  327. if (!dma_map) {
  328. WARN(1, "Could not find dma_map for device");
  329. return;
  330. }
  331. if (refcount_dec_and_test(&dma_map->users))
  332. __xp_dma_unmap(dma_map, attrs);
  333. kvfree(pool->dma_pages);
  334. pool->dma_pages = NULL;
  335. pool->dma_pages_cnt = 0;
  336. pool->dev = NULL;
  337. }
  338. EXPORT_SYMBOL(xp_dma_unmap);
  339. static void xp_check_dma_contiguity(struct xsk_dma_map *dma_map)
  340. {
  341. u32 i;
  342. for (i = 0; i < dma_map->dma_pages_cnt - 1; i++) {
  343. if (dma_map->dma_pages[i] + PAGE_SIZE == dma_map->dma_pages[i + 1])
  344. dma_map->dma_pages[i] |= XSK_NEXT_PG_CONTIG_MASK;
  345. else
  346. dma_map->dma_pages[i] &= ~XSK_NEXT_PG_CONTIG_MASK;
  347. }
  348. }
  349. static int xp_init_dma_info(struct xsk_buff_pool *pool, struct xsk_dma_map *dma_map)
  350. {
  351. if (!pool->unaligned) {
  352. u32 i;
  353. for (i = 0; i < pool->heads_cnt; i++) {
  354. struct xdp_buff_xsk *xskb = &pool->heads[i];
  355. u64 orig_addr;
  356. orig_addr = xskb->xdp.data_hard_start - pool->addrs - pool->headroom;
  357. xp_init_xskb_dma(xskb, pool, dma_map->dma_pages, orig_addr);
  358. }
  359. }
  360. pool->dma_pages = kvzalloc_objs(*pool->dma_pages,
  361. dma_map->dma_pages_cnt);
  362. if (!pool->dma_pages)
  363. return -ENOMEM;
  364. pool->dev = dma_map->dev;
  365. pool->dma_pages_cnt = dma_map->dma_pages_cnt;
  366. memcpy(pool->dma_pages, dma_map->dma_pages,
  367. pool->dma_pages_cnt * sizeof(*pool->dma_pages));
  368. return 0;
  369. }
  370. int xp_dma_map(struct xsk_buff_pool *pool, struct device *dev,
  371. unsigned long attrs, struct page **pages, u32 nr_pages)
  372. {
  373. struct xsk_dma_map *dma_map;
  374. dma_addr_t dma;
  375. int err;
  376. u32 i;
  377. dma_map = xp_find_dma_map(pool);
  378. if (dma_map) {
  379. err = xp_init_dma_info(pool, dma_map);
  380. if (err)
  381. return err;
  382. refcount_inc(&dma_map->users);
  383. return 0;
  384. }
  385. dma_map = xp_create_dma_map(dev, pool->netdev, nr_pages, pool->umem);
  386. if (!dma_map)
  387. return -ENOMEM;
  388. for (i = 0; i < dma_map->dma_pages_cnt; i++) {
  389. dma = dma_map_page_attrs(dev, pages[i], 0, PAGE_SIZE,
  390. DMA_BIDIRECTIONAL, attrs);
  391. if (dma_mapping_error(dev, dma)) {
  392. __xp_dma_unmap(dma_map, attrs);
  393. return -ENOMEM;
  394. }
  395. dma_map->dma_pages[i] = dma;
  396. }
  397. if (pool->unaligned)
  398. xp_check_dma_contiguity(dma_map);
  399. err = xp_init_dma_info(pool, dma_map);
  400. if (err) {
  401. __xp_dma_unmap(dma_map, attrs);
  402. return err;
  403. }
  404. return 0;
  405. }
  406. EXPORT_SYMBOL(xp_dma_map);
  407. static bool xp_addr_crosses_non_contig_pg(struct xsk_buff_pool *pool,
  408. u64 addr)
  409. {
  410. return xp_desc_crosses_non_contig_pg(pool, addr, pool->chunk_size);
  411. }
  412. static bool xp_check_unaligned(struct xsk_buff_pool *pool, u64 *addr)
  413. {
  414. *addr = xp_unaligned_extract_addr(*addr);
  415. if (*addr >= pool->addrs_cnt ||
  416. *addr + pool->chunk_size > pool->addrs_cnt ||
  417. xp_addr_crosses_non_contig_pg(pool, *addr))
  418. return false;
  419. return true;
  420. }
  421. static bool xp_check_aligned(struct xsk_buff_pool *pool, u64 *addr)
  422. {
  423. *addr = xp_aligned_extract_addr(pool, *addr);
  424. return *addr < pool->addrs_cnt;
  425. }
  426. static struct xdp_buff_xsk *xp_get_xskb(struct xsk_buff_pool *pool, u64 addr)
  427. {
  428. struct xdp_buff_xsk *xskb;
  429. if (pool->unaligned) {
  430. xskb = pool->free_heads[--pool->free_heads_cnt];
  431. xp_init_xskb_addr(xskb, pool, addr);
  432. if (pool->dma_pages)
  433. xp_init_xskb_dma(xskb, pool, pool->dma_pages, addr);
  434. } else {
  435. xskb = &pool->heads[xp_aligned_extract_idx(pool, addr)];
  436. }
  437. return xskb;
  438. }
  439. static struct xdp_buff_xsk *__xp_alloc(struct xsk_buff_pool *pool)
  440. {
  441. struct xdp_buff_xsk *xskb;
  442. u64 addr;
  443. bool ok;
  444. if (pool->free_heads_cnt == 0)
  445. return NULL;
  446. for (;;) {
  447. if (!xskq_cons_peek_addr_unchecked(pool->fq, &addr)) {
  448. pool->fq->queue_empty_descs++;
  449. return NULL;
  450. }
  451. ok = pool->unaligned ? xp_check_unaligned(pool, &addr) :
  452. xp_check_aligned(pool, &addr);
  453. if (!ok) {
  454. pool->fq->invalid_descs++;
  455. xskq_cons_release(pool->fq);
  456. continue;
  457. }
  458. break;
  459. }
  460. xskb = xp_get_xskb(pool, addr);
  461. xskq_cons_release(pool->fq);
  462. return xskb;
  463. }
  464. struct xdp_buff *xp_alloc(struct xsk_buff_pool *pool)
  465. {
  466. struct xdp_buff_xsk *xskb;
  467. if (!pool->free_list_cnt) {
  468. xskb = __xp_alloc(pool);
  469. if (!xskb)
  470. return NULL;
  471. } else {
  472. pool->free_list_cnt--;
  473. xskb = list_first_entry(&pool->free_list, struct xdp_buff_xsk,
  474. list_node);
  475. list_del_init(&xskb->list_node);
  476. }
  477. xskb->xdp.data = xskb->xdp.data_hard_start + XDP_PACKET_HEADROOM;
  478. xskb->xdp.data_meta = xskb->xdp.data;
  479. xskb->xdp.flags = 0;
  480. if (pool->dev)
  481. xp_dma_sync_for_device(pool, xskb->dma, pool->frame_len);
  482. return &xskb->xdp;
  483. }
  484. EXPORT_SYMBOL(xp_alloc);
  485. static u32 xp_alloc_new_from_fq(struct xsk_buff_pool *pool, struct xdp_buff **xdp, u32 max)
  486. {
  487. u32 i, cached_cons, nb_entries;
  488. if (max > pool->free_heads_cnt)
  489. max = pool->free_heads_cnt;
  490. max = xskq_cons_nb_entries(pool->fq, max);
  491. cached_cons = pool->fq->cached_cons;
  492. nb_entries = max;
  493. i = max;
  494. while (i--) {
  495. struct xdp_buff_xsk *xskb;
  496. u64 addr;
  497. bool ok;
  498. __xskq_cons_read_addr_unchecked(pool->fq, cached_cons++, &addr);
  499. ok = pool->unaligned ? xp_check_unaligned(pool, &addr) :
  500. xp_check_aligned(pool, &addr);
  501. if (unlikely(!ok)) {
  502. pool->fq->invalid_descs++;
  503. nb_entries--;
  504. continue;
  505. }
  506. xskb = xp_get_xskb(pool, addr);
  507. *xdp = &xskb->xdp;
  508. xdp++;
  509. }
  510. xskq_cons_release_n(pool->fq, max);
  511. return nb_entries;
  512. }
  513. static u32 xp_alloc_reused(struct xsk_buff_pool *pool, struct xdp_buff **xdp, u32 nb_entries)
  514. {
  515. struct xdp_buff_xsk *xskb;
  516. u32 i;
  517. nb_entries = min_t(u32, nb_entries, pool->free_list_cnt);
  518. i = nb_entries;
  519. while (i--) {
  520. xskb = list_first_entry(&pool->free_list, struct xdp_buff_xsk, list_node);
  521. list_del_init(&xskb->list_node);
  522. *xdp = &xskb->xdp;
  523. xdp++;
  524. }
  525. pool->free_list_cnt -= nb_entries;
  526. return nb_entries;
  527. }
  528. static u32 xp_alloc_slow(struct xsk_buff_pool *pool, struct xdp_buff **xdp,
  529. u32 max)
  530. {
  531. int i;
  532. for (i = 0; i < max; i++) {
  533. struct xdp_buff *buff;
  534. buff = xp_alloc(pool);
  535. if (unlikely(!buff))
  536. return i;
  537. *xdp = buff;
  538. xdp++;
  539. }
  540. return max;
  541. }
  542. u32 xp_alloc_batch(struct xsk_buff_pool *pool, struct xdp_buff **xdp, u32 max)
  543. {
  544. u32 nb_entries1 = 0, nb_entries2;
  545. if (unlikely(pool->dev && dma_dev_need_sync(pool->dev)))
  546. return xp_alloc_slow(pool, xdp, max);
  547. if (unlikely(pool->free_list_cnt)) {
  548. nb_entries1 = xp_alloc_reused(pool, xdp, max);
  549. if (nb_entries1 == max)
  550. return nb_entries1;
  551. max -= nb_entries1;
  552. xdp += nb_entries1;
  553. }
  554. nb_entries2 = xp_alloc_new_from_fq(pool, xdp, max);
  555. if (!nb_entries2)
  556. pool->fq->queue_empty_descs++;
  557. return nb_entries1 + nb_entries2;
  558. }
  559. EXPORT_SYMBOL(xp_alloc_batch);
  560. bool xp_can_alloc(struct xsk_buff_pool *pool, u32 count)
  561. {
  562. u32 req_count, avail_count;
  563. if (pool->free_list_cnt >= count)
  564. return true;
  565. req_count = count - pool->free_list_cnt;
  566. avail_count = xskq_cons_nb_entries(pool->fq, req_count);
  567. if (!avail_count)
  568. pool->fq->queue_empty_descs++;
  569. return avail_count >= req_count;
  570. }
  571. EXPORT_SYMBOL(xp_can_alloc);
  572. void xp_free(struct xdp_buff_xsk *xskb)
  573. {
  574. if (!list_empty(&xskb->list_node))
  575. return;
  576. xskb->pool->free_list_cnt++;
  577. list_add(&xskb->list_node, &xskb->pool->free_list);
  578. }
  579. EXPORT_SYMBOL(xp_free);
  580. static u64 __xp_raw_get_addr(const struct xsk_buff_pool *pool, u64 addr)
  581. {
  582. return pool->unaligned ? xp_unaligned_add_offset_to_addr(addr) : addr;
  583. }
  584. static void *__xp_raw_get_data(const struct xsk_buff_pool *pool, u64 addr)
  585. {
  586. return pool->addrs + addr;
  587. }
  588. void *xp_raw_get_data(struct xsk_buff_pool *pool, u64 addr)
  589. {
  590. return __xp_raw_get_data(pool, __xp_raw_get_addr(pool, addr));
  591. }
  592. EXPORT_SYMBOL(xp_raw_get_data);
  593. static dma_addr_t __xp_raw_get_dma(const struct xsk_buff_pool *pool, u64 addr)
  594. {
  595. return (pool->dma_pages[addr >> PAGE_SHIFT] &
  596. ~XSK_NEXT_PG_CONTIG_MASK) +
  597. (addr & ~PAGE_MASK);
  598. }
  599. dma_addr_t xp_raw_get_dma(struct xsk_buff_pool *pool, u64 addr)
  600. {
  601. return __xp_raw_get_dma(pool, __xp_raw_get_addr(pool, addr));
  602. }
  603. EXPORT_SYMBOL(xp_raw_get_dma);
  604. /**
  605. * xp_raw_get_ctx - get &xdp_desc context
  606. * @pool: XSk buff pool desc address belongs to
  607. * @addr: desc address (from userspace)
  608. *
  609. * Helper for getting desc's DMA address and metadata pointer, if present.
  610. * Saves one call on hotpath, double calculation of the actual address,
  611. * and inline checks for metadata presence and sanity.
  612. *
  613. * Return: new &xdp_desc_ctx struct containing desc's DMA address and metadata
  614. * pointer, if it is present and valid (initialized to %NULL otherwise).
  615. */
  616. struct xdp_desc_ctx xp_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr)
  617. {
  618. struct xdp_desc_ctx ret;
  619. addr = __xp_raw_get_addr(pool, addr);
  620. ret.dma = __xp_raw_get_dma(pool, addr);
  621. ret.meta = __xsk_buff_get_metadata(pool, __xp_raw_get_data(pool, addr));
  622. return ret;
  623. }
  624. EXPORT_SYMBOL(xp_raw_get_ctx);