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

Commit 841dfa43 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'netpoll-avoid-capture-effects-for-NAPI-drivers'



Eric Dumazet says:

====================
netpoll: avoid capture effects for NAPI drivers

As diagnosed by Song Liu, ndo_poll_controller() can
be very dangerous on loaded hosts, since the cpu
calling ndo_poll_controller() might steal all NAPI
contexts (for all RX/TX queues of the NIC).

This capture, showing one ksoftirqd eating all cycles
can last for unlimited amount of time, since one
cpu is generally not able to drain all the queues under load.

It seems that all networking drivers that do use NAPI
for their TX completions, should not provide a ndo_poll_controller() :

Most NAPI drivers have netpoll support already handled
in core networking stack, since netpoll_poll_dev()
uses poll_napi(dev) to iterate through registered
NAPI contexts for a device.

This patch series take care of the first round, we will
handle other drivers in future rounds.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 16fdf8ba 765cdc20
Loading
Loading
Loading
Loading
+2 −9
Original line number Diff line number Diff line
@@ -971,16 +971,13 @@ static void bond_poll_controller(struct net_device *bond_dev)
	struct slave *slave = NULL;
	struct list_head *iter;
	struct ad_info ad_info;
	struct netpoll_info *ni;
	const struct net_device_ops *ops;

	if (BOND_MODE(bond) == BOND_MODE_8023AD)
		if (bond_3ad_get_active_agg_info(bond, &ad_info))
			return;

	bond_for_each_slave_rcu(bond, slave, iter) {
		ops = slave->dev->netdev_ops;
		if (!bond_slave_is_up(slave) || !ops->ndo_poll_controller)
		if (!bond_slave_is_up(slave))
			continue;

		if (BOND_MODE(bond) == BOND_MODE_8023AD) {
@@ -992,11 +989,7 @@ static void bond_poll_controller(struct net_device *bond_dev)
				continue;
		}

		ni = rcu_dereference_bh(slave->dev->npinfo);
		if (down_trylock(&ni->dev_lock))
			continue;
		ops->ndo_poll_controller(slave->dev);
		up(&ni->dev_lock);
		netpoll_poll_dev(slave->dev);
	}
}

+0 −16
Original line number Diff line number Diff line
@@ -12894,19 +12894,6 @@ static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
	}
}

#ifdef CONFIG_NET_POLL_CONTROLLER
static void poll_bnx2x(struct net_device *dev)
{
	struct bnx2x *bp = netdev_priv(dev);
	int i;

	for_each_eth_queue(bp, i) {
		struct bnx2x_fastpath *fp = &bp->fp[i];
		napi_schedule(&bnx2x_fp(bp, fp->index, napi));
	}
}
#endif

static int bnx2x_validate_addr(struct net_device *dev)
{
	struct bnx2x *bp = netdev_priv(dev);
@@ -13113,9 +13100,6 @@ static const struct net_device_ops bnx2x_netdev_ops = {
	.ndo_tx_timeout		= bnx2x_tx_timeout,
	.ndo_vlan_rx_add_vid	= bnx2x_vlan_rx_add_vid,
	.ndo_vlan_rx_kill_vid	= bnx2x_vlan_rx_kill_vid,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= poll_bnx2x,
#endif
	.ndo_setup_tc		= __bnx2x_setup_tc,
#ifdef CONFIG_BNX2X_SRIOV
	.ndo_set_vf_mac		= bnx2x_set_vf_mac,
+0 −18
Original line number Diff line number Diff line
@@ -7672,21 +7672,6 @@ static void bnxt_tx_timeout(struct net_device *dev)
	bnxt_queue_sp_work(bp);
}

#ifdef CONFIG_NET_POLL_CONTROLLER
static void bnxt_poll_controller(struct net_device *dev)
{
	struct bnxt *bp = netdev_priv(dev);
	int i;

	/* Only process tx rings/combined rings in netpoll mode. */
	for (i = 0; i < bp->tx_nr_rings; i++) {
		struct bnxt_tx_ring_info *txr = &bp->tx_ring[i];

		napi_schedule(&txr->bnapi->napi);
	}
}
#endif

static void bnxt_timer(struct timer_list *t)
{
	struct bnxt *bp = from_timer(bp, t, timer);
@@ -8519,9 +8504,6 @@ static const struct net_device_ops bnxt_netdev_ops = {
	.ndo_set_vf_link_state	= bnxt_set_vf_link_state,
	.ndo_set_vf_spoofchk	= bnxt_set_vf_spoofchk,
	.ndo_set_vf_trust	= bnxt_set_vf_trust,
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= bnxt_poll_controller,
#endif
	.ndo_setup_tc           = bnxt_setup_tc,
#ifdef CONFIG_RFS_ACCEL
+0 −3
Original line number Diff line number Diff line
@@ -504,9 +504,6 @@ void fm10k_update_stats(struct fm10k_intfc *interface);
void fm10k_service_event_schedule(struct fm10k_intfc *interface);
void fm10k_macvlan_schedule(struct fm10k_intfc *interface);
void fm10k_update_rx_drop_en(struct fm10k_intfc *interface);
#ifdef CONFIG_NET_POLL_CONTROLLER
void fm10k_netpoll(struct net_device *netdev);
#endif

/* Netdev */
struct net_device *fm10k_alloc_netdev(const struct fm10k_info *info);
+0 −3
Original line number Diff line number Diff line
@@ -1648,9 +1648,6 @@ static const struct net_device_ops fm10k_netdev_ops = {
	.ndo_udp_tunnel_del	= fm10k_udp_tunnel_del,
	.ndo_dfwd_add_station	= fm10k_dfwd_add_station,
	.ndo_dfwd_del_station	= fm10k_dfwd_del_station,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= fm10k_netpoll,
#endif
	.ndo_features_check	= fm10k_features_check,
};

Loading