busy_poll.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * net busy poll support
  4. * Copyright(c) 2013 Intel Corporation.
  5. *
  6. * Author: Eliezer Tamir
  7. *
  8. * Contact Information:
  9. * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
  10. */
  11. #ifndef _LINUX_NET_BUSY_POLL_H
  12. #define _LINUX_NET_BUSY_POLL_H
  13. #include <linux/netdevice.h>
  14. #include <linux/sched/clock.h>
  15. #include <linux/sched/signal.h>
  16. #include <net/ip.h>
  17. #include <net/xdp.h>
  18. /* 0 - Reserved to indicate value not set
  19. * 1..NR_CPUS - Reserved for sender_cpu
  20. * NR_CPUS+1..~0 - Region available for NAPI IDs
  21. */
  22. #define MIN_NAPI_ID ((unsigned int)(NR_CPUS + 1))
  23. static inline bool napi_id_valid(unsigned int napi_id)
  24. {
  25. return napi_id >= MIN_NAPI_ID;
  26. }
  27. #define BUSY_POLL_BUDGET 8
  28. #ifdef CONFIG_NET_RX_BUSY_POLL
  29. struct napi_struct;
  30. extern unsigned int sysctl_net_busy_read __read_mostly;
  31. extern unsigned int sysctl_net_busy_poll __read_mostly;
  32. static inline bool net_busy_loop_on(void)
  33. {
  34. return READ_ONCE(sysctl_net_busy_poll);
  35. }
  36. static inline bool sk_can_busy_loop(const struct sock *sk)
  37. {
  38. return READ_ONCE(sk->sk_ll_usec) && !signal_pending(current);
  39. }
  40. bool sk_busy_loop_end(void *p, unsigned long start_time);
  41. void napi_busy_loop(unsigned int napi_id,
  42. bool (*loop_end)(void *, unsigned long),
  43. void *loop_end_arg, bool prefer_busy_poll, u16 budget);
  44. void napi_busy_loop_rcu(unsigned int napi_id,
  45. bool (*loop_end)(void *, unsigned long),
  46. void *loop_end_arg, bool prefer_busy_poll, u16 budget);
  47. void napi_suspend_irqs(unsigned int napi_id);
  48. void napi_resume_irqs(unsigned int napi_id);
  49. #else /* CONFIG_NET_RX_BUSY_POLL */
  50. static inline unsigned long net_busy_loop_on(void)
  51. {
  52. return 0;
  53. }
  54. static inline bool sk_can_busy_loop(struct sock *sk)
  55. {
  56. return false;
  57. }
  58. #endif /* CONFIG_NET_RX_BUSY_POLL */
  59. static inline unsigned long busy_loop_current_time(void)
  60. {
  61. #ifdef CONFIG_NET_RX_BUSY_POLL
  62. return (unsigned long)(ktime_get_ns() >> 10);
  63. #else
  64. return 0;
  65. #endif
  66. }
  67. /* in poll/select we use the global sysctl_net_ll_poll value */
  68. static inline bool busy_loop_timeout(unsigned long start_time)
  69. {
  70. #ifdef CONFIG_NET_RX_BUSY_POLL
  71. unsigned long bp_usec = READ_ONCE(sysctl_net_busy_poll);
  72. if (bp_usec) {
  73. unsigned long end_time = start_time + bp_usec;
  74. unsigned long now = busy_loop_current_time();
  75. return time_after(now, end_time);
  76. }
  77. #endif
  78. return true;
  79. }
  80. static inline bool sk_busy_loop_timeout(struct sock *sk,
  81. unsigned long start_time)
  82. {
  83. #ifdef CONFIG_NET_RX_BUSY_POLL
  84. unsigned long bp_usec = READ_ONCE(sk->sk_ll_usec);
  85. if (bp_usec) {
  86. unsigned long end_time = start_time + bp_usec;
  87. unsigned long now = busy_loop_current_time();
  88. return time_after(now, end_time);
  89. }
  90. #endif
  91. return true;
  92. }
  93. static inline void sk_busy_loop(struct sock *sk, int nonblock)
  94. {
  95. #ifdef CONFIG_NET_RX_BUSY_POLL
  96. unsigned int napi_id = READ_ONCE(sk->sk_napi_id);
  97. if (napi_id_valid(napi_id))
  98. napi_busy_loop(napi_id, nonblock ? NULL : sk_busy_loop_end, sk,
  99. READ_ONCE(sk->sk_prefer_busy_poll),
  100. READ_ONCE(sk->sk_busy_poll_budget) ?: BUSY_POLL_BUDGET);
  101. #endif
  102. }
  103. /* used in the NIC receive handler to mark the skb */
  104. static inline void __skb_mark_napi_id(struct sk_buff *skb,
  105. const struct gro_node *gro)
  106. {
  107. #ifdef CONFIG_NET_RX_BUSY_POLL
  108. /* If the skb was already marked with a valid NAPI ID, avoid overwriting
  109. * it.
  110. */
  111. if (!napi_id_valid(skb->napi_id))
  112. skb->napi_id = gro->cached_napi_id;
  113. #endif
  114. }
  115. static inline void skb_mark_napi_id(struct sk_buff *skb,
  116. const struct napi_struct *napi)
  117. {
  118. __skb_mark_napi_id(skb, &napi->gro);
  119. }
  120. /* used in the protocol handler to propagate the napi_id to the socket */
  121. static inline void sk_mark_napi_id(struct sock *sk, const struct sk_buff *skb)
  122. {
  123. #ifdef CONFIG_NET_RX_BUSY_POLL
  124. if (unlikely(READ_ONCE(sk->sk_napi_id) != skb->napi_id))
  125. WRITE_ONCE(sk->sk_napi_id, skb->napi_id);
  126. #endif
  127. sk_rx_queue_update(sk, skb);
  128. }
  129. /* Variant of sk_mark_napi_id() for passive flow setup,
  130. * as sk->sk_napi_id and sk->sk_rx_queue_mapping content
  131. * needs to be set.
  132. */
  133. static inline void sk_mark_napi_id_set(struct sock *sk,
  134. const struct sk_buff *skb)
  135. {
  136. #ifdef CONFIG_NET_RX_BUSY_POLL
  137. WRITE_ONCE(sk->sk_napi_id, skb->napi_id);
  138. #endif
  139. sk_rx_queue_set(sk, skb);
  140. }
  141. static inline void __sk_mark_napi_id_once(struct sock *sk, unsigned int napi_id)
  142. {
  143. #ifdef CONFIG_NET_RX_BUSY_POLL
  144. if (!READ_ONCE(sk->sk_napi_id))
  145. WRITE_ONCE(sk->sk_napi_id, napi_id);
  146. #endif
  147. }
  148. /* variant used for unconnected sockets */
  149. static inline void sk_mark_napi_id_once(struct sock *sk,
  150. const struct sk_buff *skb)
  151. {
  152. #ifdef CONFIG_NET_RX_BUSY_POLL
  153. __sk_mark_napi_id_once(sk, skb->napi_id);
  154. #endif
  155. }
  156. #endif /* _LINUX_NET_BUSY_POLL_H */