Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net v3] bonding: disable arp and enable mii monitoring when bond change to no uses arp mode
From: Nikolay Aleksandrov @ 2013-11-22 20:01 UTC (permalink / raw)
  To: Ding Tianhong, Andy Gospodarek, Dan Williams, David Miller
  Cc: fubar, vfalico, netdev
In-Reply-To: <528F6A1B.70904@huawei.com>

On 11/22/2013 03:28 PM, Ding Tianhong wrote:
> Because the ARP monitoring is not support for 802.3ad, but I still
> could change the mode to 802.3ad from ab mode while ARP monitoring
> is running, it is incorrect.
> 
> So add a check for 802.3ad in bonding_store_mode to fix the problem,
> and make a new macro BOND_NO_USES_ARP() to simplify the code.
> 
> v2: according to the Dan Williams's suggestion, bond mode is the most
>     important bond option, it should override any of the other sub-options.
>     So when the mode is changed, the conficting values should be cleared
>     or reset, otherwise the user has to duplicate more operations to modify
>     the logic. I disable the arp and enable mii monitoring when the bond mode
>     is changed to AB, TB and 8023AD if the arp interval is true.
> 
> v3: according to the Nik's suggestion, the default value of miimon should need
>     a name, there is several place to use it, and the bond_store_arp_interval()
>     could use micro BOND_NO_USES_ARP to make the code more simpify.
> 
> Suggested-by: Dan Williams <dcbw@redhat.com>
> Suggested-by: Nikolay Aleksandrov <nikolay@redhat.com>
> Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
> ---

Reviewed-by: Nikolay Aleksandrov <nikolay@redhat.com>

^ permalink raw reply

* Re: [PATCH RFC 5/5] net: macb: Adjust tx_clk when link speed changes
From: Sören Brinkmann @ 2013-11-22 19:31 UTC (permalink / raw)
  To: Nicolas Ferre; +Cc: netdev, David Miller, linux-kernel, Michal Simek
In-Reply-To: <525CF4AD.1070304@atmel.com>

Hi Nicolas,

On Tue, Oct 15, 2013 at 09:54:21AM +0200, Nicolas Ferre wrote:
> On 15/10/2013 01:59, Soren Brinkmann :
> >Adjust the ethernet clock according to the negotiated link speed.
> >
> >Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com>
> 
> I will need more time to study this one.
> 
> Moreover, I will have to add the "tx_clk" to every user of this
> driver before switchin to the addition of this clock.

I just wanted to follow up on this. Did you have a chance to look at
this closer?

	Thanks,
	Sören

^ permalink raw reply

* Re: [PATCH] net: sctp: set chunk->tsn_gap_acked at the end of cycle
From: Chang @ 2013-11-22 19:24 UTC (permalink / raw)
  To: Vlad Yasevich, nhorman, davem; +Cc: linux-sctp, netdev, linux-kernel
In-Reply-To: <528F69B7.7020902@gmail.com>


On 11/22/2013 03:27 PM, Vlad Yasevich wrote:
> On 11/22/2013 02:49 AM, Chang Xiangzhong wrote:
>> tsn_gap_acked is an important state flag in chunk, which indicates if the
>> chunk has been acked in gap reports before.
> Actually, this bit indicates simply that the chunk has been acked.  It
> doesn't state whether it's been acked in a gap report or via cumulative tsn.
Thanks for pointing this out. Sorry for not having made that clear.
>
>> SFR-CACC algorithm depends on this
>> variable. So set this at the end of each iteration, otherwise the SFR-CACC
>> algorithm would never be toggled.
>>
>> Signed-off-by: Chang Xiangzhong <changxiangzhong@gmail.com>
>> ---
>>   net/sctp/outqueue.c | 3 ++-
>>   1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
>> index 1b494fa..bff828c 100644
>> --- a/net/sctp/outqueue.c
>> +++ b/net/sctp/outqueue.c
>> @@ -1396,7 +1396,6 @@ static void sctp_check_transmitted(struct sctp_outq *q,
>>   			 * while DATA was outstanding).
>>   			 */
>>   			if (!tchunk->tsn_gap_acked) {
>> -				tchunk->tsn_gap_acked = 1;
>>   				if (TSN_lt(*highest_new_tsn_in_sack, tsn))
>>   					*highest_new_tsn_in_sack = tsn;
>>   				bytes_acked += sctp_data_size(tchunk);
>> @@ -1460,6 +1459,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
>>   				 */
>>   				list_add_tail(lchunk, &tlist);
>>   			}
>> +
>> +			tchunk->tsn_gap_acked = 1;
> The current code will set the state if it hasn't been set yet.  Why is
> this needed?
Because in line 1420 ~ 1440 The SFR-CACC algorithms use tsn_gap_acked. 
That "if block" would never be triggered because the varaiable's been 
set. That's why I move the "state changing sentence" to the end of the 
iteration.
> Now there is an issue with tracking highest_new_tsn_in_sack.  The spec
> is a little vague on this, but the highest_new_tsn_in_sack only supposed
> to track tsns that have not been resent.  If a tsn has been reneged, and
> then sent again, it is not considered 'new' thus should not count
> toward highest_new_tsn_in_sack.  We currently do not track this right.
I'll try to figure this out.
> -vlad
>
> -vlad
>
>>   		} else {
>>   			if (tchunk->tsn_gap_acked) {
>>   				pr_debug("%s: receiver reneged on data TSN:0x%x\n",
>>

^ permalink raw reply

* Re: [PATCH net v3] bonding: disable arp and enable mii monitoring when bond change to no uses arp mode
From: Dan Williams @ 2013-11-22 19:07 UTC (permalink / raw)
  To: Ding Tianhong
  Cc: Andy Gospodarek, David Miller, fubar, nikolay, vfalico, netdev
In-Reply-To: <528F6A1B.70904@huawei.com>

On Fri, 2013-11-22 at 22:28 +0800, Ding Tianhong wrote:
> Because the ARP monitoring is not support for 802.3ad, but I still
> could change the mode to 802.3ad from ab mode while ARP monitoring
> is running, it is incorrect.
> 
> So add a check for 802.3ad in bonding_store_mode to fix the problem,
> and make a new macro BOND_NO_USES_ARP() to simplify the code.

Excellent, that's exactly what I was thinking of.  Thanks!

Dan

> v2: according to the Dan Williams's suggestion, bond mode is the most
>     important bond option, it should override any of the other sub-options.
>     So when the mode is changed, the conficting values should be cleared
>     or reset, otherwise the user has to duplicate more operations to modify
>     the logic. I disable the arp and enable mii monitoring when the bond mode
>     is changed to AB, TB and 8023AD if the arp interval is true.
> 
> v3: according to the Nik's suggestion, the default value of miimon should need
>     a name, there is several place to use it, and the bond_store_arp_interval()
>     could use micro BOND_NO_USES_ARP to make the code more simpify.
> 
> Suggested-by: Dan Williams <dcbw@redhat.com>
> Suggested-by: Nikolay Aleksandrov <nikolay@redhat.com>
> Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
> ---
>  drivers/net/bonding/bond_main.c    |  4 ++--
>  drivers/net/bonding/bond_options.c | 13 +++++++++----
>  drivers/net/bonding/bond_sysfs.c   |  4 +---
>  drivers/net/bonding/bonding.h      |  7 +++++++
>  4 files changed, 19 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
> index 4dd5ee2..36eab0c 100644
> --- a/drivers/net/bonding/bond_main.c
> +++ b/drivers/net/bonding/bond_main.c
> @@ -4110,7 +4110,7 @@ static int bond_check_params(struct bond_params *params)
>  		if (!miimon) {
>  			pr_warning("Warning: miimon must be specified, otherwise bonding will not detect link failure, speed and duplex which are essential for 802.3ad operation\n");
>  			pr_warning("Forcing miimon to 100msec\n");
> -			miimon = 100;
> +			miimon = BOND_DEFAULT_MIIMON;
>  		}
>  	}
>  
> @@ -4147,7 +4147,7 @@ static int bond_check_params(struct bond_params *params)
>  		if (!miimon) {
>  			pr_warning("Warning: miimon must be specified, otherwise bonding will not detect link failure and link speed which are essential for TLB/ALB load balancing\n");
>  			pr_warning("Forcing miimon to 100msec\n");
> -			miimon = 100;
> +			miimon = BOND_DEFAULT_MIIMON;
>  		}
>  	}
>  
> diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
> index 9a5223c..ea6f640 100644
> --- a/drivers/net/bonding/bond_options.c
> +++ b/drivers/net/bonding/bond_options.c
> @@ -45,10 +45,15 @@ int bond_option_mode_set(struct bonding *bond, int mode)
>  		return -EPERM;
>  	}
>  
> -	if (BOND_MODE_IS_LB(mode) && bond->params.arp_interval) {
> -		pr_err("%s: %s mode is incompatible with arp monitoring.\n",
> -		       bond->dev->name, bond_mode_tbl[mode].modename);
> -		return -EINVAL;
> +	if (BOND_NO_USES_ARP(mode) && bond->params.arp_interval) {
> +		pr_info("%s: %s mode is incompatible with arp monitoring, start mii monitoring\n",
> +			bond->dev->name, bond_mode_tbl[mode].modename);
> +		/* disable arp monitoring */
> +		bond->params.arp_interval = 0;
> +		/* set miimon to default value */
> +		bond->params.miimon = BOND_DEFAULT_MIIMON;
> +		pr_info("%s: Setting MII monitoring interval to %d.\n",
> +			bond->dev->name, bond->params.miimon);
>  	}
>  
>  	/* don't cache arp_validate between modes */
> diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
> index 0ec2a7e..abf5e10 100644
> --- a/drivers/net/bonding/bond_sysfs.c
> +++ b/drivers/net/bonding/bond_sysfs.c
> @@ -523,9 +523,7 @@ static ssize_t bonding_store_arp_interval(struct device *d,
>  		ret = -EINVAL;
>  		goto out;
>  	}
> -	if (bond->params.mode == BOND_MODE_ALB ||
> -	    bond->params.mode == BOND_MODE_TLB ||
> -	    bond->params.mode == BOND_MODE_8023AD) {
> +	if (BOND_NO_USES_ARP(bond->params.mode)) {
>  		pr_info("%s: ARP monitoring cannot be used with ALB/TLB/802.3ad. Only MII monitoring is supported on %s.\n",
>  			bond->dev->name, bond->dev->name);
>  		ret = -EINVAL;
> diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
> index ca31286..a9f4f9f 100644
> --- a/drivers/net/bonding/bonding.h
> +++ b/drivers/net/bonding/bonding.h
> @@ -35,6 +35,8 @@
>  
>  #define BOND_MAX_ARP_TARGETS	16
>  
> +#define BOND_DEFAULT_MIIMON	100
> +
>  #define IS_UP(dev)					   \
>  	      ((((dev)->flags & IFF_UP) == IFF_UP)	&& \
>  	       netif_running(dev)			&& \
> @@ -55,6 +57,11 @@
>  		 ((mode) == BOND_MODE_TLB)          ||	\
>  		 ((mode) == BOND_MODE_ALB))
>  
> +#define BOND_NO_USES_ARP(mode)				\
> +		(((mode) == BOND_MODE_8023AD)	||	\
> +		 ((mode) == BOND_MODE_TLB)	||	\
> +		 ((mode) == BOND_MODE_ALB))
> +
>  #define TX_QUEUE_OVERRIDE(mode)				\
>  			(((mode) == BOND_MODE_ACTIVEBACKUP) ||	\
>  			 ((mode) == BOND_MODE_ROUNDROBIN))

^ permalink raw reply

* [PATCH net 3/3] be2net: Avoid programming permenant MAC by BE3-R VFs
From: Ajit Khaparde @ 2013-11-22 18:51 UTC (permalink / raw)
  To: netdev

On BE3-R, the PF programs the initial MAC address for its VFs. Doing it again
in VF probe, causes a FW error which although harmless generates
an unnecessary error log message.

Signed-off-by: Vasundhara Volam <vasundhara.volam@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>
---
 drivers/net/ethernet/emulex/benet/be.h      |  1 +
 drivers/net/ethernet/emulex/benet/be_main.c | 10 ++++------
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index f4825db..5878df6 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -503,6 +503,7 @@ struct be_adapter {
 };
 
 #define be_physfn(adapter)		(!adapter->virtfn)
+#define be_virtfn(adapter)		(adapter->virtfn)
 #define	sriov_enabled(adapter)		(adapter->num_vfs > 0)
 #define sriov_want(adapter)             (be_physfn(adapter) &&	\
 					 (num_vfs || pci_num_vf(adapter->pdev)))
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 9b148cf..78a0e85 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -3253,12 +3253,10 @@ static int be_mac_setup(struct be_adapter *adapter)
 		memcpy(mac, adapter->netdev->dev_addr, ETH_ALEN);
 	}
 
-	/* On BE3 VFs this cmd may fail due to lack of privilege.
-	 * Ignore the failure as in this case pmac_id is fetched
-	 * in the IFACE_CREATE cmd.
-	 */
-	be_cmd_pmac_add(adapter, mac, adapter->if_handle,
-			&adapter->pmac_id[0], 0);
+	/* For BE3-R VFs, the PF programs the initial MAC address */
+	if (!(BEx_chip(adapter) && be_virtfn(adapter)))
+		be_cmd_pmac_add(adapter, mac, adapter->if_handle,
+				&adapter->pmac_id[0], 0);
 	return 0;
 }
 
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH net 2/3] be2net: set coalesce-wm in CQ_CREATE_V2 cmd
From: Ajit Khaparde @ 2013-11-22 18:51 UTC (permalink / raw)
  To: netdev

