Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a9b189a0 authored by Subash Abhinov Kasiviswanathan's avatar Subash Abhinov Kasiviswanathan
Browse files

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.

CRs-Fixed: 2086060
Change-Id: I7cf1c5e39a5ccbd7a74a096b11efd179a4d0d034
Signed-off-by: default avatarSubash Abhinov Kasiviswanathan <subashab@codeaurora.org>
parent 50b9a890
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -2741,6 +2741,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 */
@@ -3252,6 +3253,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)
{
+19 −2
Original line number Diff line number Diff line
@@ -5145,8 +5145,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();
@@ -5170,6 +5169,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;
}

@@ -5262,9 +5265,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);
	}

@@ -5520,6 +5526,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;
@@ -5539,6 +5553,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);
	}