Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH openvswitch] netlink: Implement & enable memory mapped netlink i/o
From: Thomas Graf @ 2013-11-27 22:51 UTC (permalink / raw)
  To: Ben Pfaff
  Cc: dev-yBygre7rU0TnMu66kgdUjQ, netdev-u79uwXL29TY76Z2rM5mHXA,
	fleitner-H+wXaHxf7aLQT0dZR+AlfA
In-Reply-To: <20131125230253.GR1435-l0M0P4e3n4LQT0dZR+AlfA@public.gmane.org>

On 11/26/2013 12:02 AM, Ben Pfaff wrote:
> On Thu, Nov 21, 2013 at 07:16:54PM +0100, Thomas Graf wrote:
>> Based on the initial patch by Cong Wang posted a couple of months
>> ago.
>>
>> This is the user space counterpart needed for the kernel patch
>> '[PATCH net-next 3/8] openvswitch: Enable memory mapped Netlink i/o'
>>
>> Allows the kernel to construct Netlink messages on memory mapped
>> buffers and thus avoids copying. The functionality is enabled on
>> sockets used for unicast traffic.
>>
>> Further optimizations are possible by avoiding the copy into the
>> ofpbuf after reading.
>>
>> Cc: Cong Wang <xiyou.wangcong-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> Signed-off-by: Thomas Graf <tgraf-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>
> Does this depend on other patches or some specific Linux kernel
> headers?  It doesn't build here on GCC (similar results with Clang):

Yes, it depends on a sufficiently recent <linux/netlink.h>. We can
either #ifdef the mmap code or we provide a local copy of
<linux/netlink.h> in include/linux. The code automatically falls back if
the kernel does not support NL MMAP so that seems superior.

What do you prefer?

^ permalink raw reply

* Re: r8169 - it's dead jim
From: Francois Romieu @ 2013-11-27 23:14 UTC (permalink / raw)
  To: James Feeney; +Cc: Realtek and the Linux r8169 crew
In-Reply-To: <20131124005022.GA6299@electric-eye.fr.zoreil.com>

Francois Romieu <romieu@fr.zoreil.com> :
[...]
> You can try the genuinely untested hack below if you don't like current
> runtime suspend / resume behavior.

The patch is badly broken.

-- 
Ueimor

^ permalink raw reply

* [PATCH] pch_gbe: Fix transmit queue management
From: Ondrej Puzman @ 2013-11-27 23:29 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-kernel, Ondrej Puzman

According to Documentation/networking/driver.txt the ndo_start_xmit method should not return NETDEV_TX_BUSY under normal circumstances.
Stop the transmit queue when tx_ring is full.

Signed-off-by: Ondrej Puzman <puzman@gmail.com>
---
 .../net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c   |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 27ffe0e..6764e59 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -2157,6 +2157,10 @@ static int pch_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 
 	/* CRC,ITAG no support */
 	pch_gbe_tx_queue(adapter, tx_ring, skb);
+
+	if (unlikely(!PCH_GBE_DESC_UNUSED(tx_ring)))
+		netif_stop_queue(netdev);
+
 	spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
 	return NETDEV_TX_OK;
 }
-- 
1.5.6.5

^ permalink raw reply related

* [PATCH] pch_gbe: Remove tx_queue_len setting from the driver
From: Ondrej Puzman @ 2013-11-27 23:29 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-kernel, Ondrej Puzman
In-Reply-To: <1385594950-2662-1-git-send-email-puzman@gmail.com>

The driver should not touch netdev tx_queue_len when changing link speed.

Signed-off-by: Ondrej Puzman <puzman@gmail.com>
---
 drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h    |    2 --
 .../net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c   |    5 -----
 2 files changed, 0 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h
