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

Commit 01081591 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "net: Reset NAPI bit if IPI failed"

parents 866b7283 a5d8ad9c
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -2330,6 +2330,7 @@ struct softnet_data {
	struct Qdisc		*output_queue;
	struct Qdisc		**output_queue_tailp;
	struct list_head	poll_list;
	struct napi_struct	*current_napi;
	struct sk_buff		*completion_queue;
	struct sk_buff_head	process_queue;

@@ -2848,6 +2849,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)
{
+24 −4
Original line number Diff line number Diff line
@@ -4402,9 +4402,15 @@ static void net_rps_action_and_irq_enable(struct softnet_data *sd)
		while (remsd) {
			struct softnet_data *next = remsd->rps_ipi_next;

			if (cpu_online(remsd->cpu))
			if (cpu_online(remsd->cpu)) {
				smp_call_function_single_async(remsd->cpu,
							   &remsd->csd);
			} else {
				pr_err("%s() cpu offline\n", __func__);
				rps_lock(remsd);
				remsd->backlog.state = 0;
				rps_unlock(remsd);
			}
			remsd = next;
		}
	} else
@@ -4437,8 +4443,7 @@ static int process_backlog(struct napi_struct *napi, int quota)
			local_irq_disable();
			input_queue_head_incr(sd);
			if (++work >= quota) {
				local_irq_enable();
				return work;
				goto state_changed;
			}
		}

@@ -4456,14 +4461,17 @@ static int process_backlog(struct napi_struct *napi, int quota)
			napi->state = 0;
			rps_unlock(sd);

			break;
			goto state_changed;
		}

		skb_queue_splice_tail_init(&sd->input_pkt_queue,
					   &sd->process_queue);
		rps_unlock(sd);
	}
state_changed:
	local_irq_enable();
	napi_gro_flush(napi, false);
	sd->current_napi = NULL;

	return work;
}
@@ -4486,11 +4494,14 @@ EXPORT_SYMBOL(__napi_schedule);

void __napi_complete(struct napi_struct *n)
{
	struct softnet_data *sd = &__get_cpu_var(softnet_data);

	BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state));
	BUG_ON(n->gro_list);

	list_del(&n->poll_list);
	smp_mb__before_atomic();
	sd->current_napi = NULL;
	clear_bit(NAPI_STATE_SCHED, &n->state);
}
EXPORT_SYMBOL(__napi_complete);
@@ -4598,6 +4609,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 = &__get_cpu_var(softnet_data);

	return sd->current_napi;
}
EXPORT_SYMBOL(get_current_napi_context);