It is not being set currently. (This field is not applicable for Lancer)

Signed-off-by: Vasundhara Volam <vasundhara.volam@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>
---
 drivers/net/ethernet/emulex/benet/be_cmds.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index dbcd526..e0e8bc1 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -1032,6 +1032,13 @@ int be_cmd_cq_create(struct be_adapter *adapter, struct be_queue_info *cq,
 	} else {
 		req->hdr.version = 2;
 		req->page_size = 1; /* 1 for 4K */
+
+		/* coalesce-wm field in this cmd is not relevant to Lancer.
+		 * Lancer uses COMMON_MODIFY_CQ to set this field
+		 */
+		if (!lancer_chip(adapter))
+			AMAP_SET_BITS(struct amap_cq_context_v2, coalescwm,
+				      ctxt, coalesce_wm);
 		AMAP_SET_BITS(struct amap_cq_context_v2, nodelay, ctxt,
 								no_delay);
 		AMAP_SET_BITS(struct amap_cq_context_v2, count, ctxt,
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH net 1/3] be2net: Disabling and enabling interrupts in suspend and resume
From: Ajit Khaparde @ 2013-11-22 18:51 UTC (permalink / raw)
  To: netdev

Interrupts need to be enabled in be_resume, when adapter boots back up from D3cold.

disabling interrupts in be_suspend() just to be symmetric to be_resume().

Signed-off-by: Ravikumar Nelavelli <ravikumar.nelavelli@emulex.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>
---
 drivers/net/ethernet/emulex/benet/be_main.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index abde974..9b148cf 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -4599,6 +4599,7 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state)
 	if (adapter->wol)
 		be_setup_wol(adapter, true);
 
+	be_intr_set(adapter, false);
 	cancel_delayed_work_sync(&adapter->func_recovery_work);
 
 	netif_device_detach(netdev);
@@ -4634,6 +4635,7 @@ static int be_resume(struct pci_dev *pdev)
 	if (status)
 		return status;
 
+	be_intr_set(adapter, true);
 	/* tell fw we're ready to fire cmds */
 	status = be_cmd_fw_init(adapter);
 	if (status)
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH net 0/3] be2net: Patch set
From: Ajit Khaparde @ 2013-11-22 18:50 UTC (permalink / raw)
  To: netdev

Please apply.

Ravikumar Nelavelli (1):
  be2net: Disabling and enabling interrupts in suspend and resume

Vasundhara Volam (2):
  be2net: set coalesce-wm in CQ_CREATE_V2 cmd
  be2net: Avoid programming permenant MAC by BE3-R VFs

 drivers/net/ethernet/emulex/benet/be.h      |  1 +
 drivers/net/ethernet/emulex/benet/be_cmds.c |  7 +++++++
 drivers/net/ethernet/emulex/benet/be_main.c | 12 ++++++------
 3 files changed, 14 insertions(+), 6 deletions(-)

-- 
1.8.1.2

^ permalink raw reply

* [PATCH net] netem: fix loss generators
From: Stephen Hemminger @ 2013-11-22  1:54 UTC (permalink / raw)
  To: David Miller, stefano.salsano; +Cc: netdev

Patch from developers of the alternative loss models, downloaded from:
   http://netgroup.uniroma2.it/twiki/bin/view.cgi/Main/NetemCLG

We found some bugs in our first implementation.
A first set of bugs is in the function loss_4state:
   In the case 1 of the switch statement in the if conditions we
    need to add clg->a4 to clg->a1, according to the model.
   In the case 3 of the switch statement we need to delete "return
    true" if the condition leads us in the state 1, because the state 1 is
    a good state.

A second set of bugs is in the function loss_gilb_ell
  In both cases of the switch statement we need to add the break
    statement, because the two cases are mutually exclusive.
  In the case 2, of the switch we change the direction of the inequality to
    net_random()>clg->a3, because clg->a3 is h in the GE model and when h
    is 0 all packets will be lost.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>

--- a/net/sched/sch_netem.c	2013-11-21 17:22:03.655649667 -0800
+++ b/net/sched/sch_netem.c	2013-11-21 17:24:46.438773795 -0800
@@ -215,10 +215,10 @@ static bool loss_4state(struct netem_sch
 		if (rnd < clg->a4) {
 			clg->state = 4;
 			return true;
-		} else if (clg->a4 < rnd && rnd < clg->a1) {
+		} else if (clg->a4 < rnd && rnd < clg->a1 + clg->a4) {
 			clg->state = 3;
 			return true;
-		} else if (clg->a1 < rnd)
+		} else if (clg->a1 + clg->a4 < rnd)
 			clg->state = 1;
 
 		break;
