Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next v5 2/2] net: thunderx: add timestamping support
From: Joe Perches @ 2017-12-12 19:47 UTC (permalink / raw)
  To: Richard Cochran, Aleksey Makarov
  Cc: netdev, linux-arm-kernel, linux-kernel, Goutham, Sunil,
	Radoslaw Biernacki, Robert Richter, David Daney,
	Philippe Ombredanne, Sunil Goutham
In-Reply-To: <20171211233641.cs7zdw34qkngicmj@localhost>

On Mon, 2017-12-11 at 15:36 -0800, Richard Cochran wrote:
> On Mon, Dec 11, 2017 at 05:14:31PM +0300, Aleksey Makarov wrote:
> > @@ -880,6 +889,46 @@ static void nic_pause_frame(struct nicpf *nic, int vf, struct pfc *cfg)
> >  	}
> >  }
> >  
> > +/* Enable or disable HW timestamping by BGX for pkts received on a LMAC */
> > +static void nic_config_timestamp(struct nicpf *nic, int vf, struct set_ptp *ptp)
> > +{
> > +	struct pkind_cfg *pkind;
> > +	u8 lmac, bgx_idx;
> > +	u64 pkind_val, pkind_idx;
> > +
> > +	if (vf >= nic->num_vf_en)
> > +		return;
> > +
> > +	bgx_idx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
> > +	lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
> > +
> > +	pkind_idx = lmac + bgx_idx * MAX_LMAC_PER_BGX;
> > +	pkind_val = nic_reg_read(nic, NIC_PF_PKIND_0_15_CFG | (pkind_idx << 3));
> > +	pkind = (struct pkind_cfg *)&pkind_val;
> > +
> > +	if (ptp->enable && !pkind->hdr_sl) {
> > +		/* Skiplen to exclude 8byte timestamp while parsing pkt
> > +		 * If not configured, will result in L2 errors.
> > +		 */
> > +		pkind->hdr_sl = 4;
> > +		/* Adjust max packet length allowed */
> > +		pkind->maxlen += (pkind->hdr_sl * 2);

Are all compilers smart enough to set this to 8?
I rather doubt a compiler is even allowed to.

^ permalink raw reply

* Re: [RFC][PATCH] new byteorder primitives - ..._{replace,get}_bits()
From: Al Viro @ 2017-12-12 19:45 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: Linus Torvalds, netdev, linux-kernel
In-Reply-To: <20171212062002.GY21978@ZenIV.linux.org.uk>

On Tue, Dec 12, 2017 at 06:20:02AM +0000, Al Viro wrote:

> Umm...  What's wrong with
> 
> #define FIELD_FOO 0,4
> #define FIELD_BAR 6,12
> #define FIELD_BAZ 18,14
> 
> A macro can bloody well expand to any sequence of tokens - le32_get_bits(v, FIELD_BAZ)
> will become le32_get_bits(v, 18, 14) just fine.  What's the problem with that?

FWIW, if you want to use the mask, __builtin_ffsll() is not the only way to do
it - you don't need the shift.  Multiplier would do just as well, and that can
be had easier.  If mask = (2*a + 1)<<n = ((2*a)<<n) ^ (1<<n), then
	mask - 1 = ((2*a) << n) + ((1<<n) - 1) = ((2*n) << n) ^ ((1<<n) - 1)
	mask ^ (mask - 1) = (1<<n) + ((1<<n) - 1)
and
	mask & (mask ^ (mask - 1)) = 1<<n.

IOW, with

static __always_inline u64 mask_to_multiplier(u64 mask)
{
	return mask & (mask ^ (mask - 1));
}

we could do

static __always_inline __le64 le64_replace_bits(__le64 old, u64 v, u64 mask)
{
	__le64 m = cpu_to_le64(mask);
	return (old & ~m) | (cpu_to_le64(v * mask_to_multiplier(mask)) & m);
}

static __always_inline u64 le64_get_bits(__le64 v, u64 mask)
{
	return (le64_to_cpu(v) & mask) / mask_to_multiplier(mask);
}

etc.  Compiler will turn those into shifts...  I can live with either calling
conventions.

Comments?

^ permalink raw reply

* [PATCH net-next] cxgb4: Add support for ethtool i2c dump
From: Ganesh Goudar @ 2017-12-12 19:34 UTC (permalink / raw)
  To: netdev, davem
  Cc: nirranjan, indranil, venkatesh, Arjun Vynipadath, Casey Leedom,
	Ganesh Goudar

From: Arjun Vynipadath <arjun@chelsio.com>

Adds support for ethtool get_module_info() and get_module_eeprom()
callbacks that will dump necessary information for a SFP.

Signed-off-by: Arjun Vynipadath <arjun@chelsio.com>
Signed-off-by: Casey Leedom <leedom@chelsio.com>
Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4.h         | 18 ++++
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c | 97 ++++++++++++++++++++++
 drivers/net/ethernet/chelsio/cxgb4/t4_hw.c         | 56 +++++++++++++
 drivers/net/ethernet/chelsio/cxgb4/t4_hw.h         | 10 +++
 drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h      |  1 +
 5 files changed, 182 insertions(+)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 97dc3ef..b1df2aa 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -1424,6 +1424,21 @@ static inline void init_rspq(struct adapter *adap, struct sge_rspq *q,
 	q->size = size;
 }
 
+/**
+ *     t4_is_inserted_mod_type - is a plugged in Firmware Module Type
+ *     @fw_mod_type: the Firmware Mofule Type
+ *
+ *     Return whether the Firmware Module Type represents a real Transceiver
+ *     Module/Cable Module Type which has been inserted.
+ */
+static inline bool t4_is_inserted_mod_type(unsigned int fw_mod_type)
+{
+	return (fw_mod_type != FW_PORT_MOD_TYPE_NONE &&
+		fw_mod_type != FW_PORT_MOD_TYPE_NOTSUPPORTED &&
+		fw_mod_type != FW_PORT_MOD_TYPE_UNKNOWN &&
+		fw_mod_type != FW_PORT_MOD_TYPE_ERROR);
+}
+
 void t4_write_indirect(struct adapter *adap, unsigned int addr_reg,
 		       unsigned int data_reg, const u32 *vals,
 		       unsigned int nregs, unsigned int start_idx);
@@ -1697,6 +1712,9 @@ void t4_uld_mem_free(struct adapter *adap);
 int t4_uld_mem_alloc(struct adapter *adap);
 void t4_uld_clean_up(struct adapter *adap);
 void t4_register_netevent_notifier(void);
+int t4_i2c_rd(struct adapter *adap, unsigned int mbox, int port,
+	      unsigned int devid, unsigned int offset,
+	      unsigned int len, u8 *buf);
 void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq, struct sge_fl *fl);
 void free_tx_desc(struct adapter *adap, struct sge_txq *q,
 		  unsigned int n, bool unmap);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
index eb33821..541419b 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
@@ -1396,6 +1396,101 @@ static int get_dump_data(struct net_device *dev, struct ethtool_dump *eth_dump,
 	return 0;
 }
 
+static int cxgb4_get_module_info(struct net_device *dev,
+				 struct ethtool_modinfo *modinfo)
+{
+	struct port_info *pi = netdev_priv(dev);
+	u8 sff8472_comp, sff_diag_type, sff_rev;
+	struct adapter *adapter = pi->adapter;
+	int ret;
+
+	if (!t4_is_inserted_mod_type(pi->mod_type))
+		return -EINVAL;
+
+	switch (pi->port_type) {
+	case FW_PORT_TYPE_SFP:
+	case FW_PORT_TYPE_QSA:
+	case FW_PORT_TYPE_SFP28:
+		ret = t4_i2c_rd(adapter, adapter->mbox, pi->tx_chan,
+				I2C_DEV_ADDR_A0, SFF_8472_COMP_ADDR,
+				SFF_8472_COMP_LEN, &sff8472_comp);
+		if (ret)
+			return ret;
+		ret = t4_i2c_rd(adapter, adapter->mbox, pi->tx_chan,
+				I2C_DEV_ADDR_A0, SFP_DIAG_TYPE_ADDR,
+				SFP_DIAG_TYPE_LEN, &sff_diag_type);
+		if (ret)
+			return ret;
+
+		if (!sff8472_comp || (sff_diag_type & 4)) {
+			modinfo->type = ETH_MODULE_SFF_8079;
+			modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
+		} else {
+			modinfo->type = ETH_MODULE_SFF_8472;
+			modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
+		}
+		break;
+
+	case FW_PORT_TYPE_QSFP:
+	case FW_PORT_TYPE_QSFP_10G:
+	case FW_PORT_TYPE_CR_QSFP:
+	case FW_PORT_TYPE_CR2_QSFP:
+	case FW_PORT_TYPE_CR4_QSFP:
+		ret = t4_i2c_rd(adapter, adapter->mbox, pi->tx_chan,
+				I2C_DEV_ADDR_A0, SFF_REV_ADDR,
+				SFF_REV_LEN, &sff_rev);
+		/* For QSFP type ports, revision value >= 3
+		 * means the SFP is 8636 compliant.
+		 */
+		if (ret)
+			return ret;
+		if (sff_rev >= 0x3) {
+			modinfo->type = ETH_MODULE_SFF_8636;
+			modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN;
+		} else {
+			modinfo->type = ETH_MODULE_SFF_8436;
+			modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
+		}
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int cxgb4_get_module_eeprom(struct net_device *dev,
+				   struct ethtool_eeprom *eprom, u8 *data)
+{
+	int ret = 0, offset = eprom->offset, len = eprom->len;
+	struct port_info *pi = netdev_priv(dev);
+	struct adapter *adapter = pi->adapter;
+
+	memset(data, 0, eprom->len);
+	if (offset + len <= I2C_PAGE_SIZE)
+		return t4_i2c_rd(adapter, adapter->mbox, pi->tx_chan,
+				 I2C_DEV_ADDR_A0, offset, len, data);
+
+	/* offset + len spans 0xa0 and 0xa1 pages */
+	if (offset <= I2C_PAGE_SIZE) {
+		/* read 0xa0 page */
+		len = I2C_PAGE_SIZE - offset;
+		ret =  t4_i2c_rd(adapter, adapter->mbox, pi->tx_chan,
+				 I2C_DEV_ADDR_A0, offset, len, data);
+		if (ret)
+			return ret;
+		offset = I2C_PAGE_SIZE;
+		/* Remaining bytes to be read from second page =
+		 * Total length - bytes read from first page
+		 */
+		len = eprom->len - len;
+	}
+	/* Read additional optical diagnostics from page 0xa2 if supported */
+	return t4_i2c_rd(adapter, adapter->mbox, pi->tx_chan, I2C_DEV_ADDR_A2,
+			 offset, len, &data[eprom->len - len]);
+}
+
 static const struct ethtool_ops cxgb_ethtool_ops = {
 	.get_link_ksettings = get_link_ksettings,
 	.set_link_ksettings = set_link_ksettings,
@@ -1430,6 +1525,8 @@ static const struct ethtool_ops cxgb_ethtool_ops = {
 	.set_dump          = set_dump,
 	.get_dump_flag     = get_dump_flag,
 	.get_dump_data     = get_dump_data,
+	.get_module_info   = cxgb4_get_module_info,
+	.get_module_eeprom = cxgb4_get_module_eeprom,
 };
 
 void cxgb4_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 112963d..f044717 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -9743,3 +9743,59 @@ int t4_sched_params(struct adapter *adapter, int type, int level, int mode,
 	return t4_wr_mbox_meat(adapter, adapter->mbox, &cmd, sizeof(cmd),
 			       NULL, 1);
 }
+
+/**
+ *	t4_i2c_rd - read I2C data from adapter
+ *	@adap: the adapter
+ *	@port: Port number if per-port device; <0 if not
+ *	@devid: per-port device ID or absolute device ID
+ *	@offset: byte offset into device I2C space
+ *	@len: byte length of I2C space data
+ *	@buf: buffer in which to return I2C data
+ *
+ *	Reads the I2C data from the indicated device and location.
+ */
+int t4_i2c_rd(struct adapter *adap, unsigned int mbox, int port,
+	      unsigned int devid, unsigned int offset,
+	      unsigned int len, u8 *buf)
+{
+	struct fw_ldst_cmd ldst_cmd, ldst_rpl;
+	unsigned int i2c_max = sizeof(ldst_cmd.u.i2c.data);
+	int ret = 0;
+
+	if (len > I2C_PAGE_SIZE)
+		return -EINVAL;
+
+	/* Dont allow reads that spans multiple pages */
+	if (offset < I2C_PAGE_SIZE && offset + len > I2C_PAGE_SIZE)
+		return -EINVAL;
+
+	memset(&ldst_cmd, 0, sizeof(ldst_cmd));
+	ldst_cmd.op_to_addrspace =
+		cpu_to_be32(FW_CMD_OP_V(FW_LDST_CMD) |
+			    FW_CMD_REQUEST_F |
+			    FW_CMD_READ_F |
+			    FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_I2C));
+	ldst_cmd.cycles_to_len16 = cpu_to_be32(FW_LEN16(ldst_cmd));
+	ldst_cmd.u.i2c.pid = (port < 0 ? 0xff : port);
+	ldst_cmd.u.i2c.did = devid;
+
+	while (len > 0) {
+		unsigned int i2c_len = (len < i2c_max) ? len : i2c_max;
+
+		ldst_cmd.u.i2c.boffset = offset;
+		ldst_cmd.u.i2c.blen = i2c_len;
+
+		ret = t4_wr_mbox(adap, mbox, &ldst_cmd, sizeof(ldst_cmd),
+				 &ldst_rpl);
+		if (ret)
+			break;
+
+		memcpy(buf, ldst_rpl.u.i2c.data, i2c_len);
+		offset += i2c_len;
+		buf += i2c_len;
+		len -= i2c_len;
+	}
+
+	return ret;
+}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
index 83afb32c..872a91b 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
@@ -286,4 +286,14 @@ enum {
 #define SGE_TIMESTAMP_V(x) ((__u64)(x) << SGE_TIMESTAMP_S)
 #define SGE_TIMESTAMP_G(x) (((__u64)(x) >> SGE_TIMESTAMP_S) & SGE_TIMESTAMP_M)
 
+#define I2C_DEV_ADDR_A0		0xa0
+#define I2C_DEV_ADDR_A2		0xa2
+#define I2C_PAGE_SIZE		0x100
+#define SFP_DIAG_TYPE_ADDR	0x5c
+#define SFP_DIAG_TYPE_LEN	0x1
+#define SFF_8472_COMP_ADDR	0x5e
+#define SFF_8472_COMP_LEN	0x1
+#define SFF_REV_ADDR		0x1
+#define SFF_REV_LEN		0x1
+
 #endif /* __T4_HW_H */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
index 57eb4ad..01f5a5e 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
@@ -828,6 +828,7 @@ enum fw_ldst_addrspc {
 	FW_LDST_ADDRSPC_MPS       = 0x0020,
 	FW_LDST_ADDRSPC_FUNC      = 0x0028,
 	FW_LDST_ADDRSPC_FUNC_PCIE = 0x0029,
+	FW_LDST_ADDRSPC_I2C       = 0x0038,
 };
 
 enum fw_ldst_mps_fid {
-- 
2.1.0

^ permalink raw reply related

* [PATCH v3] igb: Free IRQs when device is hotplugged
From: Lyude Paul @ 2017-12-12 19:31 UTC (permalink / raw)
  To: intel-wired-lan
  Cc: Todd Fujinaka, Stephen Hemminger, stable, Jeff Kirsher, netdev,
	linux-kernel

Recently I got a Caldigit TS3 Thunderbolt 3 dock, and noticed that upon
hotplugging my kernel would immediately crash due to igb:

[  680.825801] kernel BUG at drivers/pci/msi.c:352!
[  680.828388] invalid opcode: 0000 [#1] SMP
[  680.829194] Modules linked in: igb(O) thunderbolt i2c_algo_bit joydev vfat fat btusb btrtl btbcm btintel bluetooth ecdh_generic hp_wmi sparse_keymap rfkill wmi_bmof iTCO_wdt intel_rapl x86_pkg_temp_thermal coretemp crc32_pclmul snd_pcm rtsx_pci_ms mei_me snd_timer memstick snd pcspkr mei soundcore i2c_i801 tpm_tis psmouse shpchp wmi tpm_tis_core tpm video hp_wireless acpi_pad rtsx_pci_sdmmc mmc_core crc32c_intel serio_raw rtsx_pci mfd_core xhci_pci xhci_hcd i2c_hid i2c_core [last unloaded: igb]
[  680.831085] CPU: 1 PID: 78 Comm: kworker/u16:1 Tainted: G           O     4.15.0-rc3Lyude-Test+ #6
[  680.831596] Hardware name: HP HP ZBook Studio G4/826B, BIOS P71 Ver. 01.03 06/09/2017
[  680.832168] Workqueue: kacpi_hotplug acpi_hotplug_work_fn
[  680.832687] RIP: 0010:free_msi_irqs+0x180/0x1b0
[  680.833271] RSP: 0018:ffffc9000030fbf0 EFLAGS: 00010286
[  680.833761] RAX: ffff8803405f9c00 RBX: ffff88033e3d2e40 RCX: 000000000000002c
[  680.834278] RDX: 0000000000000000 RSI: 00000000000000ac RDI: ffff880340be2178
[  680.834832] RBP: 0000000000000000 R08: ffff880340be1ff0 R09: ffff8803405f9c00
[  680.835342] R10: 0000000000000000 R11: 0000000000000040 R12: ffff88033d63a298
[  680.835822] R13: ffff88033d63a000 R14: 0000000000000060 R15: ffff880341959000
[  680.836332] FS:  0000000000000000(0000) GS:ffff88034f440000(0000) knlGS:0000000000000000
[  680.836817] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  680.837360] CR2: 000055e64044afdf CR3: 0000000001c09002 CR4: 00000000003606e0
[  680.837954] Call Trace:
[  680.838853]  pci_disable_msix+0xce/0xf0
[  680.839616]  igb_reset_interrupt_capability+0x5d/0x60 [igb]
[  680.840278]  igb_remove+0x9d/0x110 [igb]
[  680.840764]  pci_device_remove+0x36/0xb0
[  680.841279]  device_release_driver_internal+0x157/0x220
[  680.841739]  pci_stop_bus_device+0x7d/0xa0
[  680.842255]  pci_stop_bus_device+0x2b/0xa0
[  680.842722]  pci_stop_bus_device+0x3d/0xa0
[  680.843189]  pci_stop_and_remove_bus_device+0xe/0x20
[  680.843627]  trim_stale_devices+0xf3/0x140
[  680.844086]  trim_stale_devices+0x94/0x140
[  680.844532]  trim_stale_devices+0xa6/0x140
[  680.845031]  ? get_slot_status+0x90/0xc0
[  680.845536]  acpiphp_check_bridge.part.5+0xfe/0x140
[  680.846021]  acpiphp_hotplug_notify+0x175/0x200
[  680.846581]  ? free_bridge+0x100/0x100
[  680.847113]  acpi_device_hotplug+0x8a/0x490
[  680.847535]  acpi_hotplug_work_fn+0x1a/0x30
[  680.848076]  process_one_work+0x182/0x3a0
[  680.848543]  worker_thread+0x2e/0x380
[  680.848963]  ? process_one_work+0x3a0/0x3a0
[  680.849373]  kthread+0x111/0x130
[  680.849776]  ? kthread_create_worker_on_cpu+0x50/0x50
[  680.850188]  ret_from_fork+0x1f/0x30
[  680.850601] Code: 43 14 85 c0 0f 84 d5 fe ff ff 31 ed eb 0f 83 c5 01 39 6b 14 0f 86 c5 fe ff ff 8b 7b 10 01 ef e8 b7 e4 d2 ff 48 83 78 70 00 74 e3 <0f> 0b 49 8d b5 a0 00 00 00 e8 62 6f d3 ff e9 c7 fe ff ff 48 8b
[  680.851497] RIP: free_msi_irqs+0x180/0x1b0 RSP: ffffc9000030fbf0

As it turns out, normally the freeing of IRQs that would fix this is called
inside of the scope of __igb_close(). However, since the device is
already gone by the point we try to unregister the netdevice from the
driver due to a hotplug we end up seeing that the netif isn't present
and thus, forget to free any of the device IRQs.

So: make sure that if we're in the process of dismantling the netdev, we
always allow __igb_close() to be called so that IRQs may be freed
normally. Additionally, only allow igb_close() to be called from
__igb_close() if it hasn't already been called for the given adapter.

Signed-off-by: Lyude Paul <lyude@redhat.com>
Fixes: 9474933caf21 ("igb: close/suspend race in netif_device_detach")
Cc: Todd Fujinaka <todd.fujinaka@intel.com>
Cc: Stephen Hemminger <stephen@networkplumber.org>
Cc: stable@vger.kernel.org
---
Changes since v2:
  - Remove hunk in __igb_close() that was left over by accident, it's
    not needed

 drivers/net/ethernet/intel/igb/igb_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index c208753ff5b7..c69a5b3ae8c8 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -3676,7 +3676,7 @@ static int __igb_close(struct net_device *netdev, bool suspending)
 
 int igb_close(struct net_device *netdev)
 {
-	if (netif_device_present(netdev))
+	if (netif_device_present(netdev) || netdev->dismantle)
 		return __igb_close(netdev, false);
 	return 0;
 }
-- 
2.14.3

^ permalink raw reply related

* Re: [PATCH] veth: Optionally pad packets to minimum Ethernet length
From: Ed Swierk @ 2017-12-12 19:00 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Marcelo Ricardo Leitner, Dan Williams, netdev, Benjamin Warren,
	Keith Holleman
In-Reply-To: <20171212103423.508ad7c9@xeon-e3>

On Tue, Dec 12, 2017 at 10:34 AM, Stephen Hemminger
<stephen@networkplumber.org> wrote:
> Why not add to netdevsim rather than cluttering up a normal driver
> with test support.  We just pulled a bunch of test stuff out of dummy
> for the same reason.

My test setup to trigger an openvswitch conntrack issue
(https://marc.info/?l=linux-netdev&m=151309548725627) involves a lot
of moving parts:

[netns-a: vetha1] - [vetha0] - [ovsbr0] - [vethb0] - [netns-b: vethb1]

with nc client and server in netns-a and -b, and tweaks like turning
off tcp_timestamps to make sure the packets in the TCP stream are
small enough to reproduce the problem. A simpler, less fragile test
setup would be valuable, especially if it ends up as an automated
regression test.

Could netdevsim be useful for that? Are there any existing tests
producing TCP traffic that might serve as an example?

--Ed

^ permalink raw reply

* Re: [PATCH] veth: Optionally pad packets to minimum Ethernet length
From: Stephen Hemminger @ 2017-12-12 18:34 UTC (permalink / raw)
  To: Marcelo Ricardo Leitner
  Cc: Dan Williams, Ed Swierk, netdev, Benjamin Warren, Keith Holleman
In-Reply-To: <20171212181817.GB3531@localhost.localdomain>

On Tue, 12 Dec 2017 16:18:17 -0200
Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> wrote:

> On Tue, Dec 12, 2017 at 11:32:46AM -0600, Dan Williams wrote:
> > On Tue, 2017-12-12 at 08:13 -0800, Ed Swierk wrote:  
> > > Most physical Ethernet devices pad short packets to the minimum
> > > length
> > > of 64 bytes (including FCS) on transmit. It can be useful to simulate
> > > this behavior when debugging a problem that results from it (such as
> > > incorrect L4 checksum calculation).
> > > 
> > > Padding is unnecessary for most applications so leave it off by
> > > default. Enable padding only when the otherwise unused IFF_AUTOMEDIA
> > > flag is set (e.g. by writing 0x5003 to flags in sysfs).  
> > 
> > This seems like a weird overload of AUTOMEDIA, which no other driver
> > uses for this purpose.  Seems like the only other user of AUTOMEDIA is
> > 8390/etherh.c for some 10BaseT/10Base2 stuff.
> > 
> > I'm not sure what the interface should be, but perhaps a sysfs
> > attribute would be better than overloading IFF_AUTOMEDIA?  
> 
> What about using some tc action (i.e. skbmod) for this?
> 
>   Marcelo

Why not add to netdevsim rather than cluttering up a normal driver
with test support.  We just pulled a bunch of test stuff out of dummy
for the same reason.  

^ permalink raw reply

* [PATCH net] skge: remove redundunt free_irq under spinlock
From: Stephen Hemminger @ 2017-12-12 18:30 UTC (permalink / raw)
  To: davem; +Cc: netdev, Stephen Hemminger, Stephen Hemminger

The code to handle multi-port SKGE boards was freeing IRQ
twice. The first one was under lock and might sleep.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
Given that multi-port SKGE devices are very old and unlikely
to still be in use. This patch does not need to go to stable.

 drivers/net/ethernet/marvell/skge.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c
index 6e423f098a60..31efc47c847e 100644
--- a/drivers/net/ethernet/marvell/skge.c
+++ b/drivers/net/ethernet/marvell/skge.c
@@ -4081,7 +4081,6 @@ static void skge_remove(struct pci_dev *pdev)
 	if (hw->ports > 1) {
 		skge_write32(hw, B0_IMSK, 0);
 		skge_read32(hw, B0_IMSK);
-		free_irq(pdev->irq, hw);
 	}
 	spin_unlock_irq(&hw->hw_lock);
 
-- 
2.11.0

^ permalink raw reply related

* Re: [PATCH] drivers/staging/irda: fix max dup length for kstrndup
From: Stephen Hemminger @ 2017-12-12 18:27 UTC (permalink / raw)
  To: Ma Shimiao; +Cc: samuel, netdev, linux-kernel
In-Reply-To: <20171212085444.15901-1-mashimiao.fnst@cn.fujitsu.com>

On Tue, 12 Dec 2017 16:54:44 +0800
Ma Shimiao <mashimiao.fnst@cn.fujitsu.com> wrote:

> If source string longer than max, kstrndup will alloc max+1 space.
> So, we should make sure the result will not over limit.
> 
> Signed-off-by: Ma Shimiao <mashimiao.fnst@cn.fujitsu.com>

Did you read the TODO file in drivers/staging/irda?
	
	The irda code will be removed soon from the kernel tree as it is old and
	obsolete and broken.

	Don't worry about fixing up anything here, it's not needed.

^ permalink raw reply

* Re: [RFC PATCH] reuseport: compute the ehash only if needed
From: Paolo Abeni @ 2017-12-12 18:25 UTC (permalink / raw)
  To: Craig Gallek; +Cc: netdev, David S. Miller, Eric Dumazet
In-Reply-To: <CAEfhGiwOrpkKJWXgdesFS=OUjOmr4BmUCRVFJy32G-N_g2+SGw@mail.gmail.com>

Hi,
On Tue, 2017-12-12 at 12:44 -0500, Craig Gallek wrote:
> On Tue, Dec 12, 2017 at 8:09 AM, Paolo Abeni <pabeni@redhat.com> wrote:
> > When a reuseport socket group is using a BPF filter to distribute
> > the packets among the sockets, we don't need to compute any hash
> > value, but the current reuseport_select_sock() requires the
> > caller to compute such hash in advance.
> > 
> > This patch reworks reuseport_select_sock() to compute the hash value
> > only if needed - missing or failing BPF filter. Since different
> > hash functions have different argument types - ipv4 addresses vs ipv6
> > ones - to avoid over-complicate the interface, reuseport_select_sock()
> > is now a macro.
> 
> Purely subjective, but I think a slightly more complicated function
> signature for reuseport_select_sock (and reuseport_select_sock6?)
> would look a little better than this macro.  It would avoid needing to
> expose the reuseport_info struct and would keep the rcu semantics
> entirely within the function call (the fast-path memory access
> semantics here are already non-trivial...)

Thanks for the feedback. 

I was in doubt about the macro, too. The downside of using explicit
functions is the very long argument list and the need of 2 separate
functions for ipv4 and ipv6.

> > Additionally, the sk_reuseport test is move inside reuseport_select_sock,
> > to avoid some code duplication.
> > 
> > Overall this gives small but measurable performance improvement
> > under UDP flood while using SO_REUSEPORT + BPF.
> 
> Exciting, do you have some specific numbers here?  I'd be interested
> in knowing what kinds of loads you end up seeing improvements for.

this are the numbers I collected so far:

(ipv4)
socks nr 	vanilla(kpps)	patched(kpps)
1		1747		1843
2		3109		3140
3		4480		4534
4		5796		5864
5		7063		7139
6		8168		8235

(ipv6)
socks nr 	vanilla(kpps)	patched(kpps)
1		1433		1544
2		2537		2731
3		3622		3794
4		4689		4979
5		5738		6011
6		6671		6920

Cheers,

Paolo

^ permalink raw reply

* Re: [BUG] skge: a possible sleep-in-atomic bug in skge_remove
From: Stephen Hemminger @ 2017-12-12 18:22 UTC (permalink / raw)
  To: David Miller
  Cc: baijiaju1990, mlindner, shemminger, shemminger, netdev,
	linux-kernel
In-Reply-To: <20171212.083445.2256119006373036925.davem@davemloft.net>

On Tue, 12 Dec 2017 08:34:45 -0500 (EST)
David Miller <davem@davemloft.net> wrote:

> From: Jia-Ju Bai <baijiaju1990@gmail.com>
> Date: Tue, 12 Dec 2017 16:38:12 +0800
> 
> > According to drivers/net/ethernet/marvell/skge.c, the driver may sleep
> > under a spinlock.
> > The function call path is:
> > skge_remove (acquire the spinlock)
> >   free_irq --> may sleep
> > 
> > I do not find a good way to fix it, so I only report.
> > This possible bug is found by my static analysis tool (DSAC) and
> > checked by my code review.  
> 
> This was added by:
> 
> commit a9e9fd7182332d0cf5f3e601df3e71dd431b70d7
> Author: Stephen Hemminger <shemminger@vyatta.com>
> Date:   Tue Sep 27 13:41:37 2011 -0400
> 
>     skge: handle irq better on single port card
> 
> I think the free_irq() can be moved below the unlock.
> 
> Stephen, please take a look.

The IRQ was being free twice.
How did you see it, I really doubt any multi-port SKGE cards
still exist.

^ permalink raw reply

* Re: [PATCH net-next] net: bridge: use rhashtable for fdbs
From: Nikolay Aleksandrov @ 2017-12-12 18:18 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, bridge, roopa, srn, davem
In-Reply-To: <20171212100224.1aa33a96@xeon-e3>

On 12/12/17 20:02, Stephen Hemminger wrote:
> On Tue, 12 Dec 2017 16:02:50 +0200
> Nikolay Aleksandrov <nikolay@cumulusnetworks.com> wrote:
> 
>> +		memcpy(__entry->addr, f->key.addr.addr, ETH_ALEN);
> 
> Maybe use ether_addr_copy() here?
> 

This is an unrelated cleanup, the code in question was already like that. I can post
a separate patch to turn these into ether_addr_copy().
 

^ permalink raw reply

* Re: [PATCH] veth: Optionally pad packets to minimum Ethernet length
From: Marcelo Ricardo Leitner @ 2017-12-12 18:18 UTC (permalink / raw)
  To: Dan Williams; +Cc: Ed Swierk, netdev, Benjamin Warren, Keith Holleman
In-Reply-To: <1513099966.26538.1.camel@redhat.com>

On Tue, Dec 12, 2017 at 11:32:46AM -0600, Dan Williams wrote:
> On Tue, 2017-12-12 at 08:13 -0800, Ed Swierk wrote:
> > Most physical Ethernet devices pad short packets to the minimum
> > length
> > of 64 bytes (including FCS) on transmit. It can be useful to simulate
> > this behavior when debugging a problem that results from it (such as
> > incorrect L4 checksum calculation).
> > 
> > Padding is unnecessary for most applications so leave it off by
> > default. Enable padding only when the otherwise unused IFF_AUTOMEDIA
> > flag is set (e.g. by writing 0x5003 to flags in sysfs).
> 
> This seems like a weird overload of AUTOMEDIA, which no other driver
> uses for this purpose.  Seems like the only other user of AUTOMEDIA is
> 8390/etherh.c for some 10BaseT/10Base2 stuff.
> 
> I'm not sure what the interface should be, but perhaps a sysfs
> attribute would be better than overloading IFF_AUTOMEDIA?

What about using some tc action (i.e. skbmod) for this?

  Marcelo

> 
> Dan
> 
> > Signed-off-by: Ed Swierk <eswierk@skyportsystems.com>
> > ---
> >  drivers/net/veth.c | 6 ++++++
> >  1 file changed, 6 insertions(+)
> > 
> > diff --git a/drivers/net/veth.c b/drivers/net/veth.c
> > index f5438d0978ca..292029bf4bb2 100644
> > --- a/drivers/net/veth.c
> > +++ b/drivers/net/veth.c
> > @@ -111,6 +111,12 @@ static netdev_tx_t veth_xmit(struct sk_buff
> > *skb, struct net_device *dev)
> >  		goto drop;
> >  	}
> >  
> > +	if (unlikely(dev->flags & IFF_AUTOMEDIA)) {
> > +		/* if eth_skb_pad returns an error the skb was freed
> > */
> > +		if (eth_skb_pad(skb))
> > +			goto drop;
> > +	}
> > +
> >  	if (likely(dev_forward_skb(rcv, skb) == NET_RX_SUCCESS)) {
> >  		struct pcpu_vstats *stats = this_cpu_ptr(dev-
> > >vstats);
> >  
> 

^ permalink raw reply

* Re: [PATCH net-next] net: bridge: use rhashtable for fdbs
From: Nikolay Aleksandrov @ 2017-12-12 18:16 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, bridge, roopa, srn, davem
In-Reply-To: <20171212100713.6c24c9c3@xeon-e3>

On 12/12/17 20:07, Stephen Hemminger wrote:
> On Tue, 12 Dec 2017 16:02:50 +0200
> Nikolay Aleksandrov <nikolay@cumulusnetworks.com> wrote:
> 
>> Before this patch the bridge used a fixed 256 element hash table which
>> was fine for small use cases (in my tests it starts to degrade
>> above 1000 entries), but it wasn't enough for medium or large
>> scale deployments. Modern setups have thousands of participants in a
>> single bridge, even only enabling vlans and adding a few thousand vlan
>> entries will cause a few thousand fdbs to be automatically inserted per
>> participating port. So we need to scale the fdb table considerably to
>> cope with modern workloads, and this patch converts it to use a
>> rhashtable for its operations thus improving the bridge scalability.
>> Tests show the following results (10 runs each), at up to 1000 entries
>> rhashtable is ~3% slower, at 2000 rhashtable is 30% faster, at 3000 it
>> is 2 times faster and at 30000 it is 50 times faster.
>> Obviously this happens because of the properties of the two constructs
>> and is expected, rhashtable keeps pretty much a constant time even with
>> 10000000 entries (tested), while the fixed hash table struggles
>> considerably even above 10000.
>> As a side effect this also reduces the net_bridge struct size from 3248
>> bytes to 1344 bytes. Also note that the key struct is 8 bytes.
>>
>> Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
>> ---
> 
> Thanks for doing this, it was on my list of things that never get done.
> 
> Some downsides:
>  * size of the FDB entry gets larger.

It does not, due to smp alignment of the write-heavy members we had a large
hole between cache line 1 and 2, the new 8 bytes fit perfectly and there are
still bytes left to use.

>  * you lost the ability to salt the hash (and rekey) which is important
>    for DDoS attacks

The hash is always salted (property of rhashtable) and in fact is better because
now the salt is generated for each rhashtable separately rather than having 1 global
salt for all bridge devices.

>  * being slower for small (<10 entries) also matters and is is a common
>    use case for containers.

I think they're pretty comparable in speed, the difference is negligible IMO.

^ permalink raw reply

* Re: [PATCH v2 net-next] net: ethernet: ti: cpdma: correct error handling for chan create
From: Grygorii Strashko @ 2017-12-12 18:16 UTC (permalink / raw)
  To: netdev, davem, linux-omap, linux-kernel
In-Reply-To: <20171212175012.GA27096@khorivan>



On 12/12/2017 11:50 AM, Ivan Khoronzhuk wrote:
> On Tue, Dec 12, 2017 at 11:08:51AM -0600, Grygorii Strashko wrote:
>>
>>
>> On 12/12/2017 10:35 AM, Ivan Khoronzhuk wrote:
>>> It's not correct to return NULL when that is actually an error and
>>> function returns errors in any other wrong case. In the same time,
>>> the cpsw driver and davinci emac doesn't check error case while
>>> creating channel and it can miss actual error. Also remove WARNs
>>> duplicated dev_err msgs.
>>>
>>> Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
>>> ---
>>>    drivers/net/ethernet/ti/cpsw.c          | 12 +++++++++---
>>>    drivers/net/ethernet/ti/davinci_cpdma.c |  2 +-
>>>    drivers/net/ethernet/ti/davinci_emac.c  |  9 +++++++--
>>>    3 files changed, 17 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
>>> index a60a378..3c85a08 100644
>>> --- a/drivers/net/ethernet/ti/cpsw.c
>>> +++ b/drivers/net/ethernet/ti/cpsw.c
>>> @@ -3065,10 +3065,16 @@ static int cpsw_probe(struct platform_device *pdev)
>>>    	}
>>>    
>>>    	cpsw->txv[0].ch = cpdma_chan_create(cpsw->dma, 0, cpsw_tx_handler, 0);
>>> +	if (IS_ERR(cpsw->txv[0].ch)) {
>>> +		dev_err(priv->dev, "error initializing tx dma channel\n");
>>> +		ret = PTR_ERR(cpsw->txv[0].ch);
>>> +		goto clean_dma_ret;
>>> +	}
>>> +
>>>    	cpsw->rxv[0].ch = cpdma_chan_create(cpsw->dma, 0, cpsw_rx_handler, 1);
>>> -	if (WARN_ON(!cpsw->rxv[0].ch || !cpsw->txv[0].ch)) {
>>> -		dev_err(priv->dev, "error initializing dma channels\n");
>>> -		ret = -ENOMEM;
>>> +	if (IS_ERR(cpsw->rxv[0].ch)) {
>>> +		dev_err(priv->dev, "error initializing rx dma channel\n");
>>> +		ret = PTR_ERR(cpsw->rxv[0].ch);
>>>    		goto clean_dma_ret;
>>>    	}
>>>    
>>> diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c
>>> index e4d6edf..6f9173f 100644
>>> --- a/drivers/net/ethernet/ti/davinci_cpdma.c
>>> +++ b/drivers/net/ethernet/ti/davinci_cpdma.c
>>> @@ -893,7 +893,7 @@ struct cpdma_chan *cpdma_chan_create(struct cpdma_ctlr *ctlr, int chan_num,
>>>    	chan_num = rx_type ? rx_chan_num(chan_num) : tx_chan_num(chan_num);
>>>    
>>>    	if (__chan_linear(chan_num) >= ctlr->num_chan)
>>> -		return NULL;
>>> +		return ERR_PTR(-EINVAL);
>>>    
>>>    	chan = devm_kzalloc(ctlr->dev, sizeof(*chan), GFP_KERNEL);
>>>    	if (!chan)
>>> diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
>>> index f58c0c6..3d4af64 100644
>>> --- a/drivers/net/ethernet/ti/davinci_emac.c
>>> +++ b/drivers/net/ethernet/ti/davinci_emac.c
>>> @@ -1870,10 +1870,15 @@ static int davinci_emac_probe(struct platform_device *pdev)
>>>    
>>>    	priv->txchan = cpdma_chan_create(priv->dma, EMAC_DEF_TX_CH,
>>>    					 emac_tx_handler, 0);
>>> +	if (WARN_ON(IS_ERR(priv->txchan))) {
>>
>> So, logically WARN_ON() should be removed in  davinci_emac.c also. Right?
> It doesn't have dev_err() duplicate, so not very.
> But would be better to replace them on dev_err() if no objection.
> 

right.

> 
>>
>>> +		rc = PTR_ERR(priv->txchan);
>>> +		goto no_cpdma_chan;
>>> +	}
>>> +
>>>    	priv->rxchan = cpdma_chan_create(priv->dma, EMAC_DEF_RX_CH,
>>>    					 emac_rx_handler, 1);
>>> -	if (WARN_ON(!priv->txchan || !priv->rxchan)) {
>>> -		rc = -ENOMEM;
>>> +	if (WARN_ON(IS_ERR(priv->rxchan))) {
>>> +		rc = PTR_ERR(priv->rxchan);
>>>    		goto no_cpdma_chan;
>>>    	}

-- 
regards,
-grygorii

^ permalink raw reply

* Re: [PATCH net-next] net: dsa: lan9303: Introduce lan9303_read_wait
From: Vivien Didelot @ 2017-12-12 18:08 UTC (permalink / raw)
  To: Egil Hjelmeland, andrew, f.fainelli, netdev, linux-kernel; +Cc: Egil Hjelmeland
In-Reply-To: <20171212175331.22599-1-privat@egil-hjelmeland.no>

Hi Egil,

Egil Hjelmeland <privat@egil-hjelmeland.no> writes:

> Simplify lan9303_indirect_phy_wait_for_completion()
> and lan9303_switch_wait_for_completion() by using a new function
> lan9303_read_wait()
>
> Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no>
> ---
>  drivers/net/dsa/lan9303-core.c | 59 +++++++++++++++++++-----------------------
>  1 file changed, 27 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
> index c1b004fa64d9..96ccce0939d3 100644
> --- a/drivers/net/dsa/lan9303-core.c
> +++ b/drivers/net/dsa/lan9303-core.c
> @@ -249,6 +249,29 @@ static int lan9303_read(struct regmap *regmap, unsigned int offset, u32 *reg)
>  	return -EIO;
>  }
>  
> +/* Wait a while until mask & reg == value. Otherwise return timeout. */
> +static int lan9303_read_wait(struct lan9303 *chip, int offset, int mask,
> +			     char value)
> +{
> +	int i;
> +
> +	for (i = 0; i < 25; i++) {
> +		u32 reg;
> +		int ret;
> +
> +		ret = lan9303_read(chip->regmap, offset, &reg);
> +		if (ret) {
> +			dev_err(chip->dev, "%s failed to read offset %d: %d\n",
> +				__func__, offset, ret);
> +			return ret;
> +		}
> +		if ((reg & mask) == value)
> +			return 0;

That is weird to mix int, u32 and char for mask checking. I suggest you
to use the u32 type as well for both mask and value.

Looking at how lan9303_read_wait is called, the value argument doesn't
seem necessary. You can directly return 0 if (!(reg & mask)).

> +		usleep_range(1000, 2000);
> +	}
> +	return -ETIMEDOUT;

A newline before the return statment would be appreciated.

> +}
> +
>  static int lan9303_virt_phy_reg_read(struct lan9303 *chip, int regnum)
>  {
>  	int ret;
> @@ -274,22 +297,8 @@ static int lan9303_virt_phy_reg_write(struct lan9303 *chip, int regnum, u16 val)
>  
>  static int lan9303_indirect_phy_wait_for_completion(struct lan9303 *chip)
>  {
> -	int ret, i;
> -	u32 reg;
> -
> -	for (i = 0; i < 25; i++) {
> -		ret = lan9303_read(chip->regmap, LAN9303_PMI_ACCESS, &reg);
> -		if (ret) {
> -			dev_err(chip->dev,
> -				"Failed to read pmi access status: %d\n", ret);
> -			return ret;
> -		}
> -		if (!(reg & LAN9303_PMI_ACCESS_MII_BUSY))
> -			return 0;
> -		usleep_range(1000, 2000);
> -	}
> -
> -	return -EIO;
> +	return lan9303_read_wait(chip, LAN9303_PMI_ACCESS,
> +				 LAN9303_PMI_ACCESS_MII_BUSY, 0);
>  }
>  
>  static int lan9303_indirect_phy_read(struct lan9303 *chip, int addr, int regnum)
> @@ -366,22 +375,8 @@ EXPORT_SYMBOL_GPL(lan9303_indirect_phy_ops);
>  
>  static int lan9303_switch_wait_for_completion(struct lan9303 *chip)
>  {
> -	int ret, i;
> -	u32 reg;
> -
> -	for (i = 0; i < 25; i++) {
> -		ret = lan9303_read(chip->regmap, LAN9303_SWITCH_CSR_CMD, &reg);
> -		if (ret) {
> -			dev_err(chip->dev,
> -				"Failed to read csr command status: %d\n", ret);
> -			return ret;
> -		}
> -		if (!(reg & LAN9303_SWITCH_CSR_CMD_BUSY))
> -			return 0;
> -		usleep_range(1000, 2000);
> -	}
> -
> -	return -EIO;
> +	return lan9303_read_wait(chip, LAN9303_SWITCH_CSR_CMD,
> +				 LAN9303_SWITCH_CSR_CMD_BUSY, 0);
>  }
>  
>  static int lan9303_write_switch_reg(struct lan9303 *chip, u16 regnum, u32 val)


Thanks,

        Vivien

^ permalink raw reply

* Re: [PATCH net-next] net: bridge: use rhashtable for fdbs
From: Stephen Hemminger @ 2017-12-12 18:07 UTC (permalink / raw)
  To: Nikolay Aleksandrov; +Cc: netdev, bridge, roopa, srn, davem
In-Reply-To: <1513087370-4791-1-git-send-email-nikolay@cumulusnetworks.com>

On Tue, 12 Dec 2017 16:02:50 +0200
Nikolay Aleksandrov <nikolay@cumulusnetworks.com> wrote:

> Before this patch the bridge used a fixed 256 element hash table which
> was fine for small use cases (in my tests it starts to degrade
> above 1000 entries), but it wasn't enough for medium or large
> scale deployments. Modern setups have thousands of participants in a
> single bridge, even only enabling vlans and adding a few thousand vlan
> entries will cause a few thousand fdbs to be automatically inserted per
> participating port. So we need to scale the fdb table considerably to
> cope with modern workloads, and this patch converts it to use a
> rhashtable for its operations thus improving the bridge scalability.
> Tests show the following results (10 runs each), at up to 1000 entries
> rhashtable is ~3% slower, at 2000 rhashtable is 30% faster, at 3000 it
> is 2 times faster and at 30000 it is 50 times faster.
> Obviously this happens because of the properties of the two constructs
> and is expected, rhashtable keeps pretty much a constant time even with
> 10000000 entries (tested), while the fixed hash table struggles
> considerably even above 10000.
> As a side effect this also reduces the net_bridge struct size from 3248
> bytes to 1344 bytes. Also note that the key struct is 8 bytes.
> 
> Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
> ---

Thanks for doing this, it was on my list of things that never get done.

Some downsides:
 * size of the FDB entry gets larger.
 * you lost the ability to salt the hash (and rekey) which is important
   for DDoS attacks
 * being slower for small (<10 entries) also matters and is is a common
   use case for containers.

^ permalink raw reply

* Re: [PATCH bpf 0/3] Misc BPF fixes
From: Alexei Starovoitov @ 2017-12-12 18:07 UTC (permalink / raw)
  To: Daniel Borkmann; +Cc: ast, netdev
In-Reply-To: <20171212012532.30268-1-daniel@iogearbox.net>

On Tue, Dec 12, 2017 at 02:25:29AM +0100, Daniel Borkmann wrote:
> Couple of outstanding fixes for BPF tree: 1) fixes a perf RB
> corruption, 2) and 3) fixes a few build issues from the recent
> bpf_perf_event.h uapi corrections. Thanks!

Applied, thanks Daniel!

^ permalink raw reply

* Re: [PATCH v6 2/3] sock: Move the socket inuse to namespace.
From: Cong Wang @ 2017-12-12 18:04 UTC (permalink / raw)
  To: Tonghao Zhang
  Cc: David Miller, Eric Dumazet, Willem de Bruijn, Pavel Emelyanov,
	Linux Kernel Network Developers
In-Reply-To: <1512918726-2731-2-git-send-email-xiangxia.m.yue@gmail.com>

On Sun, Dec 10, 2017 at 7:12 AM, Tonghao Zhang <xiangxia.m.yue@gmail.com> wrote:
> diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
> index b797832..6c191fb 100644
> --- a/net/core/net_namespace.c
> +++ b/net/core/net_namespace.c
> @@ -363,6 +363,13 @@ static struct net *net_alloc(void)
>         if (!net)
>                 goto out_free;
>
> +#ifdef CONFIG_PROC_FS
> +       net->core.sock_inuse = alloc_percpu(int);
> +       if (!net->core.sock_inuse) {
> +               kmem_cache_free(net_cachep, net);
> +               goto out_free;
> +       }
> +#endif
>         rcu_assign_pointer(net->gen, ng);
>  out:
>         return net;
> @@ -374,6 +381,9 @@ static struct net *net_alloc(void)
>
>  static void net_free(struct net *net)
>  {
> +#ifdef CONFIG_PROC_FS
> +       free_percpu(net->core.sock_inuse);
> +#endif
>         kfree(rcu_access_pointer(net->gen));
>         kmem_cache_free(net_cachep, net);
>  }

Putting socket code in net_namespace.c doesn't look good.

^ permalink raw reply

* Re: [PATCH net-next] net: bridge: use rhashtable for fdbs
From: Stephen Hemminger @ 2017-12-12 18:02 UTC (permalink / raw)
  To: Nikolay Aleksandrov; +Cc: netdev, bridge, roopa, srn, davem
In-Reply-To: <1513087370-4791-1-git-send-email-nikolay@cumulusnetworks.com>

On Tue, 12 Dec 2017 16:02:50 +0200
Nikolay Aleksandrov <nikolay@cumulusnetworks.com> wrote:

> +		memcpy(__entry->addr, f->key.addr.addr, ETH_ALEN);

Maybe use ether_addr_copy() here?

^ permalink raw reply

* Re: [PATCH net-next v2] ip6_vti: adjust vti mtu according to mtu of output device
From: Shannon Nelson @ 2017-12-12 17:53 UTC (permalink / raw)
  To: Alexey Kodanev, netdev; +Cc: Steffen Klassert, David Miller, Petr Vorel
In-Reply-To: <1513086812-24896-1-git-send-email-alexey.kodanev@oracle.com>

On 12/12/2017 5:53 AM, Alexey Kodanev wrote:
> LTP/udp6_ipsec_vti tests fail when sending large UDP datagrams that
> require fragmentation and the underlying device has MTU <= 1500. This
> happens because ip6_vti sets mtu to ETH_DATA_LEN and not updating it
> depending on a destination address or link parameter.
> 
> Further attempts to send UDP packets may succeed because pmtu gets
> updated on ICMPV6_PKT_TOOBIG in vti6_err().
> 
> Here is the example when the output device MTU is set to 9000:
> 
>    # ip a sh ltp_ns_veth2
>        ltp_ns_veth2@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 ...
>          inet 10.0.0.2/24 scope global ltp_ns_veth2
>          inet6 fd00::2/64 scope global
> 
>    # ip li add vti6 type vti6 local fd00::2 remote fd00::1
>    # ip li show vti6
>        vti6@NONE: <POINTOPOINT,NOARP> mtu 1500 ...
>          link/tunnel6 fd00::2 peer fd00::1
> 
> After the patch:
>    # ip li add vti6 type vti6 local fd00::2 remote fd00::1
>    # ip li show vti6
>        vti6@NONE: <POINTOPOINT,NOARP> mtu 8832 ...
>          link/tunnel6 fd00::2 peer fd00::1
> 
> Regarding ip_vti, it already tunes MTU with ip_tunnel_bind_dev().
> 
> Reported-by: Petr Vorel <pvorel@suse.cz>
> Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
> ---
> v2: * cleanup commit message issues (thanks to Shannon)

Acked-by: Shannon Nelson <shannon.nelson@oracle.com>

> 
>      * handle the case when we don't have route but have device parameter
> 
>      * cast new MTU to int and then check the maximum (tdev->mtu can be
>        less than dev->hard_header_len)
> 
> When changing the tunnel parameters, MTU can be updated as well... should
> we also check that parms 'link', 'laddr' or 'raddr' were actually changed
> in vti6_tnl_change() and/or IFLA_MTU wasn't set?
> 
>   net/ipv6/ip6_vti.c |   22 ++++++++++++++++++++++
>   1 files changed, 22 insertions(+), 0 deletions(-)
> 
> diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
> index dbb74f3..d4624c2 100644
> --- a/net/ipv6/ip6_vti.c
> +++ b/net/ipv6/ip6_vti.c
> @@ -626,6 +626,7 @@ static void vti6_link_config(struct ip6_tnl *t)
>   {
>   	struct net_device *dev = t->dev;
>   	struct __ip6_tnl_parm *p = &t->parms;
> +	struct net_device *tdev = NULL;
>   
>   	memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr));
>   	memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr));
> @@ -638,6 +639,27 @@ static void vti6_link_config(struct ip6_tnl *t)
>   		dev->flags |= IFF_POINTOPOINT;
>   	else
>   		dev->flags &= ~IFF_POINTOPOINT;
> +
> +	if (p->flags & IP6_TNL_F_CAP_XMIT) {
> +		int strict = (ipv6_addr_type(&p->raddr) &
> +			      (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL));
> +
> +		struct rt6_info *rt = rt6_lookup(t->net,
> +						 &p->raddr, &p->laddr,
> +						 p->link, strict);
> +
> +		if (rt)
> +			tdev = rt->dst.dev;
> +		ip6_rt_put(rt);
> +	}
> +
> +	if (!tdev && p->link)
> +		tdev = __dev_get_by_index(t->net, p->link);
> +
> +	if (tdev) {
> +		dev->mtu = max_t(int, tdev->mtu - dev->hard_header_len,
> +				 IPV6_MIN_MTU);
> +	}
>   }
>   
>   /**
> 

^ permalink raw reply

* Re: Huge memory leak with 4.15.0-rc2+
From: Paweł Staszewski @ 2017-12-12 17:57 UTC (permalink / raw)
  To: John Fastabend, Linux Kernel Network Developers
In-Reply-To: <bf914c95-02a3-e7bf-9831-e478e596e725@itcare.pl>



W dniu 2017-12-11 o 23:27, Paweł Staszewski pisze:
>
>
> W dniu 2017-12-11 o 23:15, John Fastabend pisze:
>> On 12/11/2017 01:48 PM, Paweł Staszewski wrote:
>>>
>>> W dniu 2017-12-11 o 22:23, Paweł Staszewski pisze:
>>>> Hi
>>>>
>>>>
>>>> I just upgraded some testing host to 4.15.0-rc2+ kernel
>>>>
>>>> And after some time of traffic processing - when traffic on all ports
>>>> reach about 3Mpps - memleak started.
>>>>
>>
>> [...]
>>
>>>> Some observations - when i disable tso on all cards there is more
>>>> memleak.
>>>>
>>>>
>>>>
>>>>
>>>>
>>> When traffic starts to drop - there is less and less memleak
>>> below link to memory usage graph:
>>> https://ibb.co/hU97kG
>>>
>>> And there is rising slab_unrecl - Amount of unreclaimable memory used
>>> for slab kernel allocations
>>>
>>>
>>> Forgot to add that im using hfsc and qdiscs like pfifo on classes.
>>>
>>>
>> Maybe some error case I missed in the qdisc patches I'm looking into
>> it.
>>
>> Thanks,
>> John
>>
>>
> This is how it looks like when corelated on graph - traffic vs mem
> https://ibb.co/njpkqG
>
> Typical hfsc class + qdisc:
> ### Client interface vlan1616
> tc qdisc del dev vlan1616 root
> tc qdisc add dev vlan1616 handle 1: root hfsc default 100
> tc class add dev vlan1616 parent 1: classid 1:100 hfsc ls m2 200Mbit 
> ul m2 200Mbit
> tc qdisc add dev vlan1616 parent 1:100 handle 100: pfifo limit 128
> ### End TM for client interface
> tc qdisc del dev vlan1616 ingress
> tc qdisc add dev vlan1616 handle ffff: ingress
> tc filter add dev vlan1616 parent ffff: protocol ip prio 50 u32 match 
> ip src 0.0.0.0/0 police rate 200Mbit burst 200M mtu 32k drop flowid 1:1
>
> And this is same for about 450 vlan interfaces
>
>
> Good thing is that compared to 4.14.3 i have about 5% less cpu load on 
> 4.15.0-rc2+
>
> When hfsc will be lockless or tbf - then it will be really huge 
> difference in cpu load on x86 when using traffic shaping - so really 
> good job John.
>
>
>
>

Yestarday changed kernel from
https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git

to

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?h=v4.15-rc3


And there is no memleak.
So yes probabbly lockless qdisc patches

^ permalink raw reply

* [PATCH net-next] net: dsa: lan9303: Introduce lan9303_read_wait
From: Egil Hjelmeland @ 2017-12-12 17:53 UTC (permalink / raw)
  To: andrew, vivien.didelot, f.fainelli, netdev, linux-kernel; +Cc: Egil Hjelmeland

Simplify lan9303_indirect_phy_wait_for_completion()
and lan9303_switch_wait_for_completion() by using a new function
lan9303_read_wait()

Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no>
---
 drivers/net/dsa/lan9303-core.c | 59 +++++++++++++++++++-----------------------
 1 file changed, 27 insertions(+), 32 deletions(-)

diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
index c1b004fa64d9..96ccce0939d3 100644
--- a/drivers/net/dsa/lan9303-core.c
+++ b/drivers/net/dsa/lan9303-core.c
@@ -249,6 +249,29 @@ static int lan9303_read(struct regmap *regmap, unsigned int offset, u32 *reg)
 	return -EIO;
 }
 
+/* Wait a while until mask & reg == value. Otherwise return timeout. */
+static int lan9303_read_wait(struct lan9303 *chip, int offset, int mask,
+			     char value)
+{
+	int i;
+
+	for (i = 0; i < 25; i++) {
+		u32 reg;
+		int ret;
+
+		ret = lan9303_read(chip->regmap, offset, &reg);
+		if (ret) {
+			dev_err(chip->dev, "%s failed to read offset %d: %d\n",
+				__func__, offset, ret);
+			return ret;
+		}
+		if ((reg & mask) == value)
+			return 0;
+		usleep_range(1000, 2000);
+	}
+	return -ETIMEDOUT;
+}
+
 static int lan9303_virt_phy_reg_read(struct lan9303 *chip, int regnum)
 {
 	int ret;
@@ -274,22 +297,8 @@ static int lan9303_virt_phy_reg_write(struct lan9303 *chip, int regnum, u16 val)
 
 static int lan9303_indirect_phy_wait_for_completion(struct lan9303 *chip)
 {
-	int ret, i;
-	u32 reg;
-
-	for (i = 0; i < 25; i++) {
-		ret = lan9303_read(chip->regmap, LAN9303_PMI_ACCESS, &reg);
-		if (ret) {
-			dev_err(chip->dev,
-				"Failed to read pmi access status: %d\n", ret);
-			return ret;
-		}
-		if (!(reg & LAN9303_PMI_ACCESS_MII_BUSY))
-			return 0;
-		usleep_range(1000, 2000);
-	}
-
-	return -EIO;
+	return lan9303_read_wait(chip, LAN9303_PMI_ACCESS,
+				 LAN9303_PMI_ACCESS_MII_BUSY, 0);
 }
 
 static int lan9303_indirect_phy_read(struct lan9303 *chip, int addr, int regnum)
@@ -366,22 +375,8 @@ EXPORT_SYMBOL_GPL(lan9303_indirect_phy_ops);
 
 static int lan9303_switch_wait_for_completion(struct lan9303 *chip)
 {
-	int ret, i;
-	u32 reg;
-
-	for (i = 0; i < 25; i++) {
-		ret = lan9303_read(chip->regmap, LAN9303_SWITCH_CSR_CMD, &reg);
-		if (ret) {
-			dev_err(chip->dev,
-				"Failed to read csr command status: %d\n", ret);
-			return ret;
-		}
-		if (!(reg & LAN9303_SWITCH_CSR_CMD_BUSY))
-			return 0;
-		usleep_range(1000, 2000);
-	}
-
-	return -EIO;
+	return lan9303_read_wait(chip, LAN9303_SWITCH_CSR_CMD,
+				 LAN9303_SWITCH_CSR_CMD_BUSY, 0);
 }
 
 static int lan9303_write_switch_reg(struct lan9303 *chip, u16 regnum, u32 val)
-- 
2.14.1

^ permalink raw reply related

* [PATCH V3 net-next 0/8] Hisilicon Network Subsystem 3 VF Ethernet Driver
From: Salil Mehta @ 2017-12-12 17:51 UTC (permalink / raw)
  To: davem
  Cc: salil.mehta, yisen.zhuang, lipeng321, mehta.salil.lnk, netdev,
	linux-kernel, linux-rdma, linuxarm

This patch-set contains the support of the HNS3 (Hisilicon Network Subsystem 3)
Virtual Function Ethernet driver for hip08 family of SoCs. The Physical Function
driver is already part of the Linux mainline. 

This VF driver has its Hardware Compatibility Layer and has commom/unified ENET
layer/client/ethtool code with the PF driver. It also has support of mailbox to
communicate with the HNS3 PF driver. The basic architecture of VF driver is
derivative of the PF driver. Just like PF driver, this driver is also PCI
Express based.

This driver is the ongoing development work and HNS3 VF Ethernet driver would be
incrementally enhanced with more new features.

High Level Architecture:

                     [ Ethtool ]
	                 | 
                 [ Ethernet Client ] ... [ RoCE Client ] 
                         |                     |           
                   [ HNAE Device ]             |________       
                         |                     |       |
    ---------------------------------------------      |
                                                       |
     [ HNAE3 Framework (Register/unregister) ]         |
                                                       |
    ---------------------------------------------      |
                         |                             |
                 [ VF HCLGE Layer ]                    |
                  |             |                      |
                  |             |                      |
                  |             |                      |
                  |     [ VF Mailbox (To PF via IMP) ] |                 
                  |             |                      |   
             [ IMP command Interface ]  [ IMP command Interface ]
                        |                              |
                        |                              |
           (A B O V E  R U N S  O N  G U E S T  S Y S T E M)
    -------------------------------------------------------------
              Q E M U / V F I O / K V M (on Host System)
    -------------------------------------------------------------
            HIP08  H A R D W A R E (limited to VF by SMMU)

   [ IMP/Mgmt Processor (hardware common to system/cmd based) ]


                Fig 1.   HNS3 Virtual Function Driver


                    

    	[ dcbnl ]  [ Ethtool ]
            |          |
   	[  Ethernet Client  ]  [ ODP/UIO Client ] . . .[ RoCE Client ]     
              |_____________________|                 |
                         |                   _________|        
                   [ HNAE Device ]           |        |
                         |                   |        |
    ---------------------------------------------     |
                                                      |
     [ HNAE3 Framework (Register/unregister) ]        |
                                                      |
    ---------------------------------------------     |
                         |                            |
                  [ HCLGE Layer ]                     |
         ________________|_________________           |
        |                |                 |          |
     [ DCB ]             |                 |          |
        |                |                 |          |
  [ Scheduler/Shaper ] [ MDIO ]      [ PF Mailbox ]   |
        |                |                 |          |
        |________________|_________________|          |     
                         |                            |
             [ IMP command Interface ]     [ IMP command Interface ] 
    ----------------------------------------------------------------
              HIP08  H A R D W A R E                  

  [ IMP/Mgmt Processor (hardware common to system/cmd based) ]


               Fig 2.    Existing HNS3 PF Driver (added with mailbox)


Change Log Summary:
Patch V3: Addressed SPDX change requested by Philippe Ombredanne
Patch V2: 1. Addressed some comments by David Miller.
	  2. Addressed some internal comments on various patches
Patch V1: Initial Submit


Salil Mehta (8):
  net: hns3: Add HNS3 VF IMP(Integrated Management Proc) cmd interface
  net: hns3: Add mailbox support to VF driver
  net: hns3: Add HNS3 VF HCL(Hardware Compatibility Layer) Support
  net: hns3: Add HNS3 VF driver to kernel build framework
  net: hns3: Unified HNS3 {VF|PF} Ethernet Driver for hip08 SoC
  net: hns3: Add mailbox support to PF driver
  net: hns3: Change PF to add ring-vect binding & resetQ to mailbox
  net: hns3: Add mailbox interrupt handling to PF driver

 drivers/net/ethernet/hisilicon/Kconfig             |   28 +-
 drivers/net/ethernet/hisilicon/hns3/Makefile       |    7 +
 drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h    |   88 ++
 drivers/net/ethernet/hisilicon/hns3/hnae3.c        |   14 +-
 drivers/net/ethernet/hisilicon/hns3/hnae3.h        |    7 +-
 .../hisilicon/hns3/{hns3pf => }/hns3_dcbnl.c       |    2 +-
 .../hisilicon/hns3/{hns3pf => }/hns3_enet.c        |    2 +
 .../hisilicon/hns3/{hns3pf => }/hns3_enet.h        |    0
 .../hisilicon/hns3/{hns3pf => }/hns3_ethtool.c     |   22 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/Makefile    |    8 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c    |  207 +--
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h    |   17 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c |  412 ++++++
 .../net/ethernet/hisilicon/hns3/hns3vf/Makefile    |    9 +
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c   |  344 +++++
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h   |  256 ++++
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  | 1491 ++++++++++++++++++++
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h  |  164 +++
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c   |  184 +++
 19 files changed, 3140 insertions(+), 122 deletions(-)
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
 rename drivers/net/ethernet/hisilicon/hns3/{hns3pf => }/hns3_dcbnl.c (97%)
 rename drivers/net/ethernet/hisilicon/hns3/{hns3pf => }/hns3_enet.c (99%)
 rename drivers/net/ethernet/hisilicon/hns3/{hns3pf => }/hns3_enet.h (100%)
 rename drivers/net/ethernet/hisilicon/hns3/{hns3pf => }/hns3_ethtool.c (97%)
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3vf/Makefile
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c

-- 
2.7.4

^ permalink raw reply

* [PATCH V3 net-next 8/8] net: hns3: Add mailbox interrupt handling to PF driver
From: Salil Mehta @ 2017-12-12 17:52 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: salil.mehta-hv44wF8Li93QT0dZR+AlfA,
	yisen.zhuang-hv44wF8Li93QT0dZR+AlfA,
	lipeng321-hv44wF8Li93QT0dZR+AlfA,
	mehta.salil.lnk-Re5JQEeQqe8AvxtiuMwx3w,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linuxarm-hv44wF8Li93QT0dZR+AlfA
In-Reply-To: <20171212175205.236-1-salil.mehta-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>

All PF mailbox events are conveyed through a common interrupt
(vector 0). This interrupt vector is shared by reset and mailbox.

This patch adds the handling of mailbox interrupt event and its
deferred processing in context to a separate mailbox task.

Signed-off-by: Salil Mehta <salil.mehta-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Signed-off-by: lipeng <lipeng321-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
---
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c    | 68 +++++++++++++++++++---
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h    |  8 ++-
 2 files changed, 68 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 3b1fc49..e97fd66 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -2227,6 +2227,12 @@ static int hclge_mac_init(struct hclge_dev *hdev)
 	return hclge_cfg_func_mta_filter(hdev, 0, hdev->accept_mta_mc);
 }
 
+static void hclge_mbx_task_schedule(struct hclge_dev *hdev)
+{
+	if (!test_and_set_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state))
+		schedule_work(&hdev->mbx_service_task);
+}
+
 static void hclge_reset_task_schedule(struct hclge_dev *hdev)
 {
 	if (!test_and_set_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state))