index 2a90030..f450d09 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h
@@ -615,7 +615,6 @@ struct pch_gbe_privdata {
  * @tx_ring:		Pointer of Tx descriptor ring structure
  * @rx_ring:		Pointer of Rx descriptor ring structure
  * @rx_buffer_len:	Receive buffer length
- * @tx_queue_len:	Transmit queue length
  * @have_msi:		PCI MSI mode flag
  * @pch_gbe_privdata:	PCI Device ID driver_data
  */
@@ -639,7 +638,6 @@ struct pch_gbe_adapter {
 	struct pch_gbe_tx_ring *tx_ring;
 	struct pch_gbe_rx_ring *rx_ring;
 	unsigned long rx_buffer_len;
-	unsigned long tx_queue_len;
 	bool have_msi;
 	bool rx_stop_flag;
 	int hwts_tx_en;
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 6764e59..d967603 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -1076,11 +1076,9 @@ static void pch_gbe_set_mode(struct pch_gbe_adapter *adapter, u16 speed,
 	switch (speed) {
 	case SPEED_10:
 		mode = PCH_GBE_MODE_MII_ETHER;
-		netdev->tx_queue_len = 10;
 		break;
 	case SPEED_100:
 		mode = PCH_GBE_MODE_MII_ETHER;
-		netdev->tx_queue_len = 100;
 		break;
 	case SPEED_1000:
 		mode = PCH_GBE_MODE_GMII_ETHER;
@@ -1108,7 +1106,6 @@ static void pch_gbe_watchdog(unsigned long data)
 	pch_gbe_update_stats(adapter);
 	if ((mii_link_ok(&adapter->mii)) && (!netif_carrier_ok(netdev))) {
 		struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
-		netdev->tx_queue_len = adapter->tx_queue_len;
 		/* mii library handles link maintenance tasks */
 		if (mii_ethtool_gset(&adapter->mii, &cmd)) {
 			netdev_err(netdev, "ethtool get setting Error\n");
@@ -1975,7 +1972,6 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter)
 	}
 	pch_gbe_alloc_tx_buffers(adapter, tx_ring);
 	pch_gbe_alloc_rx_buffers(adapter, rx_ring, rx_ring->count);
-	adapter->tx_queue_len = netdev->tx_queue_len;
 	pch_gbe_enable_dma_rx(&adapter->hw);
 	pch_gbe_enable_mac_rx(&adapter->hw);
 
@@ -2013,7 +2009,6 @@ void pch_gbe_down(struct pch_gbe_adapter *adapter)
 
 	del_timer_sync(&adapter->watchdog_timer);
 
-	netdev->tx_queue_len = adapter->tx_queue_len;
 	netif_carrier_off(netdev);
 	netif_stop_queue(netdev);
 
-- 
1.5.6.5

^ permalink raw reply related

* [PATCH] pch_gbe: Add DQL support to the driver
From: Ondrej Puzman @ 2013-11-27 23:29 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-kernel, Ondrej Puzman
In-Reply-To: <1385594950-2662-2-git-send-email-puzman@gmail.com>

Add dynamic queue limits support to the driver.

Signed-off-by: Ondrej Puzman <puzman@gmail.com>
---
 .../net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c   |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index d967603..2c14e2e 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -994,6 +994,8 @@ static void pch_gbe_clean_tx_ring(struct pch_gbe_adapter *adapter,
 	netdev_dbg(adapter->netdev,
 		   "call pch_gbe_unmap_and_free_tx_resource() %d count\n", i);
 
+	netdev_reset_queue(adapter->netdev);
+
 	size = (unsigned long)sizeof(struct pch_gbe_buffer) * tx_ring->count;
 	memset(tx_ring->buffer_info, 0, size);
 
@@ -1544,6 +1546,7 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter,
 	unsigned int cleaned_count = 0;
 	bool cleaned = false;
 	int unused, thresh;
+	unsigned int bytes_compl = 0, pkts_compl = 0;
 
 	netdev_dbg(adapter->netdev, "next_to_clean : %d\n",
 		   tx_ring->next_to_clean);
@@ -1622,6 +1625,8 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter,
 			buffer_info->mapped = false;
 		}
 		if (buffer_info->skb) {
+			bytes_compl += buffer_info->skb->len;
+			pkts_compl++;
 			netdev_dbg(adapter->netdev,
 				   "trim buffer_info->skb : %d\n", i);
 			skb_trim(buffer_info->skb, 0);
@@ -1641,6 +1646,9 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter,
 		   "called pch_gbe_unmap_and_free_tx_resource() %d count\n",
 		   cleaned_count);
 	if (cleaned_count > 0)  { /*skip this if nothing cleaned*/
+		netdev_completed_queue(adapter->netdev,
+				       pkts_compl, bytes_compl);
+
 		/* Recover from running out of Tx resources in xmit_frame */
 		spin_lock(&tx_ring->tx_lock);
 		if (unlikely(cleaned && (netif_queue_stopped(adapter->netdev))))
@@ -2152,6 +2160,7 @@ static int pch_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 
 	/* CRC,ITAG no support */
 	pch_gbe_tx_queue(adapter, tx_ring, skb);
+	netdev_sent_queue(netdev, skb->len);
 
 	if (unlikely(!PCH_GBE_DESC_UNUSED(tx_ring)))
 		netif_stop_queue(netdev);
-- 
1.5.6.5

^ permalink raw reply related

* [PATCH] pch_gbe: Fix: Link configuration in module parameters was ignored
From: Ondrej Puzman @ 2013-11-27 23:29 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-kernel, Ondrej Puzman
In-Reply-To: <1385594950-2662-3-git-send-email-puzman@gmail.com>

PHY configuration set in pch_gbe_phy_init_setting() by mii_ethtool_sset() was immedeiately reset by two calls of pch_gbe_phy_sw_reset().
Result of this bug was that module parameters like AutoNeg were ignored silently.

Signed-off-by: Ondrej Puzman <puzman@gmail.com>
---
 .../net/ethernet/oki-semi/pch_gbe/pch_gbe_api.c    |    4 ----
 .../net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.c    |   13 +------------
 .../net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.h    |    1 -
 3 files changed, 1 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_api.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_api.c
index ff3ad70..365c202 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_api.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_api.c
@@ -77,10 +77,6 @@ static s32 pch_gbe_plat_init_hw(struct pch_gbe_hw *hw)
 		return ret_val;
 	}
 	pch_gbe_phy_init_setting(hw);
-	/* Setup Mac interface option RGMII */
-#ifdef PCH_GBE_MAC_IFOP_RGMII
-	pch_gbe_phy_set_rgmii(hw);
-#endif
 	return ret_val;
 }
 
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.c
index 8b7ff75..d283818 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.c
@@ -249,15 +249,6 @@ void pch_gbe_phy_power_down(struct pch_gbe_hw *hw)
 }
 
 /**
- * pch_gbe_phy_set_rgmii - RGMII interface setting
- * @hw:	            Pointer to the HW structure
- */
-void pch_gbe_phy_set_rgmii(struct pch_gbe_hw *hw)
-{
-	pch_gbe_phy_sw_reset(hw);
-}
-
-/**
  * pch_gbe_phy_tx_clk_delay - Setup TX clock delay via the PHY
  * @hw:	            Pointer to the HW structure
  * Returns
@@ -321,13 +312,11 @@ void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw)
 	cmd.duplex = hw->mac.link_duplex;
 	cmd.advertising = hw->phy.autoneg_advertised;
 	cmd.autoneg = hw->mac.autoneg;
-	pch_gbe_phy_write_reg_miic(hw, MII_BMCR, BMCR_RESET);
+	pch_gbe_phy_sw_reset(hw);
 	ret = mii_ethtool_sset(&adapter->mii, &cmd);
 	if (ret)
 		netdev_err(adapter->netdev, "Error: mii_ethtool_sset\n");
 
-	pch_gbe_phy_sw_reset(hw);
-
 	pch_gbe_phy_read_reg_miic(hw, PHY_PHYSP_CONTROL, &mii_reg);
 	mii_reg |= PHYSP_CTRL_ASSERT_CRS_TX;
 	pch_gbe_phy_write_reg_miic(hw, PHY_PHYSP_CONTROL, mii_reg);
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.h b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.h
index 0cbe692..cda223c 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.h
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.h
@@ -31,7 +31,6 @@ void pch_gbe_phy_sw_reset(struct pch_gbe_hw *hw);
 void pch_gbe_phy_hw_reset(struct pch_gbe_hw *hw);
 void pch_gbe_phy_power_up(struct pch_gbe_hw *hw);
 void pch_gbe_phy_power_down(struct pch_gbe_hw *hw);
-void pch_gbe_phy_set_rgmii(struct pch_gbe_hw *hw);
 void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw);
 int pch_gbe_phy_disable_hibernate(struct pch_gbe_hw *hw);
 
-- 
1.5.6.5

^ permalink raw reply related

* Re: netfilter: active obj WARN when cleaning up
From: Greg KH @ 2013-11-27 23:34 UTC (permalink / raw)
  To: Christoph Lameter, Thomas Gleixner
  Cc: Russell King - ARM Linux, Pablo Neira Ayuso, Sasha Levin,
	Patrick McHardy, kadlec, David S. Miller, netfilter-devel,
	coreteam, netdev, LKML, linux-mm, Andrew Morton,
	Christoph Lameter
In-Reply-To: <alpine.DEB.2.02.1311271443580.30673@ionos.tec.linutronix.de>

On Wed, Nov 27, 2013 at 02:44:58PM +0100, Thomas Gleixner wrote:
> On Wed, 27 Nov 2013, Russell King - ARM Linux wrote:
> 
> > On Wed, Nov 27, 2013 at 01:32:31PM +0000, Russell King - ARM Linux wrote:
> > > On Wed, Nov 27, 2013 at 02:29:41PM +0100, Thomas Gleixner wrote:
> > > > Though the kobject is the only thing which has a delayed work embedded
> > > > inside struct kmem_cache. And the debug object splat points at the
> > > > kmem_cache_free() of the struct kmem_cache itself. That's why I
> > > > assumed the wreckage around that place. And indeed:
> > > > 
> > > > kmem_cache_destroy(s)
> > > >     __kmem_cache_shutdown(s)
> > > >       sysfs_slab_remove(s)
> > > >         ....
> > > > 	kobject_put(&s->kobj)
> > > >            kref_put(&kobj->kref, kobject_release);
> > > > 	     kobject_release(kref)
> > > >     	       #ifdef CONFIG_DEBUG_KOBJECT_RELEASE
> > > > 	         schedule_delayed_work(&kobj->release)
> > > > 	       #else
> > > > 	        kobject_cleanup(kobj)
> > > > 	       #endif
> > > > 
> > > > So in the CONFIG_DEBUG_KOBJECT_RELEASE=y case, schedule_delayed_work()
> > > > _IS_ called which arms the timer. debugobjects catches the attempt to
> > > > free struct kmem_cache which contains the armed timer.
> > > 
> > > You fail to show where the free is in the above path.
> > 
> > Right, there's a kmem_cache_free(kmem_cache, s); by the slob code
> > after the above sequence, which is The Bug(tm).
> > 
> > As I said, a kobject has its own lifetime.  If you embed that into
> > another structure, that structure inherits the lifetime of the kobject,
> > which is from the point at which it's created to the point at which the
> > kobject's release function is called.
> > 
> > So no, the code here is buggy.  The kobject debugging has yet again
> > found a violation of the kobject lifetime rules.  slub needs fixing.
> 
> I leave that discussion to you, greg and the slub folks.

/me grabs some popcorn from tglx

It's really not that much of a discussion, Documentation/kobject.txt has
said this for years, it's as if no one even reads documentation
anymore...

If you embed a kobject into a structure, you have to use the kobject for
the reference counting of the structure, otherwise it's a bug.  If you
don't want to use a kobject to reference count the structure, don't
embed it into it, use a pointer.

Are "slabs" never freed in the slub allocator?  Surely someone should
have seen the huge "this kobject doesn't have a release function" error
message that the kernel should have spit out for it?

Just make the kobject "dynamic" instead of embedded in struct kmem_cache
and all will be fine.  I can't believe this code has been broken for
this long.

thanks,

greg k-h

^ permalink raw reply

* Re: r8169 Wake on Lan
From: Francois Romieu @ 2013-11-28  0:00 UTC (permalink / raw)
  To: Pablo Cholaky; +Cc: netdev
In-Reply-To: <CAEv3EXHY6MzeUxmuJKtO51QMa8AirsVbPP5EgWTfNw941Q9i1Q@mail.gmail.com>

Pablo Cholaky <mrwaltercool@gmail.com> :
> That's the logic:
> 
> - If I turn off my PC with WOL disabled using ethtool, WOL will be
> disabled (normal off, suspend to disk and suspend to RAM).
> 
> - If I turn on my PC,  WOL will always be turned on (including from
> suspend to disk and suspend to RAM)

The driver suspend / resume handlers should thus save and restore the
WoL state. It isn't rocket science but I won't hack it past midnight.

Thanks.

-- 
Ueimor

^ permalink raw reply

* Re: [PATCH net] r8169: check ALDPS bit and disable it if enabled for the 8168g
From: Francois Romieu @ 2013-11-28  0:02 UTC (permalink / raw)
  To: Hayes Wang; +Cc: netdev, David S. Miller, jlee, David Chang
In-Reply-To: <1385538516-32104-1-git-send-email-dchang@suse.com>

David Chang <dchang@suse.com> :
[...]
> Windows driver will enable ALDPS function, but linux driver and firmware
> do not have any configuration related to ALDPS function for 8168g.
> So restart system to linux and remove the NIC cable, LAN enter ALDPS,
> then LAN RX will be disabled.
> 
> This issue can be easily reproduced on dual boot windows and linux
> system with RTL_GIGA_MAC_VER_40 chip.

Hayes, could it be that a different chipset also needs the same kind
of fix ?

-- 
Ueimor

^ permalink raw reply

* RE: [PATCH] net: fec_main: dma_map() only the length of the skb
From: Fugang Duan @ 2013-11-28  1:18 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: netdev@vger.kernel.org, David S. Miller, Fabio Estevam, Frank Li,
	Jim Baxter, Marek Szyprowski
In-Reply-To: <5295F5D3.8020002@linutronix.de>

From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Sent: Wednesday, November 27, 2013 9:38 PM

>To: Duan Fugang-B38611
>Cc: netdev@vger.kernel.org; David S. Miller; Estevam Fabio-R49496; Frank Li;
>Jim Baxter; Marek Szyprowski
>Subject: Re: [PATCH] net: fec_main: dma_map() only the length of the skb
>
>- <frank.li@freescale.net> because MTA complains
>
>On 11/27/2013 02:08 PM, Fugang Duan wrote:
>> In fact, there have one memory copy for enet as below since enet have 16
>bytes data buffer alignment request.
>> if (((unsigned long) bufaddr) & FEC_ALIGNMENT) {
>>                 memcpy(fep->tx_bounce[index], skb->data, skb->len);
>>                 bufaddr = fep->tx_bounce[index]; }
>
>This memcpy() is only executed if the buffer isn't properly aligned which
>shouldn't be the rule but an exception. This aligment check is also available
>in v2.6.31 where the BUG_ON() statement was triggered.
>
In fact, the skb->data address is not aligned with FEC_ALIGNMENT, so memcpy() always is called at here.

Thanks,
Andy 

^ permalink raw reply

* [RESEND PATCH net-next 0/4] net: several cleanups
From: Zhi Yong Wu @ 2013-11-28  1:31 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel, Zhi Yong Wu

From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>

Per David's request, it's time to resend them now.

Zhi Yong Wu (4):
  vhost: remove the dead branch
  vhost: adjust vhost_dev_init() to be void
  macvtap: remove the dead branch
  macvtap: adjust macvtap_skb_to_vnet_hdr() to be void

 drivers/net/macvtap.c |    8 ++------
 drivers/vhost/net.c   |    9 ++-------
 drivers/vhost/scsi.c  |    7 +------
 drivers/vhost/test.c  |    8 +-------
 drivers/vhost/vhost.c |    4 +---
 drivers/vhost/vhost.h |    2 +-
 6 files changed, 8 insertions(+), 30 deletions(-)

-- 
1.7.6.5

^ permalink raw reply

* [RESEND PATCH net-next 1/4] vhost: remove the dead branch
From: Zhi Yong Wu @ 2013-11-28  1:31 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel, Zhi Yong Wu
In-Reply-To: <1385602293-24024-1-git-send-email-zwu.kernel@gmail.com>

From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>

Since vhost_dev_init() forever return 0, some branches are never run,
therefore need to be removed.

Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
---
 drivers/vhost/net.c  |    5 -----
 drivers/vhost/scsi.c |    5 -----
 drivers/vhost/test.c |    5 -----
 3 files changed, 0 insertions(+), 15 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 831eb4f..0554785 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -707,11 +707,6 @@ static int vhost_net_open(struct inode *inode, struct file *f)
 		n->vqs[i].sock_hlen = 0;
 	}
 	r = vhost_dev_init(dev, vqs, VHOST_NET_VQ_MAX);
-	if (r < 0) {
-		kfree(n);
-		kfree(vqs);
-		return r;
-	}
 
 	vhost_poll_init(n->poll + VHOST_NET_VQ_TX, handle_tx_net, POLLOUT, dev);
 	vhost_poll_init(n->poll + VHOST_NET_VQ_RX, handle_rx_net, POLLIN, dev);
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index f175629..3164680 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -1421,14 +1421,9 @@ static int vhost_scsi_open(struct inode *inode, struct file *f)
 
 	tcm_vhost_init_inflight(vs, NULL);
 
-	if (r < 0)
-		goto err_init;
-
 	f->private_data = vs;
 	return 0;
 
-err_init:
-	kfree(vqs);
 err_vqs:
 	vhost_scsi_free(vs);
 err_vs:
diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c
index 339eae8..99cb960 100644
--- a/drivers/vhost/test.c
+++ b/drivers/vhost/test.c
@@ -118,11 +118,6 @@ static int vhost_test_open(struct inode *inode, struct file *f)
 	vqs[VHOST_TEST_VQ] = &n->vqs[VHOST_TEST_VQ];
 	n->vqs[VHOST_TEST_VQ].handle_kick = handle_vq_kick;
 	r = vhost_dev_init(dev, vqs, VHOST_TEST_VQ_MAX);
-	if (r < 0) {
-		kfree(vqs);
-		kfree(n);
-		return r;
-	}
 
 	f->private_data = n;
 
-- 
1.7.6.5

^ permalink raw reply related

* [RESEND PATCH net-next 2/4] vhost: adjust vhost_dev_init() to be void
From: Zhi Yong Wu @ 2013-11-28  1:31 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel, Zhi Yong Wu
In-Reply-To: <1385602293-24024-1-git-send-email-zwu.kernel@gmail.com>

From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>

Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
---
 drivers/vhost/net.c   |    4 ++--
 drivers/vhost/scsi.c  |    2 +-
 drivers/vhost/test.c  |    3 +--
 drivers/vhost/vhost.c |    4 +---
 drivers/vhost/vhost.h |    2 +-
 5 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 0554785..9a68409 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -683,7 +683,7 @@ static int vhost_net_open(struct inode *inode, struct file *f)
 	struct vhost_net *n = kmalloc(sizeof *n, GFP_KERNEL);
 	struct vhost_dev *dev;
 	struct vhost_virtqueue **vqs;
-	int r, i;
+	int i;
 
 	if (!n)
 		return -ENOMEM;
@@ -706,7 +706,7 @@ static int vhost_net_open(struct inode *inode, struct file *f)
 		n->vqs[i].vhost_hlen = 0;
 		n->vqs[i].sock_hlen = 0;
 	}
-	r = vhost_dev_init(dev, vqs, VHOST_NET_VQ_MAX);
+	vhost_dev_init(dev, vqs, VHOST_NET_VQ_MAX);
 
 	vhost_poll_init(n->poll + VHOST_NET_VQ_TX, handle_tx_net, POLLOUT, dev);
 	vhost_poll_init(n->poll + VHOST_NET_VQ_RX, handle_rx_net, POLLIN, dev);
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 3164680..1e4c75c 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -1417,7 +1417,7 @@ static int vhost_scsi_open(struct inode *inode, struct file *f)
 		vqs[i] = &vs->vqs[i].vq;
 		vs->vqs[i].vq.handle_kick = vhost_scsi_handle_kick;
 	}
-	r = vhost_dev_init(&vs->dev, vqs, VHOST_SCSI_MAX_VQ);
+	vhost_dev_init(&vs->dev, vqs, VHOST_SCSI_MAX_VQ);
 
 	tcm_vhost_init_inflight(vs, NULL);
 
diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c
index 99cb960..c2a54fb 100644
--- a/drivers/vhost/test.c
+++ b/drivers/vhost/test.c
@@ -104,7 +104,6 @@ static int vhost_test_open(struct inode *inode, struct file *f)
 	struct vhost_test *n = kmalloc(sizeof *n, GFP_KERNEL);
 	struct vhost_dev *dev;
 	struct vhost_virtqueue **vqs;
-	int r;
 
 	if (!n)
 		return -ENOMEM;
@@ -117,7 +116,7 @@ static int vhost_test_open(struct inode *inode, struct file *f)
 	dev = &n->dev;
 	vqs[VHOST_TEST_VQ] = &n->vqs[VHOST_TEST_VQ];
 	n->vqs[VHOST_TEST_VQ].handle_kick = handle_vq_kick;
-	r = vhost_dev_init(dev, vqs, VHOST_TEST_VQ_MAX);
+	vhost_dev_init(dev, vqs, VHOST_TEST_VQ_MAX);
 
 	f->private_data = n;
 
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 69068e0..78987e4 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -290,7 +290,7 @@ static void vhost_dev_free_iovecs(struct vhost_dev *dev)
 		vhost_vq_free_iovecs(dev->vqs[i]);
 }
 
-long vhost_dev_init(struct vhost_dev *dev,
+void vhost_dev_init(struct vhost_dev *dev,
 		    struct vhost_virtqueue **vqs, int nvqs)
 {
 	struct vhost_virtqueue *vq;
@@ -319,8 +319,6 @@ long vhost_dev_init(struct vhost_dev *dev,
 			vhost_poll_init(&vq->poll, vq->handle_kick,
 					POLLIN, dev);
 	}
-
-	return 0;
 }
 EXPORT_SYMBOL_GPL(vhost_dev_init);
 
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 4465ed5..35eeb2a 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -127,7 +127,7 @@ struct vhost_dev {
 	struct task_struct *worker;
 };
 
-long vhost_dev_init(struct vhost_dev *, struct vhost_virtqueue **vqs, int nvqs);
+void vhost_dev_init(struct vhost_dev *, struct vhost_virtqueue **vqs, int nvqs);
 long vhost_dev_set_owner(struct vhost_dev *dev);
 bool vhost_dev_has_owner(struct vhost_dev *dev);
 long vhost_dev_check_owner(struct vhost_dev *);
-- 
1.7.6.5

^ permalink raw reply related

* [RESEND PATCH net-next 3/4] macvtap: remove the dead branch
From: Zhi Yong Wu @ 2013-11-28  1:31 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel, Zhi Yong Wu
In-Reply-To: <1385602293-24024-1-git-send-email-zwu.kernel@gmail.com>

From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>

Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
---
 drivers/net/macvtap.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index dc76670..eeb1a97 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -780,8 +780,6 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
 			return -EINVAL;
 
 		ret = macvtap_skb_to_vnet_hdr(skb, &vnet_hdr);
-		if (ret)
-			return ret;
 
 		if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, sizeof(vnet_hdr)))
 			return -EFAULT;
-- 
1.7.6.5

^ permalink raw reply related

* [RESEND PATCH net-next 4/4] macvtap: adjust macvtap_skb_to_vnet_hdr() to be void
From: Zhi Yong Wu @ 2013-11-28  1:31 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel, Zhi Yong Wu
In-Reply-To: <1385602293-24024-1-git-send-email-zwu.kernel@gmail.com>

From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>

Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
---
 drivers/net/macvtap.c |    6 ++----
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index eeb1a97..155d60e 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -588,7 +588,7 @@ static int macvtap_skb_from_vnet_hdr(struct sk_buff *skb,
 	return 0;
 }
 
-static int macvtap_skb_to_vnet_hdr(const struct sk_buff *skb,
+static void macvtap_skb_to_vnet_hdr(const struct sk_buff *skb,
 				   struct virtio_net_hdr *vnet_hdr)
 {
 	memset(vnet_hdr, 0, sizeof(*vnet_hdr));
@@ -619,8 +619,6 @@ static int macvtap_skb_to_vnet_hdr(const struct sk_buff *skb,
 	} else if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
 		vnet_hdr->flags = VIRTIO_NET_HDR_F_DATA_VALID;
 	} /* else everything is zero */
-
-	return 0;
 }
 
 /* Get packet from user space buffer */
@@ -779,7 +777,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
 		if ((len -= vnet_hdr_len) < 0)
 			return -EINVAL;
 
-		ret = macvtap_skb_to_vnet_hdr(skb, &vnet_hdr);
+		macvtap_skb_to_vnet_hdr(skb, &vnet_hdr);
 
 		if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, sizeof(vnet_hdr)))
 			return -EFAULT;
