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

Commit 228fdc08 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull networking fixes from David Miller:
 "Famouse last words: "final pull request" :-)

  I'm sending this because Jason Wang's fixes are pretty important

   1) Add missing per-cpu stats initialization to ip6_vti.  Otherwise
      lockdep spits out a call trace.  From Li RongQing.

   2) Fix NULL oops in wireless hwsim, from Javier Lopez

   3) TIPC deferred packet queue unlink must NULL out skb->next to avoid
      crashes.  From Erik Hugne

   4) Fix access to uninitialized buffer in nf_nat netfilter code, from
      Daniel Borkmann

   5) Fix lifetime of ipv6 loopback and SIT tunnel addresses, otherwise
      they basically timeout immediately.  From Hannes Frederic Sowa

   6) Fix DMA unmapping of TSO packets in bnx2x driver, from Michal
      Schmidt

   7) Do not allow L2 forwarding offload via macvtap device, the way
      things are now it will not end up being forwaded at all.  From
      Jason Wang

   8) Fix transmit queue selection via ndo_dfwd_start_xmit(), fixing
      things like applying NETIF_F_LLTX to the wrong device (!!) and
      eliding the proper transmit watchdog handling

   9) qlcnic driver was not updating tx statistics at all, from Manish
      Chopra"

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net:
  qlcnic: Fix ethtool statistics length calculation
  qlcnic: Fix bug in TX statistics
  net: core: explicitly select a txq before doing l2 forwarding
  macvlan: forbid L2 fowarding offload for macvtap
  bnx2x: fix DMA unmapping of TSO split BDs
  ipv6: add link-local, sit and loopback address with INFINITY_LIFE_TIME
  bnx2x: prevent WARN during driver unload
  tipc: correctly unlink packets from deferred packet queue
  ipv6: pcpu_tstats.syncp should be initialised in ip6_vti.c
  netfilter: only warn once on wrong seqadj usage
  netfilter: nf_nat: fix access to uninitialized buffer in IRC NAT helper
  NFC: Fix target mode p2p link establishment
  iwlwifi: add new devices for 7265 series
  mac80211: move "bufferable MMPDU" check to fix AP mode scan
  mac80211_hwsim: Fix NULL pointer dereference
parents e2bc4470 d6e9c89a
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -3732,7 +3732,8 @@ static inline int bond_slave_override(struct bonding *bond,
}


static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb)
static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb,
			     void *accel_priv)
{
	/*
	 * This helper function exists to help dev_pick_tx get the correct
+34 −10
Original line number Diff line number Diff line
@@ -520,10 +520,12 @@ struct bnx2x_fastpath {
#define BNX2X_FP_STATE_IDLE		      0
#define BNX2X_FP_STATE_NAPI		(1 << 0)    /* NAPI owns this FP */
#define BNX2X_FP_STATE_POLL		(1 << 1)    /* poll owns this FP */
#define BNX2X_FP_STATE_NAPI_YIELD	(1 << 2)    /* NAPI yielded this FP */
#define BNX2X_FP_STATE_POLL_YIELD	(1 << 3)    /* poll yielded this FP */
#define BNX2X_FP_STATE_DISABLED		(1 << 2)
#define BNX2X_FP_STATE_NAPI_YIELD	(1 << 3)    /* NAPI yielded this FP */
#define BNX2X_FP_STATE_POLL_YIELD	(1 << 4)    /* poll yielded this FP */
#define BNX2X_FP_OWNED	(BNX2X_FP_STATE_NAPI | BNX2X_FP_STATE_POLL)
#define BNX2X_FP_YIELD	(BNX2X_FP_STATE_NAPI_YIELD | BNX2X_FP_STATE_POLL_YIELD)
#define BNX2X_FP_LOCKED	(BNX2X_FP_STATE_NAPI | BNX2X_FP_STATE_POLL)
#define BNX2X_FP_LOCKED	(BNX2X_FP_OWNED | BNX2X_FP_STATE_DISABLED)
#define BNX2X_FP_USER_PEND (BNX2X_FP_STATE_POLL | BNX2X_FP_STATE_POLL_YIELD)
	/* protect state */
	spinlock_t lock;
@@ -613,7 +615,7 @@ static inline bool bnx2x_fp_lock_napi(struct bnx2x_fastpath *fp)
{
	bool rc = true;

	spin_lock(&fp->lock);
	spin_lock_bh(&fp->lock);
	if (fp->state & BNX2X_FP_LOCKED) {
		WARN_ON(fp->state & BNX2X_FP_STATE_NAPI);
		fp->state |= BNX2X_FP_STATE_NAPI_YIELD;
@@ -622,7 +624,7 @@ static inline bool bnx2x_fp_lock_napi(struct bnx2x_fastpath *fp)
		/* we don't care if someone yielded */
		fp->state = BNX2X_FP_STATE_NAPI;
	}
	spin_unlock(&fp->lock);
	spin_unlock_bh(&fp->lock);
	return rc;
}

@@ -631,14 +633,16 @@ static inline bool bnx2x_fp_unlock_napi(struct bnx2x_fastpath *fp)
{
	bool rc = false;

	spin_lock(&fp->lock);
	spin_lock_bh(&fp->lock);
	WARN_ON(fp->state &
		(BNX2X_FP_STATE_POLL | BNX2X_FP_STATE_NAPI_YIELD));

	if (fp->state & BNX2X_FP_STATE_POLL_YIELD)
		rc = true;
	fp->state = BNX2X_FP_STATE_IDLE;
	spin_unlock(&fp->lock);

	/* state ==> idle, unless currently disabled */
	fp->state &= BNX2X_FP_STATE_DISABLED;
	spin_unlock_bh(&fp->lock);
	return rc;
}

@@ -669,7 +673,9 @@ static inline bool bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp)

	if (fp->state & BNX2X_FP_STATE_POLL_YIELD)
		rc = true;
	fp->state = BNX2X_FP_STATE_IDLE;

	/* state ==> idle, unless currently disabled */
	fp->state &= BNX2X_FP_STATE_DISABLED;
	spin_unlock_bh(&fp->lock);
	return rc;
}
@@ -677,9 +683,23 @@ static inline bool bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp)
/* true if a socket is polling, even if it did not get the lock */
static inline bool bnx2x_fp_ll_polling(struct bnx2x_fastpath *fp)
{
	WARN_ON(!(fp->state & BNX2X_FP_LOCKED));
	WARN_ON(!(fp->state & BNX2X_FP_OWNED));
	return fp->state & BNX2X_FP_USER_PEND;
}