@@ -2372,9 +2378,18 @@ static void hclge_service_complete(struct hclge_dev *hdev)
 static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
 {
 	u32 rst_src_reg;
+	u32 cmdq_src_reg;
 
 	/* fetch the events from their corresponding regs */
 	rst_src_reg = hclge_read_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG);
+	cmdq_src_reg = hclge_read_dev(&hdev->hw, HCLGE_VECTOR0_CMDQ_SRC_REG);
+
+	/* Assumption: If by any chance reset and mailbox events are reported
+	 * together then we will only process reset event in this go and will
+	 * defer the processing of the mailbox events. Since, we would have not
+	 * cleared RX CMDQ event this time we would receive again another
+	 * interrupt from H/W just for the mailbox.
+	 */
 
 	/* check for vector0 reset event sources */
 	if (BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B) & rst_src_reg) {
@@ -2395,7 +2410,12 @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
 		return HCLGE_VECTOR0_EVENT_RST;
 	}
 
-	/* mailbox event sharing vector 0 interrupt would be placed here */
+	/* check for vector0 mailbox(=CMDQ RX) event source */
+	if (BIT(HCLGE_VECTOR0_RX_CMDQ_INT_B) & cmdq_src_reg) {
+		cmdq_src_reg &= ~BIT(HCLGE_VECTOR0_RX_CMDQ_INT_B);
+		*clearval = cmdq_src_reg;
+		return HCLGE_VECTOR0_EVENT_MBX;
+	}
 
 	return HCLGE_VECTOR0_EVENT_OTHER;
 }