-- 
1.7.6.5

^ permalink raw reply related

* Re: [PATCH] sfc: Convert to use hwmon_device_register_with_groups
From: Ben Hutchings @ 2013-11-28  2:11 UTC (permalink / raw)
  To: Guenter Roeck; +Cc: netdev, linux-net-drivers, lm-sensors
In-Reply-To: <1385523187-31996-1-git-send-email-linux@roeck-us.net>

On Tue, 2013-11-26 at 19:33 -0800, Guenter Roeck wrote:
> Simplify the code. Avoid race conditions caused by attributes
> being created after hwmon device registration. Implicitly
> (through hwmon API) add mandatory 'name' sysfs attribute.
> 
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
> Compile tested only.
[...]

Very close, but you missed this bit:

--- a/drivers/net/ethernet/sfc/mcdi_mon.c
+++ b/drivers/net/ethernet/sfc/mcdi_mon.c
@@ -142,7 +142,7 @@ static int efx_mcdi_mon_update(struct efx_nic *efx)
 static int efx_mcdi_mon_get_entry(struct device *dev, unsigned int index,
 				  efx_dword_t *entry)
 {
-	struct efx_nic *efx = dev_get_drvdata(dev);
+	struct efx_nic *efx = dev_get_drvdata(dev->parent);
 	struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx);
 	int rc;
 