/* false if fp is currently owned */
static inline bool bnx2x_fp_ll_disable(struct bnx2x_fastpath *fp)
{
	int rc = true;

	spin_lock_bh(&fp->lock);
	if (fp->state & BNX2X_FP_OWNED)
		rc = false;
	fp->state |= BNX2X_FP_STATE_DISABLED;
	spin_unlock_bh(&fp->lock);

	return rc;
}
#else
static inline void bnx2x_fp_init_lock(struct bnx2x_fastpath *fp)
{
@@ -709,6 +729,10 @@ static inline bool bnx2x_fp_ll_polling(struct bnx2x_fastpath *fp)
{
	return false;
}
static inline bool bnx2x_fp_ll_disable(struct bnx2x_fastpath *fp)
{
	return true;
}
#endif /* CONFIG_NET_RX_BUSY_POLL */

/* Use 2500 as a mini-jumbo MTU for FCoE */
+15 −13
Original line number Diff line number Diff line
@@ -160,6 +160,7 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata,
	struct sk_buff *skb = tx_buf->skb;
	u16 bd_idx = TX_BD(tx_buf->first_bd), new_cons;
	int nbd;
	u16 split_bd_len = 0;

	/* prefetch skb end pointer to speedup dev_kfree_skb() */
	prefetch(&skb->end);
@@ -167,10 +168,7 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata,
	DP(NETIF_MSG_TX_DONE, "fp[%d]: pkt_idx %d  buff @(%p)->skb %p\n",
	   txdata->txq_index, idx, tx_buf, skb);

	/* unmap first bd */
	tx_start_bd = &txdata->tx_desc_ring[bd_idx].start_bd;
	dma_unmap_single(&bp->pdev->dev, BD_UNMAP_ADDR(tx_start_bd),
			 BD_UNMAP_LEN(tx_start_bd), DMA_TO_DEVICE);

	nbd = le16_to_cpu(tx_start_bd->nbd) - 1;
#ifdef BNX2X_STOP_ON_ERROR
@@ -188,12 +186,19 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata,
	--nbd;
	bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));

	/* ...and the TSO split header bd since they have no mapping */
	/* TSO headers+data bds share a common mapping. See bnx2x_tx_split() */
	if (tx_buf->flags & BNX2X_TSO_SPLIT_BD) {
		tx_data_bd = &txdata->tx_desc_ring[bd_idx].reg_bd;
		split_bd_len = BD_UNMAP_LEN(tx_data_bd);
		--nbd;
		bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
	}

	/* unmap first bd */
	dma_unmap_single(&bp->pdev->dev, BD_UNMAP_ADDR(tx_start_bd),
			 BD_UNMAP_LEN(tx_start_bd) + split_bd_len,
			 DMA_TO_DEVICE);

	/* now free frags */
	while (nbd > 0) {

@@ -1790,26 +1795,22 @@ static void bnx2x_napi_disable_cnic(struct bnx2x *bp)
{
	int i;

	local_bh_disable();
	for_each_rx_queue_cnic(bp, i) {
		napi_disable(&bnx2x_fp(bp, i, napi));
		while (!bnx2x_fp_lock_napi(&bp->fp[i]))
			mdelay(1);
		while (!bnx2x_fp_ll_disable(&bp->fp[i]))
			usleep_range(1000, 2000);
	}
	local_bh_enable();
}

static void bnx2x_napi_disable(struct bnx2x *bp)
{
	int i;

	local_bh_disable();
	for_each_eth_queue(bp, i) {
		napi_disable(&bnx2x_fp(bp, i, napi));
		while (!bnx2x_fp_lock_napi(&bp->fp[i]))
			mdelay(1);
		while (!bnx2x_fp_ll_disable(&bp->fp[i]))
			usleep_range(1000, 2000);
	}
	local_bh_enable();
}

void bnx2x_netif_start(struct bnx2x *bp)
@@ -1832,7 +1833,8 @@ void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw)
		bnx2x_napi_disable_cnic(bp);
}