@@ -2403,10 +2423,14 @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
 static void hclge_clear_event_cause(struct hclge_dev *hdev, u32 event_type,
 				    u32 regclr)
 {
-	if (event_type == HCLGE_VECTOR0_EVENT_RST)
+	switch (event_type) {
+	case HCLGE_VECTOR0_EVENT_RST:
 		hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG, regclr);
-
-	/* mailbox event sharing vector 0 interrupt would be placed here */
+		break;
+	case HCLGE_VECTOR0_EVENT_MBX:
+		hclge_write_dev(&hdev->hw, HCLGE_VECTOR0_CMDQ_SRC_REG, regclr);
+		break;
+	}
 }
 
 static void hclge_enable_vector(struct hclge_misc_vector *vector, bool enable)
@@ -2423,13 +2447,23 @@ static irqreturn_t hclge_misc_irq_handle(int irq, void *data)
 	hclge_enable_vector(&hdev->misc_vector, false);
 	event_cause = hclge_check_event_cause(hdev, &clearval);
 
-	/* vector 0 interrupt is shared with reset and mailbox source events.
-	 * For now, we are not handling mailbox events.
-	 */
+	/* vector 0 interrupt is shared with reset and mailbox source events.*/
 	switch (event_cause) {
 	case HCLGE_VECTOR0_EVENT_RST:
 		hclge_reset_task_schedule(hdev);
 		break;
+	case HCLGE_VECTOR0_EVENT_MBX:
+		/* If we are here then,
+		 * 1. Either we are not handling any mbx task and we are not
+		 *    scheduled as well
+		 *                        OR
+		 * 2. We could be handling a mbx task but nothing more is
+		 *    scheduled.
+		 * In both cases, we should schedule mbx task as there are more
+		 * mbx messages reported by this interrupt.
+		 */
+		hclge_mbx_task_schedule(hdev);
+
 	default:
 		dev_dbg(&hdev->pdev->dev,
 			"received unknown or unhandled event of vector0\n");
@@ -2708,6 +2742,21 @@ static void hclge_reset_service_task(struct work_struct *work)
 	clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state);
 }
 