---

With that addition, it works for me, and you can add my Reviewed-by.

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply

* Re: [PATCH] sfc: Convert to use hwmon_device_register_with_groups
From: Guenter Roeck @ 2013-11-28  2:51 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: netdev, linux-net-drivers, lm-sensors
In-Reply-To: <1385604693.1586.76.camel@bwh-desktop.uk.level5networks.com>

On 11/27/2013 06:11 PM, Ben Hutchings wrote:
> On Tue, 2013-11-26 at 19:33 -0800, Guenter Roeck wrote:
>> Simplify the code. Avoid race conditions caused by attributes
>> being created after hwmon device registration. Implicitly
>> (through hwmon API) add mandatory 'name' sysfs attribute.
>>
>> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
>> ---
>> Compile tested only.
> [...]
>
> Very close, but you missed this bit:
>
> --- a/drivers/net/ethernet/sfc/mcdi_mon.c
> +++ b/drivers/net/ethernet/sfc/mcdi_mon.c
> @@ -142,7 +142,7 @@ static int efx_mcdi_mon_update(struct efx_nic *efx)
>   static int efx_mcdi_mon_get_entry(struct device *dev, unsigned int index,
>   				  efx_dword_t *entry)
>   {
> -	struct efx_nic *efx = dev_get_drvdata(dev);
> +	struct efx_nic *efx = dev_get_drvdata(dev->parent);
>   	struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx);
>   	int rc;
>
> ---
>
> With that addition, it works for me, and you can add my Reviewed-by.
>