@@ -235,6 +235,7 @@ static bool loss_4state(struct netem_sch
 			clg->state = 2;
 		else if (clg->a3 < rnd && rnd < clg->a2 + clg->a3) {
 			clg->state = 1;
+			return true;
 		} else if (clg->a2 + clg->a3 < rnd) {
 			clg->state = 3;
 			return true;
@@ -268,11 +269,13 @@ static bool loss_gilb_ell(struct netem_s
 			clg->state = 2;
 		if (net_random() < clg->a4)
 			return true;
+		break;
 	case 2:
 		if (net_random() < clg->a2)
 			clg->state = 1;
-		if (clg->a3 > net_random())
+		if (net_random() > clg->a3)
 			return true;
+		break;
 	}
 
 	return false;

^ permalink raw reply

* gem csum breakage with 018c5bba (Handle CHECKSUM_COMPLETE more adequately ...)
From: Alexander Graf @ 2013-11-22 18:08 UTC (permalink / raw)
  To: David Miller
  Cc: herbert, alexander.h.duyck, netdev, edumazet, herbert,
	linux-kernel@vger.kernel.org list, Ben Herrenschmidt

Hi,

With current Linus' master tree my ibook started emitting a lot of annoying csum calculation warnings. I've bisected it down to the commit seen in the subject line, but I suppose the real problem lies somewhere a lot deeper and only gets revealed thanks to the more clever checksum logic applied now.

Any ideas how to dig further into this?


Thanks,

Alex

---

<unknown>: hw csum failure
CPU: 0 PID: 0 Comm: swapper Not tainted 3.12.0+ #1
Call Trace:
[efff1d00] [c00090f0] show_stack+0x48/0x150 (unreliable)
[efff1d40] [c049f794] csum_partial_copy_to_xdr+0xf8/0x168
[efff1d60] [c04a1120] xs_udp_data_ready+0xbc/0x140
[efff1d90] [c03f99f4] sock_queue_rcv_skb+0x144/0x1c0
[efff1db0] [c045aa28] __udp_queue_rcv_skb+0x38/0xd4
[efff1dc0] [c045de5c] udp_queue_rcv_skb+0x260/0x3ac
[efff1de0] [c045e6dc] __udp4_lib_rcv+0x2c8/0x63c
[efff1e20] [c0432a78] ip_local_deliver_finish+0x100/0x268
[efff1e40] [c0408264] __netif_receive_skb_core+0x510/0x690
[efff1ea0] [c040b78c] napi_gro_receive+0xac/0xd8
[efff1eb0] [c0353b94] gem_poll+0x5bc/0x116c
[efff1f50] [c040a60c] net_rx_action+0x118/0x1fc
[efff1f90] [c0046afc] __do_softirq+0xd4/0x1c4
[efff1fe0] [c0046f04] irq_exit+0x94/0xb8
[efff1ff0] [c000ef30] call_do_irq+0x24/0x3c
[c0733e90] [c0006ca4] do_IRQ+0x64/0xb4
[c0733eb0] [c0011b34] ret_from_except+0x0/0x1c
--- Exception: 501 at arch_cpu_idle+0x24/0x6c
    LR = arch_cpu_idle+0x24/0x6c
[c0733f70] [c0082638] rcu_idle_enter+0x84/0xc4 (unreliable)
[c0733f80] [c007c4b0] cpu_startup_entry+0xa4/0x16c
[c0733fb0] [c06caf54] start_kernel+0x308/0x31c
[c0733ff0] [00003d34] 0x3d34

^ permalink raw reply

* Re: [PATCH 3/7] netfilter: synproxy: correct wscale option passing
From: Sergei Shtylyov @ 2013-11-22 17:19 UTC (permalink / raw)
  To: Pablo Neira Ayuso, netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1385024728-4057-4-git-send-email-pablo@netfilter.org>

Hello.

On 21-11-2013 13:05, Pablo Neira Ayuso wrote:

> From: Martin Topholm <mph@one.com>

> Timestamp are used to store additional syncookie parameters such as sack,
> ecn, and wscale. The wscale value we need to encode is the client's
> wscale, since we can't recover that later in the session. Next overwrite
> the wscale option so the later synproxy_send_client_synack will send
> the backend's wscale to the client.

> Signed-off-by: Martin Topholm <mph@one.com>
> Reviewed-by: Jesper Dangaard Brouer <brouer@redhat.com>
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> ---
>   net/netfilter/nf_synproxy_core.c |    7 ++++---
>   1 file changed, 4 insertions(+), 3 deletions(-)

> diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c
> index cdf4567..9858e3e 100644
> --- a/net/netfilter/nf_synproxy_core.c
> +++ b/net/netfilter/nf_synproxy_core.c
> @@ -151,9 +151,10 @@ void synproxy_init_timestamp_cookie(const struct xt_synproxy_info *info,
>   	opts->tsecr = opts->tsval;
>   	opts->tsval = tcp_time_stamp & ~0x3f;
>
> -	if (opts->options & XT_SYNPROXY_OPT_WSCALE)
> -		opts->tsval |= info->wscale;
> -	else
> +	if (opts->options & XT_SYNPROXY_OPT_WSCALE) {
> +		opts->tsval |= opts->wscale;
> +		opts->wscale = info->wscale;
> +	} else
>   		opts->tsval |= 0xf;

    According to Documentation/CodingStyle, both arms of *if* statement should 
have {} if one arm has it.

WBR, Sergei

^ permalink raw reply

* Re: [PATCH 4/7] netfilter: fix wrong byte order in nf_ct_seqadj_set internal information
From: Sergei Shtylyov @ 2013-11-22 17:16 UTC (permalink / raw)
  To: Pablo Neira Ayuso, netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1385024728-4057-5-git-send-email-pablo@netfilter.org>

Hello.

On 21-11-2013 13:05, Pablo Neira Ayuso wrote:

> From: Phil Oester <kernel@linuxace.com>

> In commit 41d73ec053d2, sequence number adjustments were moved to a

    Please also specify that commit's summary line in parens.

> separate file. Unfortunately, the sequence numbers that are stored
> in the nf_ct_seqadj structure are expressed in host byte order. The
> necessary ntohl call was removed when the call to adjust_tcp_sequence
> was collapsed into nf_ct_seqadj_set. This broke the FTP NAT helper.
> Fix it by adding back the byte order conversions.

> Reported-by: Dawid Stawiarski <dawid.stawiarski@netart.pl>
> Signed-off-by: Phil Oester <kernel@linuxace.com>
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

WBR, Sergei


^ permalink raw reply

* [PATCH net-next 7/8] openvswitch: Drop user features if old user space attempted to create datapath
From: Thomas Graf @ 2013-11-22 16:56 UTC (permalink / raw)
  To: jesse, davem
  Cc: dev, netdev, dborkman, ffusco, fleitner, eric.dumazet, bhutchings
In-Reply-To: <cover.1385137618.git.tgraf@suug.ch>

Drop user features if an outdated user space instance that does not
understand the concept of user_features attempted to create a new
datapath.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
Reviewed-by: Daniel Borkmann <dborkman@redhat.com>
---
 include/uapi/linux/openvswitch.h | 10 +++++++++-
 net/openvswitch/datapath.c       |  9 +++++++++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h
index 07ef2c3..a6863e2 100644
--- a/include/uapi/linux/openvswitch.h
+++ b/include/uapi/linux/openvswitch.h
@@ -40,7 +40,15 @@ struct ovs_header {
 
 #define OVS_DATAPATH_FAMILY  "ovs_datapath"
 #define OVS_DATAPATH_MCGROUP "ovs_datapath"
-#define OVS_DATAPATH_VERSION 0x1
+
+/* V2:
+ *   - API users are expected to provide OVS_DP_ATTR_USER_FEATURES
+ *     with NLM_F_REPLACE when creating the datapath.
+ */
+#define OVS_DATAPATH_VERSION 2
+
+/* First OVS datapath version to support features */
+#define OVS_DP_VER_FEATURES 2
 
 enum ovs_datapath_cmd {
 	OVS_DP_CMD_UNSPEC,
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 3f1fb87..f6c1b1e 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -1198,6 +1198,15 @@ static int ovs_dp_create_or_update(struct sk_buff *skb, struct genl_info *info,
 		if (info->nlhdr->nlmsg_flags & NLM_F_REPLACE)
 			goto update;
 
+		/* An outdated user space instance that does not understand
+		 * the concept of user_features has attempted to create a new
+		 * datapath. Drop all user features.
+		 */
+		if (info->genlhdr->version < OVS_DP_VER_FEATURES) {
+			WARN(dp->user_features, "Dropping previously announced user features\n");
+			dp->user_features = 0;
+		}
+
 		err = -EEXIST;
 		goto err_unlock_ovs;
 	}
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next 8/8] openvswitch: Use skb_zerocopy() for upcall
From: Thomas Graf @ 2013-11-22 16:56 UTC (permalink / raw)
  To: jesse, davem
  Cc: dev, netdev, dborkman, ffusco, fleitner, eric.dumazet, bhutchings
In-Reply-To: <cover.1385137618.git.tgraf@suug.ch>

Use of skb_zerocopy() can avoids the expensive call to memcpy()
when copying the packet data into the Netlink skb. Completes
checksum through skb_checksum_help() if needed.

Zerocopy is only performed if user space supported unaligned
Netlink messages. memory mapped netlink i/o is preferred over
zerocopy if it is set up.

Cost of upcall is significantly reduced from:
+   7.48%       vhost-8471  [k] memcpy
+   5.57%     ovs-vswitchd  [k] memcpy
+   2.81%       vhost-8471  [k] csum_partial_copy_generic

to:
+   5.72%     ovs-vswitchd  [k] memcpy
+   3.32%       vhost-5153  [k] memcpy
+   0.68%       vhost-5153  [k] skb_zerocopy

(megaflows disabled)

Signed-off-by: Thomas Graf <tgraf@suug.ch>
Reviewed-by: Daniel Borkmann <dborkman@redhat.com>
---
 net/openvswitch/datapath.c | 54 +++++++++++++++++++++++++++++++---------------
 1 file changed, 37 insertions(+), 17 deletions(-)

diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index f6c1b1e..5b3efb6 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -108,10 +108,10 @@ int lockdep_ovsl_is_held(void)
 #endif
 
 static struct vport *new_vport(const struct vport_parms *);
-static int queue_gso_packets(struct net *, int dp_ifindex, struct sk_buff *,
-			     const struct dp_upcall_info *);
-static int queue_userspace_packet(struct net *, int dp_ifindex,
-				  struct sk_buff *,
+static int queue_gso_packets(struct datapath *, struct net *, int dp_ifindex,
+			     struct sk_buff *, const struct dp_upcall_info *);
+static int queue_userspace_packet(struct datapath *, struct net *,
+				  int dp_ifindex, struct sk_buff *,
 				  const struct dp_upcall_info *);
 
 /* Must be called with rcu_read_lock or ovs_mutex. */
@@ -292,9 +292,9 @@ int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb,
 	}
 
 	if (!skb_is_gso(skb))
-		err = queue_userspace_packet(ovs_dp_get_net(dp), dp_ifindex, skb, upcall_info);
+		err = queue_userspace_packet(dp, ovs_dp_get_net(dp), dp_ifindex, skb, upcall_info);
 	else
-		err = queue_gso_packets(ovs_dp_get_net(dp), dp_ifindex, skb, upcall_info);
+		err = queue_gso_packets(dp, ovs_dp_get_net(dp), dp_ifindex, skb, upcall_info);
 	if (err)
 		goto err;
 
@@ -310,7 +310,7 @@ err:
 	return err;
 }
 
-static int queue_gso_packets(struct net *net, int dp_ifindex,
+static int queue_gso_packets(struct datapath *dp, struct net *net, int dp_ifindex,
 			     struct sk_buff *skb,
 			     const struct dp_upcall_info *upcall_info)
 {
@@ -327,7 +327,7 @@ static int queue_gso_packets(struct net *net, int dp_ifindex,
 	/* Queue all of the segments. */
 	skb = segs;
 	do {
-		err = queue_userspace_packet(net, dp_ifindex, skb, upcall_info);
+		err = queue_userspace_packet(dp, net, dp_ifindex, skb, upcall_info);
 		if (err)
 			break;
 
@@ -381,10 +381,11 @@ static size_t key_attr_size(void)
 }
 
 static size_t upcall_msg_size(const struct sk_buff *skb,
-			      const struct nlattr *userdata)
+			      const struct nlattr *userdata,
+			      unsigned int hdrlen)
 {
 	size_t size = NLMSG_ALIGN(sizeof(struct ovs_header))
-		+ nla_total_size(skb->len) /* OVS_PACKET_ATTR_PACKET */
+		+ nla_total_size(hdrlen) /* OVS_PACKET_ATTR_PACKET */
 		+ nla_total_size(key_attr_size()); /* OVS_PACKET_ATTR_KEY */
 
 	/* OVS_PACKET_ATTR_USERDATA */
@@ -394,8 +395,8 @@ static size_t upcall_msg_size(const struct sk_buff *skb,
 	return size;
 }
 
-static int queue_userspace_packet(struct net *net, int dp_ifindex,
-				  struct sk_buff *skb,
+static int queue_userspace_packet(struct datapath *dp, struct net *net,
+				  int dp_ifindex, struct sk_buff *skb,
 				  const struct dp_upcall_info *upcall_info)
 {
 	struct ovs_header *upcall;
@@ -407,6 +408,7 @@ static int queue_userspace_packet(struct net *net, int dp_ifindex,
 		.snd_portid = upcall_info->portid,
 	};
 	size_t len;
+	unsigned int hlen;
 	int err;
 
 	if (vlan_tx_tag_present(skb)) {
@@ -427,7 +429,21 @@ static int queue_userspace_packet(struct net *net, int dp_ifindex,
 		goto out;
 	}
 
-	len = upcall_msg_size(skb, upcall_info->userdata);
+	/* Complete checksum if needed */
+	if (skb->ip_summed == CHECKSUM_PARTIAL &&
+	    (err = skb_checksum_help(skb)))
+		goto out;
+
+	/* Older versions of OVS user space enforce alignment of the last
+	 * Netlink attribute to NLA_ALIGNTO which would require extensive
+	 * padding logic. Only perform zerocopy if padding is not required.
+	 */
+	if (dp->user_features & OVS_DP_F_UNALIGNED)
+		hlen = skb_zerocopy_headlen(skb);
+	else
+		hlen = skb->len;
+
+	len = upcall_msg_size(skb, upcall_info->userdata, hlen);
 	user_skb = genlmsg_new_unicast(len, &info, GFP_ATOMIC);
 	if (!user_skb) {
 		err = -ENOMEM;
@@ -447,13 +463,17 @@ static int queue_userspace_packet(struct net *net, int dp_ifindex,
 			  nla_len(upcall_info->userdata),
 			  nla_data(upcall_info->userdata));
 
-	nla = __nla_reserve(user_skb, OVS_PACKET_ATTR_PACKET, skb->len);
+	/* Only reserve room for attribute header, packet data is added
+	 * in skb_zerocopy() */
+	if (!(nla = nla_reserve(user_skb, OVS_PACKET_ATTR_PACKET, 0)))
+		goto out;
+	nla->nla_len = nla_attr_size(skb->len);
+
+	skb_zerocopy(user_skb, skb, skb->len, hlen);
 
-	skb_copy_and_csum_dev(skb, nla_data(nla));
+	((struct nlmsghdr *) user_skb->data)->nlmsg_len = user_skb->len;
 
-	genlmsg_end(user_skb, upcall);
 	err = genlmsg_unicast(net, user_skb, upcall_info->portid);
-
 out:
 	kfree_skb(nskb);
 	return err;
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next 6/8] openvswitch: Allow update of dp with OVS_DP_CMD_NEW if NLM_F_REPLACE is set
From: Thomas Graf @ 2013-11-22 16:56 UTC (permalink / raw)
  To: jesse, davem
  Cc: dev, netdev, dborkman, ffusco, fleitner, eric.dumazet, bhutchings
In-Reply-To: <cover.1385137618.git.tgraf@suug.ch>

Consolidates ovs_dp_cmd_new() and ovs_dp_cmd_set() to simplify
handling and avoid code duplication.

Allows user space to specify NLM_F_REPLACE with OVS_DP_CMD_NEW and
overwrite the settings such as the user features of an existing
datapath.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
Reviewed-by: Daniel Borkmann <dborkman@redhat.com>
---
 net/openvswitch/datapath.c | 83 +++++++++++++++++++++++-----------------------
 1 file changed, 42 insertions(+), 41 deletions(-)

diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 95d4424..3f1fb87 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -1175,13 +1175,8 @@ static struct datapath *lookup_datapath(struct net *net,
 	return dp ? dp : ERR_PTR(-ENODEV);
 }
 
-static void ovs_dp_change(struct datapath *dp, struct nlattr **a)
-{
-	if (a[OVS_DP_ATTR_USER_FEATURES])
-		dp->user_features = nla_get_u32(a[OVS_DP_ATTR_USER_FEATURES]);
-}
-
-static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
+static int ovs_dp_create_or_update(struct sk_buff *skb, struct genl_info *info,
+				   bool create)
 {
 	struct nlattr **a = info->attrs;
 	struct vport_parms parms;
@@ -1190,6 +1185,7 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
 	struct vport *vport;
 	struct ovs_net *ovs_net;
 	int err, i;
+	bool allocated = false;
 
 	err = -EINVAL;
 	if (!a[OVS_DP_ATTR_NAME] || !a[OVS_DP_ATTR_UPCALL_PID])
@@ -1197,11 +1193,26 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
 
 	ovs_lock();
 
+	dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
+	if (!IS_ERR(dp)) {
+		if (info->nlhdr->nlmsg_flags & NLM_F_REPLACE)
+			goto update;
+
+		err = -EEXIST;
+		goto err_unlock_ovs;
+	}
+
+	if (!create) {
+		err = PTR_ERR(dp);
+		goto err_unlock_ovs;
+	}
+
 	err = -ENOMEM;
 	dp = kzalloc(sizeof(*dp), GFP_KERNEL);
 	if (dp == NULL)
 		goto err_unlock_ovs;
 
+	allocated = true;
 	ovs_dp_set_net(dp, hold_net(sock_net(skb->sk)));
 
 	/* Allocate table. */
@@ -1239,8 +1250,6 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
 	parms.port_no = OVSP_LOCAL;
 	parms.upcall_portid = nla_get_u32(a[OVS_DP_ATTR_UPCALL_PID]);
 
-	ovs_dp_change(dp, a);
-
 	vport = new_vport(&parms);
 	if (IS_ERR(vport)) {
 		err = PTR_ERR(vport);
@@ -1250,13 +1259,27 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
 		goto err_destroy_ports_array;
 	}
 
+update:
+	if (a[OVS_DP_ATTR_USER_FEATURES])
+		dp->user_features = nla_get_u32(a[OVS_DP_ATTR_USER_FEATURES]);
+
 	reply = ovs_dp_cmd_build_info(dp, info, OVS_DP_CMD_NEW);
 	err = PTR_ERR(reply);
-	if (IS_ERR(reply))
-		goto err_destroy_local_port;
+	if (IS_ERR(reply)) {
+		if (allocated)
+			goto err_destroy_local_port;
+		else {
+			err = 0;
+			genl_set_err(&dp_datapath_genl_family, sock_net(skb->sk), 0,
+				     0, err);
+			goto err_unlock_ovs;
+		}
+	}
 
-	ovs_net = net_generic(ovs_dp_get_net(dp), ovs_net_id);
-	list_add_tail_rcu(&dp->list_node, &ovs_net->dps);
+	if (allocated) {
+		ovs_net = net_generic(ovs_dp_get_net(dp), ovs_net_id);
+		list_add_tail_rcu(&dp->list_node, &ovs_net->dps);
+	}
 
 	ovs_unlock();
 
@@ -1280,6 +1303,11 @@ err:
 	return err;
 }
 
+static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
+{
+	return ovs_dp_create_or_update(skb, info, true);
+}
+
 /* Called with ovs_mutex. */
 static void __dp_destroy(struct datapath *dp)
 {
@@ -1334,34 +1362,7 @@ unlock:
 
 static int ovs_dp_cmd_set(struct sk_buff *skb, struct genl_info *info)
 {
-	struct sk_buff *reply;
-	struct datapath *dp;
-	int err;
-
-	ovs_lock();
-	dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
-	err = PTR_ERR(dp);
-	if (IS_ERR(dp))
-		goto unlock;
-
-	ovs_dp_change(dp, info->attrs);
-
-	reply = ovs_dp_cmd_build_info(dp, info, OVS_DP_CMD_NEW);
-	if (IS_ERR(reply)) {
-		err = PTR_ERR(reply);
-		genl_set_err(&dp_datapath_genl_family, sock_net(skb->sk), 0,
-			     0, err);
-		err = 0;
-		goto unlock;
-	}
-
-	ovs_unlock();
-	ovs_notify(&dp_datapath_genl_family, reply, info);
-
-	return 0;
-unlock:
-	ovs_unlock();
-	return err;
+	return ovs_dp_create_or_update(skb, info, false);
 }
 
 static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info)
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next 5/8] openvswitch: Allow user space to announce ability to accept unaligned Netlink messages
From: Thomas Graf @ 2013-11-22 16:56 UTC (permalink / raw)
  To: jesse, davem
  Cc: dev, netdev, dborkman, ffusco, fleitner, eric.dumazet, bhutchings
In-Reply-To: <cover.1385137618.git.tgraf@suug.ch>

Signed-off-by: Thomas Graf <tgraf@suug.ch>
Reviewed-by: Daniel Borkmann <dborkman@redhat.com>
---
 include/uapi/linux/openvswitch.h |  4 ++++
 net/openvswitch/datapath.c       | 14 ++++++++++++++
 net/openvswitch/datapath.h       |  2 ++
 3 files changed, 20 insertions(+)

diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h
index d120f9f..07ef2c3 100644
--- a/include/uapi/linux/openvswitch.h
+++ b/include/uapi/linux/openvswitch.h
@@ -75,6 +75,7 @@ enum ovs_datapath_attr {
 	OVS_DP_ATTR_UPCALL_PID,		/* Netlink PID to receive upcalls */
 	OVS_DP_ATTR_STATS,		/* struct ovs_dp_stats */
 	OVS_DP_ATTR_MEGAFLOW_STATS,	/* struct ovs_dp_megaflow_stats */
+	OVS_DP_ATTR_USER_FEATURES,	/* OVS_DP_F_*  */
 	__OVS_DP_ATTR_MAX
 };
 
@@ -106,6 +107,9 @@ struct ovs_vport_stats {
 	__u64   tx_dropped;		/* no space available in linux  */
 };
 
+/* Allow last Netlink attribute to be unaligned */
+#define OVS_DP_F_UNALIGNED	(1 << 0)
+
 /* Fixed logical ports. */
 #define OVSP_LOCAL      ((__u32)0)
 
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 0ac9cde..95d4424 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -1067,6 +1067,7 @@ static const struct genl_ops dp_flow_genl_ops[] = {
 static const struct nla_policy datapath_policy[OVS_DP_ATTR_MAX + 1] = {
 	[OVS_DP_ATTR_NAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ - 1 },
 	[OVS_DP_ATTR_UPCALL_PID] = { .type = NLA_U32 },
+	[OVS_DP_ATTR_USER_FEATURES] = { .type = NLA_U32 },
 };
 
 static struct genl_family dp_datapath_genl_family = {
@@ -1125,6 +1126,9 @@ static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb,
 			&dp_megaflow_stats))
 		goto nla_put_failure;
 
+	if (nla_put_u32(skb, OVS_DP_ATTR_USER_FEATURES, dp->user_features))
+		goto nla_put_failure;
+
 	return genlmsg_end(skb, ovs_header);
 
 nla_put_failure:
@@ -1171,6 +1175,12 @@ static struct datapath *lookup_datapath(struct net *net,
 	return dp ? dp : ERR_PTR(-ENODEV);
 }
 
+static void ovs_dp_change(struct datapath *dp, struct nlattr **a)
+{
+	if (a[OVS_DP_ATTR_USER_FEATURES])
+		dp->user_features = nla_get_u32(a[OVS_DP_ATTR_USER_FEATURES]);
+}
+
 static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
 {
 	struct nlattr **a = info->attrs;
@@ -1229,6 +1239,8 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
 	parms.port_no = OVSP_LOCAL;
 	parms.upcall_portid = nla_get_u32(a[OVS_DP_ATTR_UPCALL_PID]);
 
+	ovs_dp_change(dp, a);
+
 	vport = new_vport(&parms);
 	if (IS_ERR(vport)) {
 		err = PTR_ERR(vport);
@@ -1332,6 +1344,8 @@ static int ovs_dp_cmd_set(struct sk_buff *skb, struct genl_info *info)
 	if (IS_ERR(dp))
 		goto unlock;
 
+	ovs_dp_change(dp, info->attrs);
+
 	reply = ovs_dp_cmd_build_info(dp, info, OVS_DP_CMD_NEW);
 	if (IS_ERR(reply)) {
 		err = PTR_ERR(reply);
diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h
index 4067ea4..193e2e0 100644
--- a/net/openvswitch/datapath.h
+++ b/net/openvswitch/datapath.h
@@ -88,6 +88,8 @@ struct datapath {
 	/* Network namespace ref. */
 	struct net *net;
 #endif
+
+	u32 user_features;
 };
 
 /**
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next 4/8] net: Export skb_zerocopy() to zerocopy from one skb to another
From: Thomas Graf @ 2013-11-22 16:56 UTC (permalink / raw)
  To: jesse, davem
  Cc: dev, netdev, dborkman, ffusco, fleitner, eric.dumazet, bhutchings
In-Reply-To: <cover.1385137618.git.tgraf@suug.ch>

Make the skb zerocopy logic written for nfnetlink queue available for
use by other modules.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
Reviewed-by: Daniel Borkmann <dborkman@redhat.com>
---
 include/linux/skbuff.h               |  3 ++
 net/core/skbuff.c                    | 85 ++++++++++++++++++++++++++++++++++++
 net/netfilter/nfnetlink_queue_core.c | 59 ++-----------------------
 3 files changed, 92 insertions(+), 55 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index bec1cc7..7c48e2d 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2345,6 +2345,9 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset,
 		    struct pipe_inode_info *pipe, unsigned int len,
 		    unsigned int flags);
 void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to);
+unsigned int skb_zerocopy_headlen(const struct sk_buff *from);
+void skb_zerocopy(struct sk_buff *to, const struct sk_buff *from,
+		  int len, int hlen);
 void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len);
 int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen);
 void skb_scrub_packet(struct sk_buff *skb, bool xnet);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 2718fed..55859cb 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2122,6 +2122,91 @@ __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset,
 }
 EXPORT_SYMBOL(skb_copy_and_csum_bits);
 
+ /**
+ *	skb_zerocopy_headlen - Calculate headroom needed for skb_zerocopy()
+ *	@from: source buffer
+ *
+ *	Calculates the amount of linear headroom needed in the 'to' skb passed
+ *	into skb_zerocopy().
+ */
+unsigned int
+skb_zerocopy_headlen(const struct sk_buff *from)
+{
+	unsigned int hlen = 0;
+
+	if (!from->head_frag ||
+	    skb_headlen(from) < L1_CACHE_BYTES ||
+	    skb_shinfo(from)->nr_frags >= MAX_SKB_FRAGS)
+		hlen = skb_headlen(from);
+
+	if (skb_has_frag_list(from))
+		hlen = from->len;
+
+	return hlen;
+}
+EXPORT_SYMBOL_GPL(skb_zerocopy_headlen);
+
+/**
+ *	skb_zerocopy - Zero copy skb to skb
+ *	@to: destination buffer
+ *	@source: source buffer
+ *	@len: number of bytes to copy from source buffer
+ *	@hlen: size of linear headroom in destination buffer
+ *
+ *	Copies up to `len` bytes from `from` to `to` by creating references
+ *	to the frags in the source buffer.
+ *
+ *	The `hlen` as calculated by skb_zerocopy_headlen() specifies the
+ *	headroom in the `to` buffer.
+ */
+void
+skb_zerocopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen)
+{
+	int i, j = 0;
+	int plen = 0; /* length of skb->head fragment */
+	struct page *page;
+	unsigned int offset;
+
+	BUG_ON(!from->head_frag && !hlen);
+
+	/* dont bother with small payloads */
+	if (len <= skb_tailroom(to)) {
+		skb_copy_bits(from, 0, skb_put(to, len), len);
+		return;
+	}
+
+	if (hlen) {
+		skb_copy_bits(from, 0, skb_put(to, hlen), hlen);
+		len -= hlen;
+	} else {
+		plen = min_t(int, skb_headlen(from), len);
+		if (plen) {
+			page = virt_to_head_page(from->head);
+			offset = from->data - (unsigned char *)page_address(page);
+			__skb_fill_page_desc(to, 0, page, offset, plen);
+			get_page(page);
+			j = 1;
+			len -= plen;
+		}
+	}
+
+	to->truesize += len + plen;
+	to->len += len + plen;
+	to->data_len += len + plen;
+
+	for (i = 0; i < skb_shinfo(from)->nr_frags; i++) {
+		if (!len)
+			break;
+		skb_shinfo(to)->frags[j] = skb_shinfo(from)->frags[i];
+		skb_shinfo(to)->frags[j].size = min_t(int, skb_shinfo(to)->frags[j].size, len);
+		len -= skb_shinfo(to)->frags[j].size;
+		skb_frag_ref(to, j);
+		j++;
+	}
+	skb_shinfo(to)->nr_frags = j;
+}
+EXPORT_SYMBOL_GPL(skb_zerocopy);
+
 void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to)
 {
 	__wsum csum;
diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c
index 21258cf..615ee12 100644
--- a/net/netfilter/nfnetlink_queue_core.c
+++ b/net/netfilter/nfnetlink_queue_core.c
@@ -235,51 +235,6 @@ nfqnl_flush(struct nfqnl_instance *queue, nfqnl_cmpfn cmpfn, unsigned long data)
 	spin_unlock_bh(&queue->lock);
 }
 
-static void
-nfqnl_zcopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen)
-{
-	int i, j = 0;
-	int plen = 0; /* length of skb->head fragment */
-	struct page *page;
-	unsigned int offset;
-
-	/* dont bother with small payloads */
-	if (len <= skb_tailroom(to)) {
-		skb_copy_bits(from, 0, skb_put(to, len), len);
-		return;
-	}
-
-	if (hlen) {
-		skb_copy_bits(from, 0, skb_put(to, hlen), hlen);
-		len -= hlen;
-	} else {
-		plen = min_t(int, skb_headlen(from), len);
-		if (plen) {
-			page = virt_to_head_page(from->head);
-			offset = from->data - (unsigned char *)page_address(page);
-			__skb_fill_page_desc(to, 0, page, offset, plen);
-			get_page(page);
-			j = 1;
-			len -= plen;
-		}
-	}
-
-	to->truesize += len + plen;
-	to->len += len + plen;
-	to->data_len += len + plen;
-
-	for (i = 0; i < skb_shinfo(from)->nr_frags; i++) {
-		if (!len)
-			break;
-		skb_shinfo(to)->frags[j] = skb_shinfo(from)->frags[i];
-		skb_shinfo(to)->frags[j].size = min_t(int, skb_shinfo(to)->frags[j].size, len);
-		len -= skb_shinfo(to)->frags[j].size;
-		skb_frag_ref(to, j);
-		j++;
-	}
-	skb_shinfo(to)->nr_frags = j;
-}
-
 static int
 nfqnl_put_packet_info(struct sk_buff *nlskb, struct sk_buff *packet,
 		      bool csum_verify)
@@ -304,7 +259,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
 {
 	size_t size;
 	size_t data_len = 0, cap_len = 0;
-	int hlen = 0;
+	unsigned int hlen = 0;
 	struct sk_buff *skb;
 	struct nlattr *nla;
 	struct nfqnl_msg_packet_hdr *pmsg;
@@ -356,14 +311,8 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
 		if (data_len > entskb->len)
 			data_len = entskb->len;
 
-		if (!entskb->head_frag ||
-		    skb_headlen(entskb) < L1_CACHE_BYTES ||
-		    skb_shinfo(entskb)->nr_frags >= MAX_SKB_FRAGS)
-			hlen = skb_headlen(entskb);
-
-		if (skb_has_frag_list(entskb))
-			hlen = entskb->len;
-		hlen = min_t(int, data_len, hlen);
+		hlen = skb_zerocopy_headlen(entskb);
+		hlen = min_t(unsigned int, hlen, data_len);
 		size += sizeof(struct nlattr) + hlen;
 		cap_len = entskb->len;
 		break;
@@ -504,7 +453,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
 		nla->nla_type = NFQA_PAYLOAD;
 		nla->nla_len = nla_attr_size(data_len);
 
-		nfqnl_zcopy(skb, entskb, data_len, hlen);
+		skb_zerocopy(skb, entskb, data_len, hlen);
 	}
 
 	nlh->nlmsg_len = skb->len;
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next 3/8] openvswitch: Enable memory mapped Netlink i/o
From: Thomas Graf @ 2013-11-22 16:56 UTC (permalink / raw)
  To: jesse, davem
  Cc: dev, netdev, dborkman, ffusco, fleitner, eric.dumazet, bhutchings
In-Reply-To: <cover.1385137618.git.tgraf@suug.ch>

Use memory mapped Netlink i/o for all unicast openvswitch
communication if a ring has been set up.

Benchmark
  * pktgen -> ovs internal port
  * 5M pkts, 5M flows
  * 4 threads, 8 cores

Before:
Result: OK: 67418743(c67108212+d310530) usec, 5000000 (9000byte,0frags)
  74163pps 5339Mb/sec (5339736000bps) errors: 0
	+   2.98%     ovs-vswitchd  [k] copy_user_generic_string
	+   2.49%     ovs-vswitchd  [k] memcpy
	+   1.84%       kpktgend_2  [k] memcpy
	+   1.81%       kpktgend_1  [k] memcpy
	+   1.81%       kpktgend_3  [k] memcpy
	+   1.78%       kpktgend_0  [k] memcpy

After:
Result: OK: 24229690(c24127165+d102524) usec, 5000000 (9000byte,0frags)
  206358pps 14857Mb/sec (14857776000bps) errors: 0
	+   2.80%     ovs-vswitchd  [k] memcpy
	+   1.31%       kpktgend_2  [k] memcpy
	+   1.23%       kpktgend_0  [k] memcpy
	+   1.09%       kpktgend_1  [k] memcpy
	+   1.04%       kpktgend_3  [k] memcpy
	+   0.96%     ovs-vswitchd  [k] copy_user_generic_string

Signed-off-by: Thomas Graf <tgraf@suug.ch>
Reviewed-by: Daniel Borkmann <dborkman@redhat.com>
---
 net/openvswitch/datapath.c | 56 ++++++++++++++++++++++++----------------------
 1 file changed, 29 insertions(+), 27 deletions(-)

diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 6f5e1dd..0ac9cde 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -402,6 +402,11 @@ static int queue_userspace_packet(struct net *net, int dp_ifindex,
 	struct sk_buff *nskb = NULL;
 	struct sk_buff *user_skb; /* to be queued to userspace */
 	struct nlattr *nla;
+	struct genl_info info = {
+		.dst_sk = net->genl_sock,
+		.snd_portid = upcall_info->portid,
+	};
+	size_t len;
 	int err;
 
 	if (vlan_tx_tag_present(skb)) {
@@ -422,7 +427,8 @@ static int queue_userspace_packet(struct net *net, int dp_ifindex,
 		goto out;
 	}
 
-	user_skb = genlmsg_new(upcall_msg_size(skb, upcall_info->userdata), GFP_ATOMIC);
+	len = upcall_msg_size(skb, upcall_info->userdata);
+	user_skb = genlmsg_new_unicast(len, &info, GFP_ATOMIC);
 	if (!user_skb) {
 		err = -ENOMEM;
 		goto out;
@@ -726,27 +732,30 @@ error:
 	return err;
 }
 
-static struct sk_buff *ovs_flow_cmd_alloc_info(struct sw_flow *flow)
+static struct sk_buff *ovs_flow_cmd_alloc_info(struct sw_flow *flow,
+					       struct genl_info *info)
 {
-	const struct sw_flow_actions *sf_acts;
+	size_t len;
 
-	sf_acts = ovsl_dereference(flow->sf_acts);
+	len = ovs_flow_cmd_msg_size(ovsl_dereference(flow->sf_acts));
 
-	return genlmsg_new(ovs_flow_cmd_msg_size(sf_acts), GFP_KERNEL);
+	return genlmsg_new_unicast(len, info, GFP_KERNEL);
 }
 
 static struct sk_buff *ovs_flow_cmd_build_info(struct sw_flow *flow,
 					       struct datapath *dp,
-					       u32 portid, u32 seq, u8 cmd)
+					       struct genl_info *info,
+					       u8 cmd)
 {
 	struct sk_buff *skb;
 	int retval;
 
-	skb = ovs_flow_cmd_alloc_info(flow);
+	skb = ovs_flow_cmd_alloc_info(flow, info);
 	if (!skb)
 		return ERR_PTR(-ENOMEM);
 
-	retval = ovs_flow_cmd_fill_info(flow, dp, skb, portid, seq, 0, cmd);
+	retval = ovs_flow_cmd_fill_info(flow, dp, skb, info->snd_portid,
+					info->snd_seq, 0, cmd);
 	BUG_ON(retval < 0);
 	return skb;
 }
@@ -835,8 +844,7 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
 			goto err_flow_free;
 		}
 
-		reply = ovs_flow_cmd_build_info(flow, dp, info->snd_portid,
-						info->snd_seq, OVS_FLOW_CMD_NEW);
+		reply = ovs_flow_cmd_build_info(flow, dp, info, OVS_FLOW_CMD_NEW);
 	} else {
 		/* We found a matching flow. */
 		struct sw_flow_actions *old_acts;
@@ -864,8 +872,7 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
 		rcu_assign_pointer(flow->sf_acts, acts);
 		ovs_nla_free_flow_actions(old_acts);
 
-		reply = ovs_flow_cmd_build_info(flow, dp, info->snd_portid,
-					       info->snd_seq, OVS_FLOW_CMD_NEW);
+		reply = ovs_flow_cmd_build_info(flow, dp, info, OVS_FLOW_CMD_NEW);
 
 		/* Clear stats. */
 		if (a[OVS_FLOW_ATTR_CLEAR]) {
@@ -927,8 +934,7 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info)
 		goto unlock;
 	}
 
-	reply = ovs_flow_cmd_build_info(flow, dp, info->snd_portid,
-					info->snd_seq, OVS_FLOW_CMD_NEW);
+	reply = ovs_flow_cmd_build_info(flow, dp, info, OVS_FLOW_CMD_NEW);
 	if (IS_ERR(reply)) {
 		err = PTR_ERR(reply);
 		goto unlock;
@@ -975,7 +981,7 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
 		goto unlock;
 	}
 
-	reply = ovs_flow_cmd_alloc_info(flow);
+	reply = ovs_flow_cmd_alloc_info(flow, info);
 	if (!reply) {
 		err = -ENOMEM;
 		goto unlock;
@@ -1127,17 +1133,17 @@ error:
 	return -EMSGSIZE;
 }
 
-static struct sk_buff *ovs_dp_cmd_build_info(struct datapath *dp, u32 portid,
-					     u32 seq, u8 cmd)
+static struct sk_buff *ovs_dp_cmd_build_info(struct datapath *dp,
+					     struct genl_info *info, u8 cmd)
 {
 	struct sk_buff *skb;
 	int retval;
 
-	skb = genlmsg_new(ovs_dp_cmd_msg_size(), GFP_KERNEL);
+	skb = genlmsg_new_unicast(ovs_dp_cmd_msg_size(), info, GFP_KERNEL);
 	if (!skb)
 		return ERR_PTR(-ENOMEM);
 
-	retval = ovs_dp_cmd_fill_info(dp, skb, portid, seq, 0, cmd);
+	retval = ovs_dp_cmd_fill_info(dp, skb, info->snd_portid, info->snd_seq, 0, cmd);
 	if (retval < 0) {
 		kfree_skb(skb);
 		return ERR_PTR(retval);
@@ -1232,8 +1238,7 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
 		goto err_destroy_ports_array;
 	}
 
-	reply = ovs_dp_cmd_build_info(dp, info->snd_portid,
-				      info->snd_seq, OVS_DP_CMD_NEW);
+	reply = ovs_dp_cmd_build_info(dp, info, OVS_DP_CMD_NEW);
 	err = PTR_ERR(reply);
 	if (IS_ERR(reply))
 		goto err_destroy_local_port;
@@ -1299,8 +1304,7 @@ static int ovs_dp_cmd_del(struct sk_buff *skb, struct genl_info *info)
 	if (IS_ERR(dp))
 		goto unlock;
 
-	reply = ovs_dp_cmd_build_info(dp, info->snd_portid,
-				      info->snd_seq, OVS_DP_CMD_DEL);
+	reply = ovs_dp_cmd_build_info(dp, info, OVS_DP_CMD_DEL);
 	err = PTR_ERR(reply);
 	if (IS_ERR(reply))
 		goto unlock;
@@ -1328,8 +1332,7 @@ static int ovs_dp_cmd_set(struct sk_buff *skb, struct genl_info *info)
 	if (IS_ERR(dp))
 		goto unlock;
 
-	reply = ovs_dp_cmd_build_info(dp, info->snd_portid,
-				      info->snd_seq, OVS_DP_CMD_NEW);
+	reply = ovs_dp_cmd_build_info(dp, info, OVS_DP_CMD_NEW);
 	if (IS_ERR(reply)) {
 		err = PTR_ERR(reply);
 		genl_set_err(&dp_datapath_genl_family, sock_net(skb->sk), 0,
@@ -1360,8 +1363,7 @@ static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info)
 		goto unlock;
 	}
 
-	reply = ovs_dp_cmd_build_info(dp, info->snd_portid,
-				      info->snd_seq, OVS_DP_CMD_NEW);
+	reply = ovs_dp_cmd_build_info(dp, info, OVS_DP_CMD_NEW);
 	if (IS_ERR(reply)) {
 		err = PTR_ERR(reply);
 		goto unlock;
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next 1/8] genl: Add genlmsg_new_unicast() for unicast message allocation
From: Thomas Graf @ 2013-11-22 16:56 UTC (permalink / raw)
  To: jesse, davem
  Cc: dev, netdev, dborkman, ffusco, fleitner, eric.dumazet, bhutchings
In-Reply-To: <cover.1385137618.git.tgraf@suug.ch>

Allocates a new sk_buff large enough to cover the specified payload
plus required Netlink headers. Will check receiving socket for
memory mapped i/o capability and use it if enabled. Will fall back
to non-mapped skb if message size exceeds the frame size of the ring.

Signed-of-by: Thomas Graf <tgraf@suug.ch>
Reviewed-by: Daniel Borkmann <dborkman@redhat.com>
---
 include/net/genetlink.h |  4 ++++
 net/netlink/genetlink.c | 21 +++++++++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 1b177ed..93695f0 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -73,6 +73,7 @@ struct genl_family {
  * @attrs: netlink attributes
  * @_net: network namespace
  * @user_ptr: user pointers
+ * @dst_sk: destination socket
  */
 struct genl_info {
 	u32			snd_seq;
@@ -85,6 +86,7 @@ struct genl_info {
 	struct net *		_net;
 #endif
 	void *			user_ptr[2];
+	struct sock *		dst_sk;
 };
 
 static inline struct net *genl_info_net(struct genl_info *info)
@@ -177,6 +179,8 @@ void genl_notify(struct genl_family *family,
 		 struct sk_buff *skb, struct net *net, u32 portid,
 		 u32 group, struct nlmsghdr *nlh, gfp_t flags);
 
+struct sk_buff *genlmsg_new_unicast(size_t payload, struct genl_info *info,
+				    gfp_t flags);
 void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
 		  struct genl_family *family, int flags, u8 cmd);
 
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 4518a57..85bf42e 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -454,6 +454,26 @@ int genl_unregister_family(struct genl_family *family)
 EXPORT_SYMBOL(genl_unregister_family);
 
 /**
+ * genlmsg_new_unicast - Allocate generic netlink message for unicast
+ * @payload: size of the message payload
+ * @info: information on destination
+ * @flags: the type of memory to allocate
+ *
+ * Allocates a new sk_buff large enough to cover the specified payload
+ * plus required Netlink headers. Will check receiving socket for
+ * memory mapped i/o capability and use it if enabled. Will fall back
+ * to non-mapped skb if message size exceeds the frame size of the ring.
+ */
+struct sk_buff *genlmsg_new_unicast(size_t payload, struct genl_info *info,
+				    gfp_t flags)
+{
+	size_t len = nlmsg_total_size(genlmsg_total_size(payload));
+
+	return netlink_alloc_skb(info->dst_sk, len, info->snd_portid, flags);
+}
+EXPORT_SYMBOL_GPL(genlmsg_new_unicast);
+
+/**
  * genlmsg_put - Add generic netlink header to netlink message
  * @skb: socket buffer holding the message
  * @portid: netlink portid the message is addressed to
@@ -593,6 +613,7 @@ static int genl_family_rcv_msg(struct genl_family *family,
 	info.genlhdr = nlmsg_data(nlh);
 	info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;
 	info.attrs = attrbuf;
+	info.dst_sk = skb->sk;
 	genl_info_net_set(&info, net);
 	memset(&info.user_ptr, 0, sizeof(info.user_ptr));
 
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next 0/8 v7] Open vSwitch upcall optimiziations
From: Thomas Graf @ 2013-11-22 16:56 UTC (permalink / raw)
  To: jesse, davem
  Cc: dev, netdev, dborkman, ffusco, fleitner, eric.dumazet, bhutchings

Reposting this before the merge window as it will go through Jesse's
tree.

Given jumbo frames, the capacity of the slow path is improved by 
a factor of 2.5x.

V7: - removed unintential kernel-doc comment
    - WARN_ONCE() -> WARN(), message on single line, added \n
V6: - Added memory mapped netlink i/o support
    - Drop user_features if old user space not aware of user features
      reuses an existing datapath
V5: - Removed padding requirement in user space
    - Added OVS_DP_F_UNALIGNED flag let user space signal ability to
      receive unaligned Netlink messages, fall back to linear copy
      otherwise.
V4: - Daniel Borkmann pointed out that the style in skbuff.h has changed
      in net-next, adapted to no longer using extern in headers.
V3: - Removed unneeded alignment of nlmsg_len after padding
V2: - Added skb_zerocopy_headlen() to calculate headroom of destination
      buffer. This also takes care of the from->head_frag issue.
    - Attribute alignment for frag_list case
    - API documentation
    - performance data for CHECKSUM_PARTIAL tx case

Thomas Graf (8):
  genl: Add genlmsg_new_unicast() for unicast message allocation
  netlink: Avoid netlink mmap alloc if msg size exceeds frame size
  openvswitch: Enable memory mapped Netlink i/o
  net: Export skb_zerocopy() to zerocopy from one skb to another
  openvswitch: Allow user space to announce ability to accept unaligned
    Netlink messages
  openvswitch: Allow update of dp with OVS_DP_CMD_NEW if NLM_F_REPLACE
    is set
  openvswitch: Drop user features if old user space attempted to create
    datapath
  openvswitch: Use skb_zerocopy() for upcall

 include/linux/skbuff.h               |   3 +
 include/net/genetlink.h              |   4 +
 include/uapi/linux/openvswitch.h     |  14 ++-
 net/core/skbuff.c                    |  85 ++++++++++++++++
 net/netfilter/nfnetlink_queue_core.c |  59 +----------
 net/netlink/af_netlink.c             |   4 +
 net/netlink/genetlink.c              |  21 ++++
 net/openvswitch/datapath.c           | 192 ++++++++++++++++++++++-------------
 net/openvswitch/datapath.h           |   2 +
 9 files changed, 255 insertions(+), 129 deletions(-)

-- 
1.8.3.1

^ permalink raw reply

* [PATCH net-next 2/8] netlink: Avoid netlink mmap alloc if msg size exceeds frame size
From: Thomas Graf @ 2013-11-22 16:56 UTC (permalink / raw)
  To: jesse-l0M0P4e3n4LQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: dev-yBygre7rU0TnMu66kgdUjQ, fleitner-H+wXaHxf7aLQT0dZR+AlfA,
	eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w,
	netdev-u79uwXL29TY76Z2rM5mHXA, bhutchings-s/n/eUQHGBpZroRs9YW3xA
In-Reply-To: <cover.1385137618.git.tgraf-G/eBtMaohhA@public.gmane.org>

An insufficent ring frame size configuration can lead to an
unnecessary skb allocation for every Netlink message. Check frame
size before taking the queue lock and allocating the skb and
re-check with lock to be safe.

Signed-off-by: Thomas Graf <tgraf-G/eBtMaohhA@public.gmane.org>
Reviewed-by: Daniel Borkmann <dborkman-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 net/netlink/af_netlink.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index bca50b9..6433489 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1769,6 +1769,9 @@ struct sk_buff *netlink_alloc_skb(struct sock *ssk, unsigned int size,
 	if (ring->pg_vec == NULL)
 		goto out_put;
 
+	if (ring->frame_size - NL_MMAP_HDRLEN < size)
+		goto out_put;
+
 	skb = alloc_skb_head(gfp_mask);
 	if (skb == NULL)
 		goto err1;
@@ -1778,6 +1781,7 @@ struct sk_buff *netlink_alloc_skb(struct sock *ssk, unsigned int size,
 	if (ring->pg_vec == NULL)
 		goto out_free;
 
+	/* check again under lock */
 	maxlen = ring->frame_size - NL_MMAP_HDRLEN;
 	if (maxlen < size)
 		goto out_free;
-- 
1.8.3.1

^ permalink raw reply related

* Re: [PATCH 0/4] Add ceph root filesystem functionality and documentation.
From: Mark Doffman @ 2013-11-22 16:53 UTC (permalink / raw)
  To: David Dillow
  Cc: ceph-devel-u79uwXL29TY76Z2rM5mHXA, sage-4GqslpFJ+cxBDgjK7y7TUQ,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	rob.taylor-4yDnlxn2s6sWdaTGBSpHTA
In-Reply-To: <1385065186.18238.0.camel-zHLflQxYYDO4Hhoo1DtQwJ9G+ZOsUmrO@public.gmane.org>

On 11/21/2013 02:19 PM, David Dillow wrote:
> On Wed, 2013-11-20 at 20:13 -0600, mark.doffman-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org wrote:
>> The following patch series adds the ability to use a ceph distributed
>> file system as the root device. The functionality is similar to
>> NFS root but for the ceph filesystem.
>
> Why do this in the kernel vs in the initramfs? Dracut would be a more
> appropriate place, I think, as it has support for other network root
> devices already.

I don't know if its a good idea to require an initramfs for mounting a
rootfs over the network. NFS root is currently in the kernel, and
frequently used without an initramfs.

Booting from ceph using a root device is relatively simple compared to
generating an initramfs and it has the possibility of producing smaller
images for memory constrained devices.


--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" 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

* DO YOU NEED BUSINESS AND PERSONAL LOAN
From: ''Hyde Loan Finance Company @ 2013-11-22  7:44 UTC (permalink / raw)
  To: Recipients

Loans available at 3%.Contact us for more info if interested.Serious minded only.Contact us Via Email: hydenance@gmail.com

^ permalink raw reply

* Re: [Doubt on Implict BUGs caused LRO] doubt about lro status in v3.12 of torvalds/linux.git
From: Eric Dumazet @ 2013-11-22 16:32 UTC (permalink / raw)
  To: Yanfei Wang; +Cc: netdev, China Kernel, linux-kernel
In-Reply-To: <CAJULonje7V_sMt6joBBsM3uuQkYFhfNK70BXzN0EyS3sQNb0uQ@mail.gmail.com>

On Fri, 2013-11-22 at 23:00 +0800, Yanfei Wang wrote:
> Hi,
> 
> Compared to the earlier kernel version, I found that Large receive
> offload(LRO) is obsolete in latest kernel, and that is verified from
> other materials about Generic receive offload(GRO).
> 
> However,  I also found some LRO header files and  lro-related
> functions referred by some drivers, and the lro-related function
> definition is already removed at the same time!
> 
> TEST steps:
> 1. my git local db config as follow, url =
> http://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
> 2. git checkout v3.12 -b 3.12
> 3. cd net/ipv4,
>  [backyes@f14 ipv4]$ cat Makefile | grep lro
> obj-$(CONFIG_INET_LRO) += inet_lro.o
> [backyes@f14 ipv4]$ ls inet_*
> inet_connection_sock.c  inet_diag.c  inet_fragment.c
> inet_hashtables.c  inet_timewait_sock.c
> [backyes@f14 ipv4]$
> Here, Makefile has inet_lro.o config, while the inet_lro.c is removed.
> 4. lro functions referred by some drivers, as follow,
> [backyes@f14 linux]$ grep "inet_lro" * -r
> drivers/net/ethernet/pasemi/pasemi_mac.c:#include <linux/inet_lro.h>
> drivers/net/ethernet/pasemi/pasemi_mac_ethtool.c:#include <linux/inet_lro.h>
> drivers/infiniband/hw/nes/nes_hw.c:#include <linux/inet_lro.h>
> drivers/infiniband/hw/nes/nes_hw.h:#include <linux/inet_lro.h>
> include/linux/inet_lro.h: *  linux/include/linux/inet_lro.h
> net/ipv4/Makefile:obj-$(CONFIG_INET_LRO) += inet_lro.o
> 
> so, I understand that the removal of LRO is not clean, which will
> cause compiler error for some kernel config.
> 

I think you are slightly confused.

LRO is not yet removed.

Feel free to contribute ;)

As long as at least one driver still uses LRO, we can not remove LRO.

Converting a driver means testing the new driver, and owning the
hardware.

^ permalink raw reply

* Problem with am335x (cpsw) MDIO state machine
From: Stefan Roese @ 2013-11-22 16:06 UTC (permalink / raw)
  To: Mugunthan V N; +Cc: netdev@vger.kernel.org

Hi All!

I'm currently struggling with the MDIO interface of the am335x SoC. As
its state machine continuously communicates with the potentially
available PHY devices (0...31). To determine the link status etc. But
I'm trying to communicate with am SMSC9303 switch via this MDIO
interface. It has 32bit registers organized as 2 16bit registers. These
registers need to be accessed back-to-back. Without any other frame in
between. And this is often interrupted (disturbed) by these state
machines polling frames.

Has anyone ever tried to work in this SoC with this MDIO state machine
disabled? I tried this by clearing the ENABLE bit in the MDIOCONTROL
register after each transaction. But this doesn't seem to work
(resulting in timeouts etc)?

Has anybody ever tried anything like this?

Thanks,
Stefan

^ permalink raw reply


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