+static void hclge_mailbox_service_task(struct work_struct *work)
+{
+	struct hclge_dev *hdev =
+		container_of(work, struct hclge_dev, mbx_service_task);
+
+	if (test_and_set_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state))
+		return;
+
+	clear_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state);
+
+	hclge_mbx_handler(hdev);
+
+	clear_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state);
+}
+
 static void hclge_service_task(struct work_struct *work)
 {
 	struct hclge_dev *hdev =
@@ -4815,6 +4864,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
 	timer_setup(&hdev->service_timer, hclge_service_timer, 0);
 	INIT_WORK(&hdev->service_task, hclge_service_task);
 	INIT_WORK(&hdev->rst_service_task, hclge_reset_service_task);
+	INIT_WORK(&hdev->mbx_service_task, hclge_mailbox_service_task);
 
 	/* Enable MISC vector(vector0) */
 	hclge_enable_vector(&hdev->misc_vector, true);
@@ -4823,6 +4873,8 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
 	set_bit(HCLGE_STATE_DOWN, &hdev->state);
 	clear_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state);
 	clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state);
+	clear_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state);
+	clear_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state);
 
 	pr_info("%s driver initialization finished.\n", HCLGE_DRIVER_NAME);
 	return 0;
@@ -4936,6 +4988,8 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev)
 		cancel_work_sync(&hdev->service_task);
 	if (hdev->rst_service_task.func)
 		cancel_work_sync(&hdev->rst_service_task);