static void net_rx_action(struct softirq_action *h)
{
	struct softnet_data *sd = this_cpu_ptr(&softnet_data);
@@ -4639,6 +4658,7 @@ static void net_rx_action(struct softirq_action *h)
		 */
		work = 0;
		if (test_bit(NAPI_STATE_SCHED, &n->state)) {
			sd->current_napi = n;
			work = n->poll(n, weight);
			trace_napi_poll(n);
		}
+6 −6
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -250,14 +250,14 @@ static rx_handler_result_t __rmnet_deliver_skb(struct sk_buff *skb,
		case RX_HANDLER_PASS:
			skb->pkt_type = PACKET_HOST;
			rmnet_reset_mac_header(skb);

			if (rmnet_check_skb_can_gro(skb)) {
				if (skb->dev->features & NETIF_F_GRO) {
					napi = rmnet_vnd_get_napi(skb->dev);
					napi_schedule(napi);
			if (rmnet_check_skb_can_gro(skb) &&
			    (skb->dev->features & NETIF_F_GRO)) {
				napi = get_current_napi_context();
				if (napi != NULL) {
					gro_res = napi_gro_receive(napi, skb);
					trace_rmnet_gro_downlink(gro_res);
				} else {
					WARN_ONCE(1, "current napi is NULL\n");
					netif_receive_skb(skb);
				}
			} else {
+2 −40
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -19,7 +19,6 @@
#include <linux/rmnet_data.h>
#include <linux/msm_rmnet.h>
#include <linux/etherdevice.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/spinlock.h>
#include <net/pkt_sched.h>
@@ -38,9 +37,6 @@ RMNET_LOG_MODULE(RMNET_DATA_LOGMASK_VND);
#define RMNET_MAP_FLOW_NUM_TC_HANDLE 3
#define RMNET_VND_UF_ACTION_ADD 0
#define RMNET_VND_UF_ACTION_DEL 1
#define RMNET_DATA_NAPI_WEIGHT 1
#define RMNET_DATA_NAPI_WORK 0

enum {
	RMNET_VND_UPDATE_FLOW_OK,
	RMNET_VND_UPDATE_FLOW_NO_ACTION,
@@ -62,7 +58,7 @@ struct rmnet_map_flow_mapping_s {
struct rmnet_vnd_private_s {
	uint32_t qos_version;
	struct rmnet_logical_ep_conf_s local_ep;
	struct napi_struct napi;

	rwlock_t flow_map_lock;
	struct list_head flow_head;
	struct rmnet_map_flow_mapping_s root_flow;
@@ -507,19 +503,6 @@ static void rmnet_vnd_setup(struct net_device *dev)
	INIT_LIST_HEAD(&dev_conf->flow_head);
}

/**
 * rmnet_data_napi_poll() - NAPI poll function
 * @napi:      NAPI struct
 *
 * Called by net_rx_action() when NAPI is scheduled. Since we have already
 * queued packets to network stack, we just flush and return here.
 */
static int rmnet_data_napi_poll(struct napi_struct *napi, int budget)
{
	napi_complete(napi);
	return RMNET_DATA_NAPI_WORK;
}

/* ***************** Exposed API ******************************************** */

/**
@@ -574,7 +557,6 @@ int rmnet_vnd_create_dev(int id, struct net_device **new_device,
	struct net_device *dev;
	char dev_prefix[IFNAMSIZ];
	int p, rc = 0;
	struct napi_struct *n;

	if (id < 0 || id >= RMNET_DATA_MAX_VND) {
		*new_device = 0;
@@ -634,10 +616,6 @@ int rmnet_vnd_create_dev(int id, struct net_device **new_device,
		*new_device = dev;
	}

	n = rmnet_vnd_get_napi(dev);
	netif_napi_add(dev, n, rmnet_data_napi_poll, RMNET_DATA_NAPI_WEIGHT);
	napi_enable(n);

	LOGM("Registered device %s", dev->name);
	return rc;
}
@@ -681,10 +659,6 @@ int rmnet_vnd_free_dev(int id)
	rtnl_unlock();

	if (dev) {
		struct napi_struct *n = rmnet_vnd_get_napi(dev);

		napi_disable(n);
		netif_napi_del(n);
		unregister_netdev(dev);
		free_netdev(dev);
		return 0;
@@ -1125,15 +1099,3 @@ struct net_device *rmnet_vnd_get_by_id(int id)
	}
	return rmnet_devices[id];
}

/**
 * rmnet_vnd_get_napi() - Get NAPI struct from the device
 * @dev: Virtual network device
 *
 * Return:
 *      - napi struct corresponding to the netdevice
 */
struct napi_struct *rmnet_vnd_get_napi(struct net_device *dev)
{
	return &(((struct rmnet_vnd_private_s *)netdev_priv(dev))->napi);
}
+1 −2
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -37,6 +37,5 @@ int rmnet_vnd_del_tc_flow(uint32_t id, uint32_t map_flow, uint32_t tc_flow);
int rmnet_vnd_init(void);
void rmnet_vnd_exit(void);
struct net_device *rmnet_vnd_get_by_id(int id);
struct napi_struct *rmnet_vnd_get_napi(struct net_device *dev);

#endif /* _RMNET_DATA_VND_H_ */