Thanks a lot!

Guenter

^ permalink raw reply

* [PATCH net-next 1/3] xfrm: check user specified spi for IPComp
From: Fan Du @ 2013-11-28  2:52 UTC (permalink / raw)
  To: steffen.klassert; +Cc: davem, netdev
In-Reply-To: <1385607161-27597-1-git-send-email-fan.du@windriver.com>

IPComp connection between two hosts is broken if given spi bigger
than 0xffff.

OUTSPI=0x87
INSPI=0x11112

ip xfrm policy update dst 192.168.1.101 src 192.168.1.109 dir out action allow \
       tmpl dst 192.168.1.101 src 192.168.1.109 proto comp spi $OUTSPI
ip xfrm policy update src 192.168.1.101 dst 192.168.1.109 dir in action allow \
       tmpl src 192.168.1.101 dst 192.168.1.109 proto comp spi $INSPI

ip xfrm state add src 192.168.1.101 dst 192.168.1.109  proto comp spi $INSPI \
		comp deflate "0x1111"
ip xfrm state add dst 192.168.1.101 src 192.168.1.109  proto comp spi $OUTSPI \
		comp deflate "0x1111"

tcpdump can capture outbound ping packet, but inbound packet is
dropped with XfrmOutNoStates errors. It looks like spi value used
for IPComp is expected to be 16bits wide only.

Signed-off-by: Fan Du <fan.du@windriver.com>
---
 net/xfrm/xfrm_user.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index f964d4c..52efe71 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -209,7 +209,8 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
 		    attrs[XFRMA_ALG_AUTH]	||
 		    attrs[XFRMA_ALG_AUTH_TRUNC]	||
 		    attrs[XFRMA_ALG_CRYPT]	||
-		    attrs[XFRMA_TFCPAD])
+		    attrs[XFRMA_TFCPAD] ||
+			(ntohl(p->id.spi) >= 0x10000))
 			goto out;
 		break;
 
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 0/3] IPComp fixes
From: Fan Du @ 2013-11-28  2:52 UTC (permalink / raw)
  To: steffen.klassert; +Cc: davem, netdev

Hi,

This patchset includes bug fix focusing on IPComp mainly, which addresses
IPComp Compression Parameter Index(CPI, 16bits of 32bits SPI value) problem.

And other issue is the compression part, undesirable packet will not be
compressed, and then send into wire, this packet will be dropped by policy
checking in the receiver side.

Fan Du (3):
  xfrm: check user specified spi for IPComp
  xfrm: clamp down spi range for IPComp when allocating spi
  xfrm: Restrict "level use" for IPComp configuration

 net/key/af_key.c      |    6 ++++++
 net/xfrm/xfrm_state.c |   13 +++++++++++++
 net/xfrm/xfrm_user.c  |    7 ++++++-
 3 files changed, 25 insertions(+), 1 deletion(-)

-- 
1.7.9.5

^ permalink raw reply

* [PATCH net-next 2/3] xfrm: clamp down spi range for IPComp when allocating spi
From: Fan Du @ 2013-11-28  2:52 UTC (permalink / raw)
  To: steffen.klassert; +Cc: davem, netdev
In-Reply-To: <1385607161-27597-1-git-send-email-fan.du@windriver.com>

otherwise xfrm state can not be found properly by peers.

Signed-off-by: Fan Du <fan.du@windriver.com>
---
 net/xfrm/xfrm_state.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 68c2f35..a6716d7 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1506,6 +1506,19 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
 	__be32 maxspi = htonl(high);
 	u32 mark = x->mark.v & x->mark.m;
 
+	/* Compression Parameter Index(CPI) is 16bits wide
+	 * An 32 bits spi value will hash xfrm_state into wrong hash slot.
+	 * When the upper 16bits of spi values is used as CPI for the peer
+	 * to look up xfrm state, it would generate XfrmOutNoStates error,
+	 * as apparently we are looking for the wrong hash slot.
+	 *
+	 * So clamp down the spi range into only 16bits valid wide.
+	 */
+	if (x->id.proto == IPPROTO_COMP) {
+		minspi = htonl(0xc00);
+		maxspi = htonl(0xff00);
+	}
+
 	spin_lock_bh(&x->lock);
 	if (x->km.state == XFRM_STATE_DEAD)
 		goto unlock;
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 3/3] xfrm: Restrict "level use" for IPComp configuration
From: Fan Du @ 2013-11-28  2:52 UTC (permalink / raw)
  To: steffen.klassert; +Cc: davem, netdev
In-Reply-To: <1385607161-27597-1-git-send-email-fan.du@windriver.com>

Quote from RFC3173:
2.2. Non-Expansion Policy

   If the total size of a compressed payload and the IPComp header, as
   defined in section 3, is not smaller than the size of the original
   payload, the IP datagram MUST be sent in the original non-compressed
   form.  To clarify: If an IP datagram is sent non-compressed, no

   IPComp header is added to the datagram.  This policy ensures saving
   the decompression processing cycles and avoiding incurring IP
   datagram fragmentation when the expanded datagram is larger than the
   MTU.

   Small IP datagrams are likely to expand as a result of compression.
   Therefore, a numeric threshold should be applied before compression,
   where IP datagrams of size smaller than the threshold are sent in the
   original form without attempting compression.  The numeric threshold
   is implementation dependent.

Current IPComp implementation is indeed by the book, whileas in practice
when sending non-compressed packet to the peer(whether or not packet len
is smaller than the threshold or the compressed len is large than orignal
packet len), the packet is dropped when checking the policy as this packet
matches the selector but not coming from any XFRM layer, i.e., with no
security path. Such naked packet will not evently make it to upper layer 4.
The result is much more wired to the user when ping peer with different
palyload lenght.

Fixing this by chanlledging IPComp level against "level use" to cure this
problem.

Signed-off-by: Fan Du <fan.du@windriver.com>
---
 net/key/af_key.c     |    6 ++++++
 net/xfrm/xfrm_user.c |    4 ++++
 2 files changed, 10 insertions(+)

diff --git a/net/key/af_key.c b/net/key/af_key.c
index 911ef03..d37a2c1 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1895,6 +1895,12 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
 			return -ENOBUFS;
 	}
 
+	/* IPComp requires level use option to accomodate both compressed
+	 * and non-compressed packet when checking policy.
+	 */
+	if ((t->id.proto == IPPROTO_COMP) && (t->optional == 0))
+		return -EINVAL;
+
 	/* addresses present only in tunnel mode */
 	if (t->mode == XFRM_MODE_TUNNEL) {
 		u8 *sa = (u8 *) (rq + 1);
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 52efe71..d7216ea 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1293,6 +1293,10 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family)
 		default:
 			return -EINVAL;
 		}
+
+		/* Refuse any IPComp conf that missing "level use" */
+		if ((ut[i].id.proto == IPPROTO_COMP) && (ut[i].optional == 0))
+			return -EINVAL;
 	}
 
 	return 0;
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next] netfilter: add IPComp extension match support
From: Fan Du @ 2013-11-28  2:53 UTC (permalink / raw)
  To: steffen.klassert, pablo; +Cc: kaber, netdev, netfilter-devel