+	if (hdev->mbx_service_task.func)
+		cancel_work_sync(&hdev->mbx_service_task);
 
 	if (mac->phydev)
 		mdiobus_unregister(mac->mdio_bus);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
index c7c9a28..fb043b5 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
@@ -92,6 +92,11 @@
 #define HCLGE_VECTOR0_CORERESET_INT_B	6
 #define HCLGE_VECTOR0_IMPRESET_INT_B	7
 
+/* Vector0 interrupt CMDQ event source register(RW) */
+#define HCLGE_VECTOR0_CMDQ_SRC_REG	0x27100
+/* CMDQ register bits for RX event(=MBX event) */
+#define HCLGE_VECTOR0_RX_CMDQ_INT_B	1
+
 enum HCLGE_DEV_STATE {
 	HCLGE_STATE_REINITING,
 	HCLGE_STATE_DOWN,
@@ -101,8 +106,8 @@ enum HCLGE_DEV_STATE {
 	HCLGE_STATE_SERVICE_SCHED,
 	HCLGE_STATE_RST_SERVICE_SCHED,
 	HCLGE_STATE_RST_HANDLING,
+	HCLGE_STATE_MBX_SERVICE_SCHED,
 	HCLGE_STATE_MBX_HANDLING,
-	HCLGE_STATE_MBX_IRQ,
 	HCLGE_STATE_MAX
 };
 
@@ -479,6 +484,7 @@ struct hclge_dev {
 	struct timer_list service_timer;
 	struct work_struct service_task;
 	struct work_struct rst_service_task;
+	struct work_struct mbx_service_task;
 
 	bool cur_promisc;
 	int num_alloc_vfs;	/* Actual number of VFs allocated */
-- 
2.7.4


--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH V3 net-next 7/8] net: hns3: Change PF to add ring-vect binding & resetQ to mailbox
From: Salil Mehta @ 2017-12-12 17:52 UTC (permalink / raw)
  To: davem
  Cc: salil.mehta, yisen.zhuang, lipeng321, mehta.salil.lnk, netdev,
	linux-kernel, linux-rdma, linuxarm
In-Reply-To: <20171212175205.236-1-salil.mehta@huawei.com>

This patch is required to support ring-vector binding and reset
of TQPs requested by the VF driver to the PF driver. Mailbox
handler is added with corresponding VF commands/messages to
handle the request.

Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
Signed-off-by: lipeng <lipeng321@huawei.com>
---
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c    | 138 +++++++--------------
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h    |   7 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 106 ++++++++++++++++
 3 files changed, 159 insertions(+), 92 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 980fcdf..3b1fc49 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -3256,49 +3256,48 @@ int hclge_rss_init_hw(struct hclge_dev *hdev)
 	return ret;
 }
 
