xref: /openbmc/linux/include/net/busy_poll.h (revision 545cd5e5ec5477c325e4098b6fd21213dceda408)
1076bb0c8SEliezer Tamir /*
28b80cda5SEliezer Tamir  * net busy poll support
3076bb0c8SEliezer Tamir  * Copyright(c) 2013 Intel Corporation.
4076bb0c8SEliezer Tamir  *
5076bb0c8SEliezer Tamir  * This program is free software; you can redistribute it and/or modify it
6076bb0c8SEliezer Tamir  * under the terms and conditions of the GNU General Public License,
7076bb0c8SEliezer Tamir  * version 2, as published by the Free Software Foundation.
8076bb0c8SEliezer Tamir  *
9076bb0c8SEliezer Tamir  * This program is distributed in the hope it will be useful, but WITHOUT
10076bb0c8SEliezer Tamir  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11076bb0c8SEliezer Tamir  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12076bb0c8SEliezer Tamir  * more details.
13076bb0c8SEliezer Tamir  *
14076bb0c8SEliezer Tamir  * You should have received a copy of the GNU General Public License along with
15076bb0c8SEliezer Tamir  * this program; if not, write to the Free Software Foundation, Inc.,
16076bb0c8SEliezer Tamir  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17076bb0c8SEliezer Tamir  *
18076bb0c8SEliezer Tamir  * Author: Eliezer Tamir
19076bb0c8SEliezer Tamir  *
20076bb0c8SEliezer Tamir  * Contact Information:
21076bb0c8SEliezer Tamir  * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
22076bb0c8SEliezer Tamir  */
23076bb0c8SEliezer Tamir 
248b80cda5SEliezer Tamir #ifndef _LINUX_NET_BUSY_POLL_H
258b80cda5SEliezer Tamir #define _LINUX_NET_BUSY_POLL_H
26076bb0c8SEliezer Tamir 
27076bb0c8SEliezer Tamir #include <linux/netdevice.h>
28e6017571SIngo Molnar #include <linux/sched/clock.h>
29174cd4b1SIngo Molnar #include <linux/sched/signal.h>
30076bb0c8SEliezer Tamir #include <net/ip.h>
31076bb0c8SEliezer Tamir 
32e0d1095aSCong Wang #ifdef CONFIG_NET_RX_BUSY_POLL
33076bb0c8SEliezer Tamir 
34076bb0c8SEliezer Tamir struct napi_struct;
3564b0dc51SEliezer Tamir extern unsigned int sysctl_net_busy_read __read_mostly;
3664b0dc51SEliezer Tamir extern unsigned int sysctl_net_busy_poll __read_mostly;
37076bb0c8SEliezer Tamir 
38*545cd5e5SAlexander Duyck /*		0 - Reserved to indicate value not set
39*545cd5e5SAlexander Duyck  *     1..NR_CPUS - Reserved for sender_cpu
40*545cd5e5SAlexander Duyck  *  NR_CPUS+1..~0 - Region available for NAPI IDs
41*545cd5e5SAlexander Duyck  */
42*545cd5e5SAlexander Duyck #define MIN_NAPI_ID ((unsigned int)(NR_CPUS + 1))
43*545cd5e5SAlexander Duyck 
44076bb0c8SEliezer Tamir static inline bool net_busy_loop_on(void)
45076bb0c8SEliezer Tamir {
4664b0dc51SEliezer Tamir 	return sysctl_net_busy_poll;
47076bb0c8SEliezer Tamir }
48076bb0c8SEliezer Tamir 
49076bb0c8SEliezer Tamir static inline u64 busy_loop_us_clock(void)
50076bb0c8SEliezer Tamir {
5137089834SPeter Zijlstra 	return local_clock() >> 10;
52076bb0c8SEliezer Tamir }
53076bb0c8SEliezer Tamir 
54076bb0c8SEliezer Tamir static inline unsigned long sk_busy_loop_end_time(struct sock *sk)
55076bb0c8SEliezer Tamir {
56076bb0c8SEliezer Tamir 	return busy_loop_us_clock() + ACCESS_ONCE(sk->sk_ll_usec);
57076bb0c8SEliezer Tamir }
58076bb0c8SEliezer Tamir 
59076bb0c8SEliezer Tamir /* in poll/select we use the global sysctl_net_ll_poll value */
60076bb0c8SEliezer Tamir static inline unsigned long busy_loop_end_time(void)
61076bb0c8SEliezer Tamir {
6264b0dc51SEliezer Tamir 	return busy_loop_us_clock() + ACCESS_ONCE(sysctl_net_busy_poll);
63076bb0c8SEliezer Tamir }
64076bb0c8SEliezer Tamir 
6521cb84c4SEric Dumazet static inline bool sk_can_busy_loop(const struct sock *sk)
66076bb0c8SEliezer Tamir {
67*545cd5e5SAlexander Duyck 	return sk->sk_ll_usec && !signal_pending(current);
68076bb0c8SEliezer Tamir }
69076bb0c8SEliezer Tamir 
70076bb0c8SEliezer Tamir static inline bool busy_loop_timeout(unsigned long end_time)
71076bb0c8SEliezer Tamir {
72076bb0c8SEliezer Tamir 	unsigned long now = busy_loop_us_clock();
73076bb0c8SEliezer Tamir 
74076bb0c8SEliezer Tamir 	return time_after(now, end_time);
75076bb0c8SEliezer Tamir }
76076bb0c8SEliezer Tamir 
7702d62e86SEric Dumazet bool sk_busy_loop(struct sock *sk, int nonblock);
78076bb0c8SEliezer Tamir 
79076bb0c8SEliezer Tamir /* used in the NIC receive handler to mark the skb */
808b80cda5SEliezer Tamir static inline void skb_mark_napi_id(struct sk_buff *skb,
818b80cda5SEliezer Tamir 				    struct napi_struct *napi)
82076bb0c8SEliezer Tamir {
83076bb0c8SEliezer Tamir 	skb->napi_id = napi->napi_id;
84076bb0c8SEliezer Tamir }
85076bb0c8SEliezer Tamir 
86076bb0c8SEliezer Tamir 
87e0d1095aSCong Wang #else /* CONFIG_NET_RX_BUSY_POLL */
88076bb0c8SEliezer Tamir static inline unsigned long net_busy_loop_on(void)
89076bb0c8SEliezer Tamir {
90076bb0c8SEliezer Tamir 	return 0;
91076bb0c8SEliezer Tamir }
92076bb0c8SEliezer Tamir 
93076bb0c8SEliezer Tamir static inline unsigned long busy_loop_end_time(void)
94076bb0c8SEliezer Tamir {
95076bb0c8SEliezer Tamir 	return 0;
96076bb0c8SEliezer Tamir }
97076bb0c8SEliezer Tamir 
98076bb0c8SEliezer Tamir static inline bool sk_can_busy_loop(struct sock *sk)
99076bb0c8SEliezer Tamir {
100076bb0c8SEliezer Tamir 	return false;
101076bb0c8SEliezer Tamir }
102076bb0c8SEliezer Tamir 
1038b80cda5SEliezer Tamir static inline void skb_mark_napi_id(struct sk_buff *skb,
1048b80cda5SEliezer Tamir 				    struct napi_struct *napi)
105076bb0c8SEliezer Tamir {
106076bb0c8SEliezer Tamir }
107076bb0c8SEliezer Tamir 
108076bb0c8SEliezer Tamir static inline bool busy_loop_timeout(unsigned long end_time)
109076bb0c8SEliezer Tamir {
110076bb0c8SEliezer Tamir 	return true;
111076bb0c8SEliezer Tamir }
112076bb0c8SEliezer Tamir 
113dfcefb0bSCong Wang static inline bool sk_busy_loop(struct sock *sk, int nonblock)
114dfcefb0bSCong Wang {
115dfcefb0bSCong Wang 	return false;
116dfcefb0bSCong Wang }
117dfcefb0bSCong Wang 
118e0d1095aSCong Wang #endif /* CONFIG_NET_RX_BUSY_POLL */
119e68b6e50SEric Dumazet 
120e68b6e50SEric Dumazet /* used in the protocol hanlder to propagate the napi_id to the socket */
121e68b6e50SEric Dumazet static inline void sk_mark_napi_id(struct sock *sk, const struct sk_buff *skb)
122e68b6e50SEric Dumazet {
123e68b6e50SEric Dumazet #ifdef CONFIG_NET_RX_BUSY_POLL
124e68b6e50SEric Dumazet 	sk->sk_napi_id = skb->napi_id;
125e68b6e50SEric Dumazet #endif
126e68b6e50SEric Dumazet }
127e68b6e50SEric Dumazet 
128e68b6e50SEric Dumazet /* variant used for unconnected sockets */
129e68b6e50SEric Dumazet static inline void sk_mark_napi_id_once(struct sock *sk,
130e68b6e50SEric Dumazet 					const struct sk_buff *skb)
131e68b6e50SEric Dumazet {
132e68b6e50SEric Dumazet #ifdef CONFIG_NET_RX_BUSY_POLL
133e68b6e50SEric Dumazet 	if (!sk->sk_napi_id)
134e68b6e50SEric Dumazet 		sk->sk_napi_id = skb->napi_id;
135e68b6e50SEric Dumazet #endif
136e68b6e50SEric Dumazet }
137e68b6e50SEric Dumazet 
1388b80cda5SEliezer Tamir #endif /* _LINUX_NET_BUSY_POLL_H */
139