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: 1078373
Change-Id: I7cf1c5e39a5ccbd7a74a096b11efd179a4d0d034
Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
diff --git a/net/core/dev.c b/net/core/dev.c
index 4bc19a1..446da53 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4858,8 +4858,7 @@
 			rcu_read_unlock();
 			input_queue_head_incr(sd);
 			if (++work >= quota)
-				return work;
-
+				goto state_changed;
 		}
 
 		local_irq_disable();
@@ -4883,6 +4882,10 @@
 		local_irq_enable();
 	}
 
+state_changed:
+	napi_gro_flush(napi, false);
+	sd->current_napi = NULL;
+
 	return work;
 }
 
@@ -4917,10 +4920,13 @@
 
 void __napi_complete(struct napi_struct *n)
 {
+	struct softnet_data *sd = this_cpu_ptr(&softnet_data);
+
 	BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state));
 
 	list_del_init(&n->poll_list);
 	smp_mb__before_atomic();
+	sd->current_napi = NULL;
 	clear_bit(NAPI_STATE_SCHED, &n->state);
 }
 EXPORT_SYMBOL(__napi_complete);
@@ -5136,6 +5142,14 @@
 }
 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;
@@ -5155,6 +5169,9 @@
 	 */
 	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);
 	}