-int hclge_map_vport_ring_to_vector(struct hclge_vport *vport, int vector_id,
-				   struct hnae3_ring_chain_node *ring_chain)
+int hclge_bind_ring_with_vector(struct hclge_vport *vport,
+				int vector_id, bool en,
+				struct hnae3_ring_chain_node *ring_chain)
 {
 	struct hclge_dev *hdev = vport->back;
-	struct hclge_ctrl_vector_chain_cmd *req;
 	struct hnae3_ring_chain_node *node;
 	struct hclge_desc desc;
-	int ret;
+	struct hclge_ctrl_vector_chain_cmd *req
+		= (struct hclge_ctrl_vector_chain_cmd *)desc.data;
+	enum hclge_cmd_status status;
+	enum hclge_opcode_type op;
+	u16 tqp_type_and_id;
 	int i;
 
-	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_ADD_RING_TO_VECTOR, false);
-
-	req = (struct hclge_ctrl_vector_chain_cmd *)desc.data;
+	op = en ? HCLGE_OPC_ADD_RING_TO_VECTOR : HCLGE_OPC_DEL_RING_TO_VECTOR;
+	hclge_cmd_setup_basic_desc(&desc, op, false);
 	req->int_vector_id = vector_id;
 
 	i = 0;
 	for (node = ring_chain; node; node = node->next) {
-		u16 type_and_id = 0;
-
-		hnae_set_field(type_and_id, HCLGE_INT_TYPE_M, HCLGE_INT_TYPE_S,
+		tqp_type_and_id = le16_to_cpu(req->tqp_type_and_id[i]);
+		hnae_set_field(tqp_type_and_id,  HCLGE_INT_TYPE_M,
+			       HCLGE_INT_TYPE_S,
 			       hnae_get_bit(node->flag, HNAE3_RING_TYPE_B));
-		hnae_set_field(type_and_id, HCLGE_TQP_ID_M, HCLGE_TQP_ID_S,
-			       node->tqp_index);
-		hnae_set_field(type_and_id, HCLGE_INT_GL_IDX_M,
-			       HCLGE_INT_GL_IDX_S,
-			       hnae_get_bit(node->flag, HNAE3_RING_TYPE_B));
-		req->tqp_type_and_id[i] = cpu_to_le16(type_and_id);
-		req->vfid = vport->vport_id;
-
+		hnae_set_field(tqp_type_and_id, HCLGE_TQP_ID_M,
+			       HCLGE_TQP_ID_S, node->tqp_index);
+		req->tqp_type_and_id[i] = cpu_to_le16(tqp_type_and_id);
 		if (++i >= HCLGE_VECTOR_ELEMENTS_PER_CMD) {
 			req->int_cause_num = HCLGE_VECTOR_ELEMENTS_PER_CMD;
+			req->vfid = vport->vport_id;
 
-			ret = hclge_cmd_send(&hdev->hw, &desc, 1);
-			if (ret) {
+			status = hclge_cmd_send(&hdev->hw, &desc, 1);
+			if (status) {
 				dev_err(&hdev->pdev->dev,
 					"Map TQP fail, status is %d.\n",
-					ret);
-				return ret;
+					status);
+				return -EIO;
 			}
 			i = 0;
 
 			hclge_cmd_setup_basic_desc(&desc,
-						   HCLGE_OPC_ADD_RING_TO_VECTOR,
+						   op,
 						   false);
 			req->int_vector_id = vector_id;
 		}
@@ -3306,21 +3305,21 @@ int hclge_map_vport_ring_to_vector(struct hclge_vport *vport, int vector_id,
 
 	if (i > 0) {
 		req->int_cause_num = i;
-
-		ret = hclge_cmd_send(&hdev->hw, &desc, 1);
-		if (ret) {
+		req->vfid = vport->vport_id;
+		status = hclge_cmd_send(&hdev->hw, &desc, 1);
+		if (status) {
 			dev_err(&hdev->pdev->dev,
-				"Map TQP fail, status is %d.\n", ret);
-			return ret;
+				"Map TQP fail, status is %d.\n", status);
+			return -EIO;
 		}
 	}
 
 	return 0;
 }
 
-static int hclge_map_handle_ring_to_vector(
-		struct hnae3_handle *handle, int vector,
-		struct hnae3_ring_chain_node *ring_chain)
+static int hclge_map_ring_to_vector(struct hnae3_handle *handle,
+				    int vector,
+				    struct hnae3_ring_chain_node *ring_chain)
 {
 	struct hclge_vport *vport = hclge_get_vport(handle);
 	struct hclge_dev *hdev = vport->back;
@@ -3329,24 +3328,20 @@ static int hclge_map_handle_ring_to_vector(
 	vector_id = hclge_get_vector_index(hdev, vector);
 	if (vector_id < 0) {
 		dev_err(&hdev->pdev->dev,
-			"Get vector index fail. ret =%d\n", vector_id);
+			"Get vector index fail. vector_id =%d\n", vector_id);
 		return vector_id;
 	}
 
-	return hclge_map_vport_ring_to_vector(vport, vector_id, ring_chain);
+	return hclge_bind_ring_with_vector(vport, vector_id, true, ring_chain);
 }
 
-static int hclge_unmap_ring_from_vector(
-	struct hnae3_handle *handle, int vector,
-	struct hnae3_ring_chain_node *ring_chain)
+static int hclge_unmap_ring_frm_vector(struct hnae3_handle *handle,
+				       int vector,
+				       struct hnae3_ring_chain_node *ring_chain)
 {
 	struct hclge_vport *vport = hclge_get_vport(handle);
 	struct hclge_dev *hdev = vport->back;
-	struct hclge_ctrl_vector_chain_cmd *req;
-	struct hnae3_ring_chain_node *node;
-	struct hclge_desc desc;
-	int i, vector_id;
-	int ret;
+	int vector_id, ret;
 
 	vector_id = hclge_get_vector_index(hdev, vector);
 	if (vector_id < 0) {
@@ -3355,54 +3350,17 @@ static int hclge_unmap_ring_from_vector(
 		return vector_id;
 	}
 
-	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_DEL_RING_TO_VECTOR, false);
-
-	req = (struct hclge_ctrl_vector_chain_cmd *)desc.data;
-	req->int_vector_id = vector_id;
-
-	i = 0;
-	for (node = ring_chain; node; node = node->next) {
-		u16 type_and_id = 0;
-
-		hnae_set_field(type_and_id, HCLGE_INT_TYPE_M, HCLGE_INT_TYPE_S,
-			       hnae_get_bit(node->flag, HNAE3_RING_TYPE_B));
-		hnae_set_field(type_and_id, HCLGE_TQP_ID_M, HCLGE_TQP_ID_S,
-			       node->tqp_index);
-		hnae_set_field(type_and_id, HCLGE_INT_GL_IDX_M,
-			       HCLGE_INT_GL_IDX_S,
-			       hnae_get_bit(node->flag, HNAE3_RING_TYPE_B));
-
-		req->tqp_type_and_id[i] = cpu_to_le16(type_and_id);
-		req->vfid = vport->vport_id;
-
-		if (++i >= HCLGE_VECTOR_ELEMENTS_PER_CMD) {
-			req->int_cause_num = HCLGE_VECTOR_ELEMENTS_PER_CMD;
-
-			ret = hclge_cmd_send(&hdev->hw, &desc, 1);
-			if (ret) {
-				dev_err(&hdev->pdev->dev,
-					"Unmap TQP fail, status is %d.\n",
-					ret);
-				return ret;
-			}
-			i = 0;
-			hclge_cmd_setup_basic_desc(&desc,
-						   HCLGE_OPC_DEL_RING_TO_VECTOR,
-						   false);
-			req->int_vector_id = vector_id;
-		}
+	ret = hclge_bind_ring_with_vector(vport, vector_id, false, ring_chain);
+	if (ret) {
+		dev_err(&handle->pdev->dev,
+			"Unmap ring from vector fail. vectorid=%d, ret =%d\n",
+			vector_id,
+			ret);
+		return ret;
 	}
 
-	if (i > 0) {
-		req->int_cause_num = i;
-
-		ret = hclge_cmd_send(&hdev->hw, &desc, 1);
-		if (ret) {
-			dev_err(&hdev->pdev->dev,
-				"Unmap TQP fail, status is %d.\n", ret);
-			return ret;
-		}
-	}
+	/* Free this MSIX or MSI vector */
+	hclge_free_vector(hdev, vector_id);
 
 	return 0;
 }
@@ -4423,7 +4381,7 @@ static int hclge_get_reset_status(struct hclge_dev *hdev, u16 queue_id)
 	return hnae_get_bit(req->ready_to_reset, HCLGE_TQP_RESET_B);
 }
 
-static void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
+void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
 {
 	struct hclge_vport *vport = hclge_get_vport(handle);
 	struct hclge_dev *hdev = vport->back;
@@ -4995,8 +4953,8 @@ static const struct hnae3_ae_ops hclge_ops = {
 	.uninit_ae_dev = hclge_uninit_ae_dev,
 	.init_client_instance = hclge_init_client_instance,
 	.uninit_client_instance = hclge_uninit_client_instance,
-	.map_ring_to_vector = hclge_map_handle_ring_to_vector,
-	.unmap_ring_from_vector = hclge_unmap_ring_from_vector,
+	.map_ring_to_vector = hclge_map_ring_to_vector,
+	.unmap_ring_from_vector = hclge_unmap_ring_frm_vector,
 	.get_vector = hclge_get_vector,
 	.set_promisc_mode = hclge_set_promisc_mode,
 	.set_loopback = hclge_set_loopback,
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
index 028817c..c7c9a28 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
@@ -539,8 +539,10 @@ int hclge_cfg_func_mta_filter(struct hclge_dev *hdev,
 			      u8 func_id,
 			      bool enable);
 struct hclge_vport *hclge_get_vport(struct hnae3_handle *handle);
-int hclge_map_vport_ring_to_vector(struct hclge_vport *vport, int vector,
-				   struct hnae3_ring_chain_node *ring_chain);
+int hclge_bind_ring_with_vector(struct hclge_vport *vport,
+				int vector_id, bool en,
+				struct hnae3_ring_chain_node *ring_chain);
+
 static inline int hclge_get_queue_id(struct hnae3_queue *queue)
 {
 	struct hclge_tqp *tqp = container_of(queue, struct hclge_tqp, q);
@@ -556,4 +558,5 @@ int hclge_buffer_alloc(struct hclge_dev *hdev);
 int hclge_rss_init_hw(struct hclge_dev *hdev);
 
 void hclge_mbx_handler(struct hclge_dev *hdev);
+void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id);
 #endif
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
index 5eb8fff..106f3142 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
@@ -81,6 +81,91 @@ static int hclge_send_mbx_msg(struct hclge_vport *vport, u8 *msg, u16 msg_len,
 	return status;
 }
 
+static void hclge_free_vector_ring_chain(struct hnae3_ring_chain_node *head)
+{
+	struct hnae3_ring_chain_node *chain_tmp, *chain;
+
+	chain = head->next;
+
+	while (chain) {
+		chain_tmp = chain->next;
+		kzfree(chain);
+		chain = chain_tmp;
+	}
+}
+
+/* hclge_get_ring_chain_from_mbx: get ring type & tqpid from mailbox message
+ * msg[0]: opcode
+ * msg[1]: <not relevant to this function>
+ * msg[2]: ring_num
+ * msg[3]: first ring type (TX|RX)
+ * msg[4]: first tqp id
+ * msg[5] ~ msg[14]: other ring type and tqp id
+ */
+static int hclge_get_ring_chain_from_mbx(
+			struct hclge_mbx_vf_to_pf_cmd *req,
+			struct hnae3_ring_chain_node *ring_chain,
+			struct hclge_vport *vport)
+{
+#define HCLGE_RING_NODE_VARIABLE_NUM		3
+#define HCLGE_RING_MAP_MBX_BASIC_MSG_NUM	3
+	struct hnae3_ring_chain_node *cur_chain, *new_chain;
+	int ring_num;
+	int i;
+
+	ring_num = req->msg[2];
+
+	hnae_set_bit(ring_chain->flag, HNAE3_RING_TYPE_B, req->msg[3]);
+	ring_chain->tqp_index =
+			hclge_get_queue_id(vport->nic.kinfo.tqp[req->msg[4]]);
+
+	cur_chain = ring_chain;
+
+	for (i = 1; i < ring_num; i++) {
+		new_chain = kzalloc(sizeof(*new_chain), GFP_KERNEL);
+		if (!new_chain)
+			goto err;
+
+		hnae_set_bit(new_chain->flag, HNAE3_RING_TYPE_B,
+			     req->msg[HCLGE_RING_NODE_VARIABLE_NUM * i +
+			     HCLGE_RING_MAP_MBX_BASIC_MSG_NUM]);
+
+		new_chain->tqp_index =
+		hclge_get_queue_id(vport->nic.kinfo.tqp
+			[req->msg[HCLGE_RING_NODE_VARIABLE_NUM * i +
+			HCLGE_RING_MAP_MBX_BASIC_MSG_NUM + 1]]);
+
+		cur_chain->next = new_chain;
+		cur_chain = new_chain;
+	}
+
+	return 0;
+err:
+	hclge_free_vector_ring_chain(ring_chain);
+	return -ENOMEM;
+}
+
+static int hclge_map_unmap_ring_to_vf_vector(struct hclge_vport *vport, bool en,
+					     struct hclge_mbx_vf_to_pf_cmd *req)
+{
+	struct hnae3_ring_chain_node ring_chain;
+	int vector_id = req->msg[1];
+	int ret;
+
+	memset(&ring_chain, 0, sizeof(ring_chain));
+	ret = hclge_get_ring_chain_from_mbx(req, &ring_chain, vport);
+	if (ret)
+		return ret;
+
+	ret = hclge_bind_ring_with_vector(vport, vector_id, en, &ring_chain);
+	if (ret)
+		return ret;
+
+	hclge_free_vector_ring_chain(&ring_chain);
+
+	return 0;
+}
+
 static int hclge_set_vf_promisc_mode(struct hclge_vport *vport,
 				     struct hclge_mbx_vf_to_pf_cmd *req)
 {
@@ -226,6 +311,16 @@ static int hclge_get_link_info(struct hclge_vport *vport,
 				  HCLGE_MBX_LINK_STAT_CHANGE, dest_vfid);
 }
 
+static void hclge_reset_vf_queue(struct hclge_vport *vport,
+				 struct hclge_mbx_vf_to_pf_cmd *mbx_req)
+{
+	u16 queue_id;
+
+	memcpy(&queue_id, &mbx_req->msg[0], sizeof(queue_id));
+
+	hclge_reset_tqp(&vport->nic, queue_id);
+}
+
 void hclge_mbx_handler(struct hclge_dev *hdev)
 {
 	struct hclge_cmq_ring *crq = &hdev->hw.cmq.crq;
@@ -243,6 +338,14 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
 		vport = &hdev->vport[req->mbx_src_vfid];
 
 		switch (req->msg[0]) {
+		case HCLGE_MBX_MAP_RING_TO_VECTOR:
+			ret = hclge_map_unmap_ring_to_vf_vector(vport, true,
+								req);
+			break;
+		case HCLGE_MBX_UNMAP_RING_TO_VECTOR:
+			ret = hclge_map_unmap_ring_to_vf_vector(vport, false,
+								req);
+			break;
 		case HCLGE_MBX_SET_PROMISC_MODE:
 			ret = hclge_set_vf_promisc_mode(vport, req);
 			if (ret)
@@ -292,6 +395,9 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
 					"PF fail(%d) to get link stat for VF\n",
 					ret);
 			break;
+		case HCLGE_MBX_QUEUE_RESET:
+			hclge_reset_vf_queue(vport, req);
+			break;
 		default:
 			dev_err(&hdev->pdev->dev,
 				"un-supported mailbox message, code = %d\n",
-- 
2.7.4

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox