2013-06-10 12:39:50 +04:00
/*
2013-07-10 18:13:26 +04:00
* net busy poll support
2013-06-10 12:39:50 +04:00
* Copyright ( c ) 2013 Intel Corporation .
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms and conditions of the GNU General Public License ,
* version 2 , as published by the Free Software Foundation .
*
* This program is distributed in the hope it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
* more details .
*
* You should have received a copy of the GNU General Public License along with
* this program ; if not , write to the Free Software Foundation , Inc . ,
* 51 Franklin St - Fifth Floor , Boston , MA 02110 - 1301 USA .
*
* Author : Eliezer Tamir
*
* Contact Information :
* e1000 - devel Mailing List < e1000 - devel @ lists . sourceforge . net >
*/
2013-07-10 18:13:26 +04:00
# ifndef _LINUX_NET_BUSY_POLL_H
# define _LINUX_NET_BUSY_POLL_H
2013-06-10 12:39:50 +04:00
# include <linux/netdevice.h>
# include <net/ip.h>
2013-08-01 07:10:25 +04:00
# ifdef CONFIG_NET_RX_BUSY_POLL
2013-06-10 12:39:50 +04:00
struct napi_struct ;
2013-07-10 18:13:36 +04:00
extern unsigned int sysctl_net_busy_read __read_mostly ;
extern unsigned int sysctl_net_busy_poll __read_mostly ;
2013-06-10 12:39:50 +04:00
2013-07-08 17:20:34 +04:00
static inline bool net_busy_loop_on ( void )
2013-06-28 16:59:35 +04:00
{
2013-07-10 18:13:36 +04:00
return sysctl_net_busy_poll ;
2013-06-28 16:59:35 +04:00
}
2013-07-09 14:09:21 +04:00
static inline u64 busy_loop_us_clock ( void )
2013-06-28 16:59:26 +04:00
{
2013-11-19 19:13:38 +04:00
return local_clock ( ) > > 10 ;
2013-06-28 16:59:26 +04:00
}
2013-07-09 14:09:21 +04:00
static inline unsigned long sk_busy_loop_end_time ( struct sock * sk )
2013-06-10 12:39:50 +04:00
{
2013-07-09 14:09:21 +04:00
return busy_loop_us_clock ( ) + ACCESS_ONCE ( sk - > sk_ll_usec ) ;
2013-06-24 11:28:03 +04:00
}
2013-06-14 17:33:35 +04:00
2013-07-09 14:09:21 +04:00
/* in poll/select we use the global sysctl_net_ll_poll value */
static inline unsigned long busy_loop_end_time ( void )
2013-07-03 00:22:47 +04:00
{
2013-07-10 18:13:36 +04:00
return busy_loop_us_clock ( ) + ACCESS_ONCE ( sysctl_net_busy_poll ) ;
2013-06-10 12:39:50 +04:00
}
2016-11-15 21:15:12 +03:00
static inline bool sk_can_busy_loop ( const struct sock * sk )
2013-06-10 12:39:50 +04:00
{
2016-11-15 21:15:12 +03:00
return sk - > sk_ll_usec & & sk - > sk_napi_id & & ! signal_pending ( current ) ;
2013-06-10 12:39:50 +04:00
}
2013-07-09 14:09:21 +04:00
static inline bool busy_loop_timeout ( unsigned long end_time )
2013-06-10 12:39:50 +04:00
{
2013-07-09 14:09:21 +04:00
unsigned long now = busy_loop_us_clock ( ) ;
2013-07-03 00:22:47 +04:00
2013-07-09 14:09:21 +04:00
return time_after ( now , end_time ) ;
2013-06-10 12:39:50 +04:00
}
2015-11-18 17:30:52 +03:00
bool sk_busy_loop ( struct sock * sk , int nonblock ) ;
2013-06-10 12:39:50 +04:00
/* used in the NIC receive handler to mark the skb */
2013-07-10 18:13:26 +04:00
static inline void skb_mark_napi_id ( struct sk_buff * skb ,
struct napi_struct * napi )
2013-06-10 12:39:50 +04:00
{
skb - > napi_id = napi - > napi_id ;
}
2013-08-01 07:10:25 +04:00
# else /* CONFIG_NET_RX_BUSY_POLL */
2013-07-08 17:20:34 +04:00
static inline unsigned long net_busy_loop_on ( void )
2013-06-28 16:59:35 +04:00
{
return 0 ;
}
2013-06-10 12:39:50 +04:00
2013-07-09 14:09:21 +04:00
static inline unsigned long busy_loop_end_time ( void )
2013-06-10 12:39:50 +04:00
{
return 0 ;
}
2013-07-08 17:20:34 +04:00
static inline bool sk_can_busy_loop ( struct sock * sk )
2013-06-10 12:39:50 +04:00
{
return false ;
}
2013-07-10 18:13:26 +04:00
static inline void skb_mark_napi_id ( struct sk_buff * skb ,
struct napi_struct * napi )
2013-06-10 12:39:50 +04:00
{
}
2013-07-09 14:09:21 +04:00
static inline bool busy_loop_timeout ( unsigned long end_time )
2013-06-10 12:39:50 +04:00
{
2013-07-09 14:09:21 +04:00
return true ;
2013-06-10 12:39:50 +04:00
}
2013-08-01 07:10:24 +04:00
static inline bool sk_busy_loop ( struct sock * sk , int nonblock )
{
return false ;
}
2013-08-01 07:10:25 +04:00
# endif /* CONFIG_NET_RX_BUSY_POLL */
2016-11-16 20:10:42 +03:00
/* used in the protocol hanlder to propagate the napi_id to the socket */
static inline void sk_mark_napi_id ( struct sock * sk , const struct sk_buff * skb )
{
# ifdef CONFIG_NET_RX_BUSY_POLL
sk - > sk_napi_id = skb - > napi_id ;
# endif
}
/* variant used for unconnected sockets */
static inline void sk_mark_napi_id_once ( struct sock * sk ,
const struct sk_buff * skb )
{
# ifdef CONFIG_NET_RX_BUSY_POLL
if ( ! sk - > sk_napi_id )
sk - > sk_napi_id = skb - > napi_id ;
# endif
}
2013-07-10 18:13:26 +04:00
# endif /* _LINUX_NET_BUSY_POLL_H */