net: Add the get current NAPI context API

Commit 69235aa80090 ("net: Remove the get current NAPI context API")
removed the definition of get_current_napi_context() as rmnet_data
was no longer using it. However, the rmnet_data change to use its
NAPI in multiple contexts was prone to race in hotplug scenarios.

Add back get_current_napi_context() and current_napi to the
softnet_data struct.

Change-Id: I494112f908c2222ff29cde049620d338c44d18c2
Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
This commit is contained in:
Subash Abhinov Kasiviswanathan 2017-11-01 15:32:41 -06:00 committed by Sean Tranchetti
parent 6b2ebf503a
commit 05b3252cf5
2 changed files with 21 additions and 2 deletions

View file

@ -2924,6 +2924,7 @@ extern int netdev_flow_limit_table_len;
*/
struct softnet_data {
struct list_head poll_list;
struct napi_struct *current_napi;
struct sk_buff_head process_queue;
/* stats */
@ -3526,6 +3527,7 @@ struct sk_buff *napi_get_frags(struct napi_struct *napi);
gro_result_t napi_gro_frags(struct napi_struct *napi);
struct packet_offload *gro_find_receive_by_type(__be16 type);
struct packet_offload *gro_find_complete_by_type(__be16 type);
extern struct napi_struct *get_current_napi_context(void);
static inline void napi_free_frags(struct napi_struct *napi)
{

View file

@ -5808,8 +5808,7 @@ static int process_backlog(struct napi_struct *napi, int quota)
rcu_read_unlock();
input_queue_head_incr(sd);
if (++work >= quota)
return work;
goto state_changed;
}
local_irq_disable();
@ -5833,6 +5832,10 @@ static int process_backlog(struct napi_struct *napi, int quota)
local_irq_enable();
}
state_changed:
napi_gro_flush(napi, false);
sd->current_napi = NULL;
return work;
}
@ -5925,9 +5928,12 @@ bool napi_complete_done(struct napi_struct *n, int work_done)
napi_gro_flush(n, false);
}
if (unlikely(!list_empty(&n->poll_list))) {
struct softnet_data *sd = this_cpu_ptr(&softnet_data);
/* If n->poll_list is not empty, we need to mask irqs */
local_irq_save(flags);
list_del_init(&n->poll_list);
sd->current_napi = NULL;
local_irq_restore(flags);
}
@ -6205,6 +6211,14 @@ void netif_napi_del(struct napi_struct *napi)
}
EXPORT_SYMBOL(netif_napi_del);
struct napi_struct *get_current_napi_context(void)
{
struct softnet_data *sd = this_cpu_ptr(&softnet_data);
return sd->current_napi;
}
EXPORT_SYMBOL(get_current_napi_context);
static int napi_poll(struct napi_struct *n, struct list_head *repoll)
{
void *have;
@ -6224,6 +6238,9 @@ static int napi_poll(struct napi_struct *n, struct list_head *repoll)
*/
work = 0;
if (test_bit(NAPI_STATE_SCHED, &n->state)) {
struct softnet_data *sd = this_cpu_ptr(&softnet_data);
sd->current_napi = n;
work = n->poll(n, weight);
trace_napi_poll(n, work, weight);
}