u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb)
u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb,
		       void *accel_priv)
{
	struct bnx2x *bp = netdev_priv(dev);

+2 −1
Original line number Diff line number Diff line
@@ -524,7 +524,8 @@ int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac);
int bnx2x_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos);

/* select_queue callback */
u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb);
u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb,
		       void *accel_priv);

static inline void bnx2x_update_rx_prod(struct bnx2x *bp,
					struct bnx2x_fastpath *fp,
+13 −20
Original line number Diff line number Diff line
@@ -6827,12 +6827,20 @@ static inline int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size)
	return __ixgbe_maybe_stop_tx(tx_ring, size);
}

#ifdef IXGBE_FCOE
static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb,
			      void *accel_priv)
{
	struct ixgbe_fwd_adapter *fwd_adapter = accel_priv;
#ifdef IXGBE_FCOE
	struct ixgbe_adapter *adapter;
	struct ixgbe_ring_feature *f;
	int txq;
#endif

	if (fwd_adapter)
		return skb->queue_mapping + fwd_adapter->tx_base_queue;

#ifdef IXGBE_FCOE

	/*
	 * only execute the code below if protocol is FCoE
@@ -6858,9 +6866,11 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
		txq -= f->indices;

	return txq + f->offset;
#else
	return __netdev_pick_tx(dev, skb);
#endif
}

#endif
netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
			  struct ixgbe_adapter *adapter,
			  struct ixgbe_ring *tx_ring)
@@ -7629,27 +7639,11 @@ static void ixgbe_fwd_del(struct net_device *pdev, void *priv)
	kfree(fwd_adapter);
}

static netdev_tx_t ixgbe_fwd_xmit(struct sk_buff *skb,
				  struct net_device *dev,
				  void *priv)
{
	struct ixgbe_fwd_adapter *fwd_adapter = priv;
	unsigned int queue;
	struct ixgbe_ring *tx_ring;

	queue = skb->queue_mapping + fwd_adapter->tx_base_queue;
	tx_ring = fwd_adapter->real_adapter->tx_ring[queue];

	return __ixgbe_xmit_frame(skb, dev, tx_ring);
}

static const struct net_device_ops ixgbe_netdev_ops = {
	.ndo_open		= ixgbe_open,
	.ndo_stop		= ixgbe_close,
	.ndo_start_xmit		= ixgbe_xmit_frame,
#ifdef IXGBE_FCOE
	.ndo_select_queue	= ixgbe_select_queue,
#endif
	.ndo_set_rx_mode	= ixgbe_set_rx_mode,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address	= ixgbe_set_mac,
@@ -7689,7 +7683,6 @@ static const struct net_device_ops ixgbe_netdev_ops = {
	.ndo_bridge_getlink	= ixgbe_ndo_bridge_getlink,
	.ndo_dfwd_add_station	= ixgbe_fwd_add,
	.ndo_dfwd_del_station	= ixgbe_fwd_del,
	.ndo_dfwd_start_xmit	= ixgbe_fwd_xmit,
};

/**
Loading