With this plugin, user could specify IPComp tagged with certain 
CPI that host not interested will be DROPped or any other action.

For example:
iptables -A INPUT -p 108 -m ipcomp --ipcompspi 0x87 -j DROP

Then input IPComp packet with CPI equates 0x87 will not reach
upper layer anymore.

Signed-off-by: Fan Du <fan.du@windriver.com>
---
 include/uapi/linux/netfilter_ipv4/ipt_comp.h |   17 +++++
 net/ipv4/netfilter/Kconfig                   |    9 +++
 net/ipv4/netfilter/Makefile                  |    1 +
 net/ipv4/netfilter/ipt_comp.c                |  101 ++++++++++++++++++++++++++
 4 files changed, 128 insertions(+)
 create mode 100644 include/uapi/linux/netfilter_ipv4/ipt_comp.h
 create mode 100644 net/ipv4/netfilter/ipt_comp.c

diff --git a/include/uapi/linux/netfilter_ipv4/ipt_comp.h b/include/uapi/linux/netfilter_ipv4/ipt_comp.h
new file mode 100644
index 0000000..d072202
--- /dev/null
+++ b/include/uapi/linux/netfilter_ipv4/ipt_comp.h
@@ -0,0 +1,17 @@
+#ifndef _IPT_COMP_H
+#define _IPT_COMP_H
+
+#include <linux/types.h>
+
+struct ipt_comp {
+	__u32 spis[2];			/* Security Parameter Index */
+	__u8  invflags;			/* Inverse flags */
+};
+
+
+
+/* Values for "invflags" field in struct ipt_comp. */
+#define IPT_IPCOMP_INV_SPI		0x01	/* Invert the sense of spi. */
+#define IPT_IPCOMP_INV_MASK	0x01	/* All possible flags. */
+
+#endif /*_IPT_COMP_H*/
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 40d5607..f71cf7b 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -81,6 +81,15 @@ config IP_NF_MATCH_AH
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
+config IP_NF_MATCH_IPCOMP
+	tristate '"ipcomp" match support'
+	depends on NETFILTER_ADVANCED
+	help
+	  This match extension allows you to match a range of SPIs (Actually it's
+	  Compression Parameter Index(CPI) inside IPComp header of IPSec packets.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 config IP_NF_MATCH_ECN
 	tristate '"ecn" match support'
 	depends on NETFILTER_ADVANCED
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 19df72b..b67ecb8 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_IP_NF_SECURITY) += iptable_security.o
 
 # matches
 obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
+obj-$(CONFIG_IP_NF_MATCH_IPCOMP) += ipt_comp.o
 obj-$(CONFIG_IP_NF_MATCH_RPFILTER) += ipt_rpfilter.o
 
 # targets
diff --git a/net/ipv4/netfilter/ipt_comp.c b/net/ipv4/netfilter/ipt_comp.c
new file mode 100644
index 0000000..7796e6e
--- /dev/null
+++ b/net/ipv4/netfilter/ipt_comp.c
@@ -0,0 +1,101 @@
+/*  Kernel module to match IPComp parameters
+ *
+ *  Copyright (C) 2013 WindRiver
+ *
+ *  Author:
+ *  Fan Du <fan.du@windriver.com>
+ *
+ *  Based on:
+ *  net/ipv4/netfilter/ipt_ah.c
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/in.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+
+#include <linux/netfilter_ipv4/ipt_comp.h>
+#include <linux/netfilter/x_tables.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Fan Du <fan.du@windriver.com>");
+MODULE_DESCRIPTION("Xtables: IPv4 IPsec-IPComp SPI match");
+
+/* Returns 1 if the spi is matched by the range, 0 otherwise */
+static inline bool
+spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
+{
+	bool r;
+	pr_debug("spi_match:%c 0x%x <= 0x%x <= 0x%x\n",
+		 invert ? '!' : ' ', min, spi, max);
+	r = (spi >= min && spi <= max) ^ invert;
+	pr_debug(" result %s\n", r ? "PASS" : "FAILED");
+	return r;
+}
+
+static bool comp_mt(const struct sk_buff *skb, struct xt_action_param *par)
+{
+	struct ip_comp_hdr _comphdr;
+	const struct ip_comp_hdr *chdr;
+	const struct ipt_comp *compinfo = par->matchinfo;
+
+	/* Must not be a fragment. */
+	if (par->fragoff != 0)
+		return false;
+
+	chdr = skb_header_pointer(skb, par->thoff, sizeof(_comphdr), &_comphdr);
+	if (chdr == NULL) {
+		/* We've been asked to examine this packet, and we
+		 * can't.  Hence, no choice but to drop.
+		 */
+		pr_debug("Dropping evil IPComp tinygram.\n");
+		par->hotdrop = true;
+		return 0;
+	}
+
+	return spi_match(compinfo->spis[0], compinfo->spis[1],
+			 ntohl(chdr->cpi << 16),
+			 !!(compinfo->invflags & IPT_IPCOMP_INV_SPI));
+}
+
+static int comp_mt_check(const struct xt_mtchk_param *par)
+{
+	const struct ipt_comp *compinfo = par->matchinfo;
+
+	/* Must specify no unknown invflags */
+	if (compinfo->invflags & ~IPT_IPCOMP_INV_MASK) {
+		pr_debug("unknown flags %X\n", compinfo->invflags);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static struct xt_match comp_mt_reg __read_mostly = {
+	.name		= "ipcomp",
+	.family		= NFPROTO_IPV4,
+	.match		= comp_mt,
+	.matchsize	= sizeof(struct ipt_comp),
+	.proto		= IPPROTO_COMP,
+	.checkentry	= comp_mt_check,
+	.me		= THIS_MODULE,
+};
+
+static int __init comp_mt_init(void)
+{
+	return xt_register_match(&comp_mt_reg);
+}
+
+static void __exit comp_mt_exit(void)
+{
+	xt_unregister_match(&comp_mt_reg);
+}
+
+module_init(comp_mt_init);
+module_exit(comp_mt_exit);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2] sfc: Convert to use hwmon_device_register_with_groups
From: Guenter Roeck @ 2013-11-28  2:54 UTC (permalink / raw)
  To: netdev; +Cc: linux-net-drivers, Ben Hutchings, lm-sensors, Guenter Roeck

Simplify the code. Avoid race conditions caused by attributes
being created after hwmon device registration. Implicitly
(through hwmon API) add mandatory 'name' sysfs attribute.

Reviewed-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v2: Fix wrong dev_get_drvdata dereference in efx_mcdi_mon_get_entry()

 drivers/net/ethernet/sfc/mcdi.h     |    2 +
 drivers/net/ethernet/sfc/mcdi_mon.c |   78 ++++++++++++++---------------------
 2 files changed, 32 insertions(+), 48 deletions(-)

diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h
index 656a327..15816ca 100644
--- a/drivers/net/ethernet/sfc/mcdi.h
+++ b/drivers/net/ethernet/sfc/mcdi.h
@@ -75,6 +75,8 @@ struct efx_mcdi_mon {
 	unsigned long last_update;
 	struct device *device;
 	struct efx_mcdi_mon_attribute *attrs;
+	struct attribute_group group;
+	const struct attribute_group *groups[2];
 	unsigned int n_attrs;
 };
 
diff --git a/drivers/net/ethernet/sfc/mcdi_mon.c b/drivers/net/ethernet/sfc/mcdi_mon.c
index 4cc5d95..d72ad4f 100644
--- a/drivers/net/ethernet/sfc/mcdi_mon.c
+++ b/drivers/net/ethernet/sfc/mcdi_mon.c
@@ -139,17 +139,10 @@ static int efx_mcdi_mon_update(struct efx_nic *efx)
 	return rc;
 }
 
