gve_utils.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // SPDX-License-Identifier: (GPL-2.0 OR MIT)
  2. /* Google virtual Ethernet (gve) driver
  3. *
  4. * Copyright (C) 2015-2021 Google, Inc.
  5. */
  6. #include "gve.h"
  7. #include "gve_adminq.h"
  8. #include "gve_utils.h"
  9. bool gve_tx_was_added_to_block(struct gve_priv *priv, int queue_idx)
  10. {
  11. struct gve_notify_block *block =
  12. &priv->ntfy_blocks[gve_tx_idx_to_ntfy(priv, queue_idx)];
  13. return block->tx != NULL;
  14. }
  15. void gve_tx_remove_from_block(struct gve_priv *priv, int queue_idx)
  16. {
  17. struct gve_notify_block *block =
  18. &priv->ntfy_blocks[gve_tx_idx_to_ntfy(priv, queue_idx)];
  19. block->tx = NULL;
  20. }
  21. void gve_tx_add_to_block(struct gve_priv *priv, int queue_idx)
  22. {
  23. unsigned int active_cpus = min_t(int, priv->num_ntfy_blks / 2,
  24. num_online_cpus());
  25. int ntfy_idx = gve_tx_idx_to_ntfy(priv, queue_idx);
  26. struct gve_notify_block *block = &priv->ntfy_blocks[ntfy_idx];
  27. struct gve_tx_ring *tx = &priv->tx[queue_idx];
  28. block->tx = tx;
  29. tx->ntfy_id = ntfy_idx;
  30. netif_set_xps_queue(priv->dev, get_cpu_mask(ntfy_idx % active_cpus),
  31. queue_idx);
  32. }
  33. bool gve_rx_was_added_to_block(struct gve_priv *priv, int queue_idx)
  34. {
  35. struct gve_notify_block *block =
  36. &priv->ntfy_blocks[gve_rx_idx_to_ntfy(priv, queue_idx)];
  37. return block->rx != NULL;
  38. }
  39. void gve_rx_remove_from_block(struct gve_priv *priv, int queue_idx)
  40. {
  41. struct gve_notify_block *block =
  42. &priv->ntfy_blocks[gve_rx_idx_to_ntfy(priv, queue_idx)];
  43. block->rx = NULL;
  44. }
  45. void gve_rx_add_to_block(struct gve_priv *priv, int queue_idx)
  46. {
  47. u32 ntfy_idx = gve_rx_idx_to_ntfy(priv, queue_idx);
  48. struct gve_notify_block *block = &priv->ntfy_blocks[ntfy_idx];
  49. struct gve_rx_ring *rx = &priv->rx[queue_idx];
  50. block->rx = rx;
  51. rx->ntfy_id = ntfy_idx;
  52. }
  53. struct sk_buff *gve_rx_copy_data(struct net_device *dev, struct napi_struct *napi,
  54. u8 *data, u16 len)
  55. {
  56. struct sk_buff *skb;
  57. skb = napi_alloc_skb(napi, len);
  58. if (unlikely(!skb))
  59. return NULL;
  60. __skb_put(skb, len);
  61. skb_copy_to_linear_data_offset(skb, 0, data, len);
  62. skb->protocol = eth_type_trans(skb, dev);
  63. return skb;
  64. }
  65. struct sk_buff *gve_rx_copy(struct net_device *dev, struct napi_struct *napi,
  66. struct gve_rx_slot_page_info *page_info, u16 len)
  67. {
  68. void *va = page_info->page_address + page_info->page_offset +
  69. page_info->pad;
  70. return gve_rx_copy_data(dev, napi, va, len);
  71. }
  72. void gve_dec_pagecnt_bias(struct gve_rx_slot_page_info *page_info)
  73. {
  74. page_info->pagecnt_bias--;
  75. if (page_info->pagecnt_bias == 0) {
  76. int pagecount = page_count(page_info->page);
  77. /* If we have run out of bias - set it back up to INT_MAX
  78. * minus the existing refs.
  79. */
  80. page_info->pagecnt_bias = INT_MAX - pagecount;
  81. /* Set pagecount back up to max. */
  82. page_ref_add(page_info->page, INT_MAX - pagecount);
  83. }
  84. }
  85. void gve_add_napi(struct gve_priv *priv, int ntfy_idx,
  86. int (*gve_poll)(struct napi_struct *, int))
  87. {
  88. struct gve_notify_block *block = &priv->ntfy_blocks[ntfy_idx];
  89. netif_napi_add(priv->dev, &block->napi, gve_poll);
  90. }
  91. void gve_remove_napi(struct gve_priv *priv, int ntfy_idx)
  92. {
  93. struct gve_notify_block *block = &priv->ntfy_blocks[ntfy_idx];
  94. netif_napi_del(&block->napi);
  95. }