-static ssize_t efx_mcdi_mon_show_name(struct device *dev,
-				      struct device_attribute *attr,
-				      char *buf)
-{
-	return sprintf(buf, "%s\n", KBUILD_MODNAME);
-}
-
 static int efx_mcdi_mon_get_entry(struct device *dev, unsigned int index,
 				  efx_dword_t *entry)
 {
-	struct efx_nic *efx = dev_get_drvdata(dev);
+	struct efx_nic *efx = dev_get_drvdata(dev->parent);
 	struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx);
 	int rc;
 
@@ -263,7 +256,7 @@ static ssize_t efx_mcdi_mon_show_label(struct device *dev,
 		       efx_mcdi_sensor_type[mon_attr->type].label);
 }
 
-static int
+static void
 efx_mcdi_mon_add_attr(struct efx_nic *efx, const char *name,
 		      ssize_t (*reader)(struct device *,
 					struct device_attribute *, char *),
@@ -272,7 +265,6 @@ efx_mcdi_mon_add_attr(struct efx_nic *efx, const char *name,
 {
 	struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx);
 	struct efx_mcdi_mon_attribute *attr = &hwmon->attrs[hwmon->n_attrs];
-	int rc;
 
 	strlcpy(attr->name, name, sizeof(attr->name));
 	attr->index = index;
@@ -286,10 +278,7 @@ efx_mcdi_mon_add_attr(struct efx_nic *efx, const char *name,
 	attr->dev_attr.attr.name = attr->name;
 	attr->dev_attr.attr.mode = S_IRUGO;
 	attr->dev_attr.show = reader;
-	rc = device_create_file(&efx->pci_dev->dev, &attr->dev_attr);
-	if (rc == 0)
-		++hwmon->n_attrs;
-	return rc;
+	hwmon->group.attrs[hwmon->n_attrs++] = &attr->dev_attr.attr;
 }
 
 int efx_mcdi_mon_probe(struct efx_nic *efx)
@@ -338,26 +327,22 @@ int efx_mcdi_mon_probe(struct efx_nic *efx)
 	efx_mcdi_mon_update(efx);
 
 	/* Allocate space for the maximum possible number of
-	 * attributes for this set of sensors: name of the driver plus
+	 * attributes for this set of sensors:
 	 * value, min, max, crit, alarm and label for each sensor.
 	 */
-	n_attrs = 1 + 6 * n_sensors;
+	n_attrs = 6 * n_sensors;
 	hwmon->attrs = kcalloc(n_attrs, sizeof(*hwmon->attrs), GFP_KERNEL);
 	if (!hwmon->attrs) {
 		rc = -ENOMEM;
 		goto fail;
 	}
-
-	hwmon->device = hwmon_device_register(&efx->pci_dev->dev);
-	if (IS_ERR(hwmon->device)) {
-		rc = PTR_ERR(hwmon->device);
+	hwmon->group.attrs = kcalloc(n_attrs + 1, sizeof(struct attribute *),
+				     GFP_KERNEL);
+	if (!hwmon->group.attrs) {
+		rc = -ENOMEM;
 		goto fail;
 	}
 
-	rc = efx_mcdi_mon_add_attr(efx, "name", efx_mcdi_mon_show_name, 0, 0, 0);
-	if (rc)
-		goto fail;
-
 	for (i = 0, j = -1, type = -1; ; i++) {
 		enum efx_hwmon_type hwmon_type;
 		const char *hwmon_prefix;
@@ -372,7 +357,7 @@ int efx_mcdi_mon_probe(struct efx_nic *efx)
 				page = type / 32;
 				j = -1;
 				if (page == n_pages)
-					return 0;
+					goto hwmon_register;
 
 				MCDI_SET_DWORD(inbuf, SENSOR_INFO_EXT_IN_PAGE,
 					       page);
@@ -453,28 +438,22 @@ int efx_mcdi_mon_probe(struct efx_nic *efx)
 		if (min1 != max1) {
 			snprintf(name, sizeof(name), "%s%u_input",
 				 hwmon_prefix, hwmon_index);
-			rc = efx_mcdi_mon_add_attr(
+			efx_mcdi_mon_add_attr(
 				efx, name, efx_mcdi_mon_show_value, i, type, 0);
-			if (rc)
-				goto fail;
 
 			if (hwmon_type != EFX_HWMON_POWER) {
 				snprintf(name, sizeof(name), "%s%u_min",
 					 hwmon_prefix, hwmon_index);
-				rc = efx_mcdi_mon_add_attr(
+				efx_mcdi_mon_add_attr(
 					efx, name, efx_mcdi_mon_show_limit,
 					i, type, min1);
-				if (rc)
-					goto fail;
 			}
 
 			snprintf(name, sizeof(name), "%s%u_max",
 				 hwmon_prefix, hwmon_index);
-			rc = efx_mcdi_mon_add_attr(
+			efx_mcdi_mon_add_attr(
 				efx, name, efx_mcdi_mon_show_limit,
 				i, type, max1);
-			if (rc)
-				goto fail;
 
 			if (min2 != max2) {
 				/* Assume max2 is critical value.
@@ -482,32 +461,38 @@ int efx_mcdi_mon_probe(struct efx_nic *efx)
 				 */
 				snprintf(name, sizeof(name), "%s%u_crit",
 					 hwmon_prefix, hwmon_index);
-				rc = efx_mcdi_mon_add_attr(
+				efx_mcdi_mon_add_attr(
 					efx, name, efx_mcdi_mon_show_limit,
 					i, type, max2);
-				if (rc)
-					goto fail;
 			}
 		}
 
 		snprintf(name, sizeof(name), "%s%u_alarm",
 			 hwmon_prefix, hwmon_index);
-		rc = efx_mcdi_mon_add_attr(
+		efx_mcdi_mon_add_attr(
 			efx, name, efx_mcdi_mon_show_alarm, i, type, 0);
-		if (rc)
-			goto fail;
 
 		if (type < ARRAY_SIZE(efx_mcdi_sensor_type) &&
 		    efx_mcdi_sensor_type[type].label) {
 			snprintf(name, sizeof(name), "%s%u_label",
 				 hwmon_prefix, hwmon_index);
-			rc = efx_mcdi_mon_add_attr(
+			efx_mcdi_mon_add_attr(
 				efx, name, efx_mcdi_mon_show_label, i, type, 0);
-			if (rc)
-				goto fail;
 		}
 	}
 
+hwmon_register:
+	hwmon->groups[0] = &hwmon->group;
+	hwmon->device = hwmon_device_register_with_groups(&efx->pci_dev->dev,
+							  KBUILD_MODNAME, NULL,
+							  hwmon->groups);
+	if (IS_ERR(hwmon->device)) {
+		rc = PTR_ERR(hwmon->device);
+		goto fail;
+	}
+
+	return 0;
+
 fail:
 	efx_mcdi_mon_remove(efx);
 	return rc;
@@ -516,14 +501,11 @@ fail:
 void efx_mcdi_mon_remove(struct efx_nic *efx)
 {
 	struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx);
-	unsigned int i;
 
-	for (i = 0; i < hwmon->n_attrs; i++)
-		device_remove_file(&efx->pci_dev->dev,
-				   &hwmon->attrs[i].dev_attr);
-	kfree(hwmon->attrs);
 	if (hwmon->device)
 		hwmon_device_unregister(hwmon->device);
+	kfree(hwmon->attrs);
+	kfree(hwmon->group.attrs);
 	efx_nic_free_buffer(efx, &hwmon->dma_buf);
 }
 
-- 
1.7.9.7

^ permalink raw reply related

* Re: [PATCH 1/2] virtio_net: fix error handling for mergeable buffers
From: Jason Wang @ 2013-11-28  3:14 UTC (permalink / raw)
  To: Michael S. Tsirkin, linux-kernel
  Cc: netdev, Eric Dumazet, Michael Dalton, virtualization
In-Reply-To: <1385569684-26595-1-git-send-email-mst@redhat.com>

On 11/28/2013 12:31 AM, Michael S. Tsirkin wrote:
> Eric Dumazet noticed that if we encounter an error
> when processing a mergeable buffer, we don't
> dequeue all of the buffers from this packet,
> the result is almost sure to be loss of networking.
>
> Jason Wang noticed that we also leak a page and that we don't decrement
> the rq buf count, so we won't repost buffers (a resource leak).
>
> Fix both issues, and also make the logic a bit more
> robust against device errors by not looping when e.g. because of a leak
> like the one we are fixing here the number of buffers is 0.
>
> Cc: Rusty Russell <rusty@rustcorp.com.au>
> Cc: Michael Dalton <mwdalton@google.com>
> Reported-by: Eric Dumazet <edumazet@google.com>
> Reported-by: Jason Wang <jasowang@redhat.com>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> ---
>
> Note: this bugfix is needed on stable too, but backport
> might not be trivial.
> I'll send a backport for stable separately.

That will be fine.
>
>  drivers/net/virtio_net.c | 84 ++++++++++++++++++++++++++++++------------------
>  1 file changed, 52 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 7bab4de..0e6ea69 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -299,41 +299,53 @@ static struct sk_buff *page_to_skb(struct receive_queue *rq,
>  	return skb;
>  }
>  
> -static int receive_mergeable(struct receive_queue *rq, struct sk_buff *head_skb)
> +static struct sk_buff *receive_mergeable(struct net_device *dev,
> +					 struct receive_queue *rq,
> +					 void *buf,
> +					 unsigned int len)
>  {
> -	struct skb_vnet_hdr *hdr = skb_vnet_hdr(head_skb);
> +	struct skb_vnet_hdr *hdr = buf;
> +	int num_buf = hdr->mhdr.num_buffers;
> +	struct page *page = virt_to_head_page(buf);
> +	int offset = buf - page_address(page);
> +	struct sk_buff *head_skb = page_to_skb(rq, page, offset, len,
> +					       MERGE_BUFFER_LEN);
>  	struct sk_buff *curr_skb = head_skb;
> -	char *buf;
> -	struct page *page;
> -	int num_buf, len, offset;
>  
> -	num_buf = hdr->mhdr.num_buffers;
> +	if (unlikely(!curr_skb))
> +		goto err_skb;
> +
>  	while (--num_buf) {
> -		int num_skb_frags = skb_shinfo(curr_skb)->nr_frags;
> +		int num_skb_frags;
> +
>  		buf = virtqueue_get_buf(rq->vq, &len);
>  		if (unlikely(!buf)) {
> -			pr_debug("%s: rx error: %d buffers missing\n",
> -				 head_skb->dev->name, hdr->mhdr.num_buffers);
> -			head_skb->dev->stats.rx_length_errors++;
> -			return -EINVAL;
> +			pr_debug("%s: rx error: %d buffers out of %d missing\n",
> +				 dev->name, num_buf, hdr->mhdr.num_buffers);
> +			dev->stats.rx_length_errors++;
> +			goto err_buf;

Not sure it's correct here. Since the we break immediately if buffer is
missed in err_buf and rx_length_error will be miss counted.

Maybe an ERR_PTR(-EINVAL) is better.
>  		}
>  		if (unlikely(len > MERGE_BUFFER_LEN)) {
>  			pr_debug("%s: rx error: merge buffer too long\n",
> -				 head_skb->dev->name);
> +				 dev->name);
>  			len = MERGE_BUFFER_LEN;
>  		}
> +
> +		page = virt_to_head_page(buf);
> +		--rq->num;
> +
> +		num_skb_frags = skb_shinfo(curr_skb)->nr_frags;
>  		if (unlikely(num_skb_frags == MAX_SKB_FRAGS)) {
>  			struct sk_buff *nskb = alloc_skb(0, GFP_ATOMIC);
> -			if (unlikely(!nskb)) {
> -				head_skb->dev->stats.rx_dropped++;
> -				return -ENOMEM;
> -			}
> +
> +			if (unlikely(!nskb))
> +				goto err_skb;
>  			if (curr_skb == head_skb)
>  				skb_shinfo(curr_skb)->frag_list = nskb;
>  			else
>  				curr_skb->next = nskb;
> -			curr_skb = nskb;
>  			head_skb->truesize += nskb->truesize;
> +			curr_skb = nskb;

This change seems unnecessary.

Other looks good.
>  			num_skb_frags = 0;
>  		}
>  		if (curr_skb != head_skb) {
> @@ -341,8 +353,7 @@ static int receive_mergeable(struct receive_queue *rq, struct sk_buff *head_skb)
>  			head_skb->len += len;
>  			head_skb->truesize += MERGE_BUFFER_LEN;
>  		}
> -		page = virt_to_head_page(buf);
> -		offset = buf - (char *)page_address(page);
> +		offset = buf - page_address(page);
>  		if (skb_can_coalesce(curr_skb, num_skb_frags, page, offset)) {
>  			put_page(page);
>  			skb_coalesce_rx_frag(curr_skb, num_skb_frags - 1,
> @@ -351,9 +362,28 @@ static int receive_mergeable(struct receive_queue *rq, struct sk_buff *head_skb)
>  			skb_add_rx_frag(curr_skb, num_skb_frags, page,
>  					offset, len, MERGE_BUFFER_LEN);
>  		}
> +	}
> +
> +	return head_skb;
> +
> +err_skb:
> +	put_page(page);
> +err_buf:
> +	dev->stats.rx_dropped++;
> +	dev_kfree_skb(head_skb);
> +	while (--num_buf) {
> +		buf = virtqueue_get_buf(rq->vq, &len);
> +		if (unlikely(!buf)) {
> +			pr_debug("%s: rx error: %d buffers missing\n",
> +				 dev->name, num_buf);
> +			dev->stats.rx_length_errors++;
> +			break;
> +		}
> +		page = virt_to_head_page(buf);
> +		put_page(page);
>  		--rq->num;
>  	}
> -	return 0;
> +	return NULL;
>  }
>  
>  static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len)
> @@ -382,19 +412,9 @@ static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len)
>  		len -= sizeof(struct virtio_net_hdr);
>  		skb_trim(skb, len);
>  	} else if (vi->mergeable_rx_bufs) {
> -		struct page *page = virt_to_head_page(buf);
> -		skb = page_to_skb(rq, page,
> -				  (char *)buf - (char *)page_address(page),
> -				  len, MERGE_BUFFER_LEN);
> -		if (unlikely(!skb)) {
> -			dev->stats.rx_dropped++;
> -			put_page(page);
> +		skb = receive_mergeable(dev, rq, buf, len);
> +		if (unlikely(!skb))
>  			return;
> -		}
> -		if (receive_mergeable(rq, skb)) {
> -			dev_kfree_skb(skb);
> -			return;
> -		}
>  	} else {
>  		page = buf;
>  		skb = page_to_skb(rq, page, 0, len, PAGE_SIZE);

^ permalink raw reply

* [PATCH 1/8] atm: eni: use DEFINE_PCI_DEVICE_TABLE macro
From: Jingoo Han @ 2013-11-28  3:37 UTC (permalink / raw)
  To: 'David S. Miller'
  Cc: 'Chas Williams', netdev, linux-atm-general,
	'Jingoo Han', 'Francois Romieu'

This macro is used to create a struct pci_device_id array.

Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
 drivers/atm/eni.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
index b1955ba..846fc9e 100644
--- a/drivers/atm/eni.c
+++ b/drivers/atm/eni.c
@@ -2283,7 +2283,7 @@ err_disable:
 }
 
 
-static struct pci_device_id eni_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(eni_pci_tbl) = {
 	{ PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_FPGA), 0 /* FPGA */ },
 	{ PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_ASIC), 1 /* ASIC */ },
 	{ 0, }
-- 
1.7.10.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