Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH v3] net/fsl_pq_mdio: Document supported compatibles
From: David Miller @ 2015-02-04  0:11 UTC (permalink / raw)
  To: Emilian.Medve-eDlz3WWmN0ll57MIdRCFDg
  Cc: scottwood-eDlz3WWmN0ll57MIdRCFDg,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
	devicetree-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
	Kanetkar.Shruti-Re5JQEeQqe8AvxtiuMwx3w
In-Reply-To: <1422827911-32629-1-git-send-email-Emilian.Medve-eDlz3WWmN0ll57MIdRCFDg@public.gmane.org>

From: Emil Medve <Emilian.Medve-eDlz3WWmN0ll57MIdRCFDg@public.gmane.org>
Date: Sun, 1 Feb 2015 15:58:31 -0600

> From: Shruti Kanetkar <Kanetkar.Shruti-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> 
> The device tree binding(s) document has fallen out of sync with the
> driver code. Update the list of supported devices to reflect current
> driver capabilities
> 
> Change-Id: I440d8de2ee2d9c3b7b23e69b3da851cab18a4c9a
> Signed-off-by: Shruti Kanetkar <Kanetkar.Shruti-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Signed-off-by: Emil Medve <Emilian.Medve-eDlz3WWmN0ll57MIdRCFDg@public.gmane.org>

Applied to net-next, thanks.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" 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

* Re: [PATCH] tun: orphan an skb on tx
From: David Miller @ 2015-02-04  0:19 UTC (permalink / raw)
  To: dwmw2
  Cc: mst, herbert, eric.dumazet, jan.kiszka, netdev, linux-kernel,
	qemu-devel
In-Reply-To: <1422862030.11044.86.camel@infradead.org>

From: David Woodhouse <dwmw2@infradead.org>
Date: Mon, 02 Feb 2015 07:27:10 +0000

> I'm guessing you don't want to push the *whole* management of the TLS
> control connection *and* the UDP transport, and probing the latter with
> keepalives, into the kernel? I certainly don't :)

Whilst Herbert Xu and I have discussed in the past supporting
automatic SSL handling of socket data during socket writes in the
kernel, doing TLS stuff would be a bit of a stretch :-)

^ permalink raw reply

* Re: NETDEV WATCHDOG:  internal(r8152): transmit queue 0 timed out
From: poma @ 2015-02-04  0:20 UTC (permalink / raw)
  To: sean darcy
  Cc: Community support for Fedora users, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-usb-u79uwXL29TY76Z2rM5mHXA, Hayes Wang
In-Reply-To: <54BA23CE.70001-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

On 17.01.2015 09:56, poma wrote:
> On 17.01.2015 00:57, sean darcy wrote:
>> On 01/16/2015 07:09 AM, poma wrote:
>>> On 16.01.2015 10:37, Hayes Wang wrote:
>>>>   poma [mailto:pomidorabelisima-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org]
>>>>> Sent: Friday, January 16, 2015 4:25 PM
>>>> [...]
>>>>>> This looks like a USB problem. Is there a way to get usb (or
>>>>>> NetworkManager) to reinitialize the driver when this happens?
>>>>>
>>>>> I would ask these people for advice, therefore.
>>>>
>>>> Our hw engineers need to analyse the behavior of the device.
>>>> However, I don't think you have such instrument to provide
>>>> the required information. If we don't know the reason, we
>>>> couldn't give you the proper solution. Besides, your solution
>>>> would work if and only if reloading the driver is helpful.
>>>>
>>>> The issue have to debug from the hardware, and I have no idea
>>>> about what the software could do before analysing the hw. Maybe
>>>> you could try the following driver first to check if it is useful.
>>>>
>>>> http://www.realtek.com.tw/downloads/downloadsView.aspx?Langid=2&PNid=13&PFid=56&Level=5&Conn=4&DownTypeID=3&GetDown=false
>>>>
>>>> Best Regards,
>>>> Hayes
>>>>
>>>
>>> Thanks for your response, Mr. Hayes.
>>>
>>> Mr. Sean, please download and check if "timeout" is still present with built RTL8153 module from REALTEK site, as Mr. Hayes proposed.
>>> http://www.realtek.com.tw/downloads/downloadsView.aspx?Langid=2&PNid=13&PFid=56&Level=5&Conn=4&DownTypeID=3&GetDown=false#2
>>> r8152.53-2.03.0.tar.bz2
>>>
>>> Procedure - should be equal for both, Fedora 21 & 20:
>>>
>>> $ uname -r
>>> 3.17.8-300.fc21.x86_64
>>>
>>> $ su -c 'yum install kernel-devel'
>>>
>>> $ tar xf r8152.53-2.03.0.tar.bz2
>>> $ cd r8152-2.03.0/
>>> $ make
>>> $ su
>>>
>>> # cp 50-usb-realtek-net.rules /etc/udev/rules.d/
>>> # udevadm trigger --action=add
>>>
>>> # modprobe -rv r8152
>>> # cp r8152.ko /lib/modules/$(uname -r)/updates/
>>> # depmod
>>> # modprobe -v r8152
>>>
>>>
>>> poma
>>>
>> OK. Did all that. Now to see if I get the same problem over the next 
>> couple of weeks.
>>
>> I'd never heard about the updates subfolder in modules. Very slick.
>>
>> But when I update the kernel, I get to do this again correct? How will I 
> 
> $ cd r8152-2.03.0/
> $ make clean
> $ make
> $ su
> 
> # cp r8152.ko /lib/modules/$(uname -r)/updates/
> # depmod
> # modprobe -v r8152
> 
> is part of the procedure necessary for a new i.e. an upgraded kernel.
> 
> 
>> know that this module has been incorporated in the running kernel. 
>> modinfo doesn't give any version info.
>>
> 
> $ modinfo r8152 -n
> 
> will show the module considered for loading.
> 
> 
>> BTW, I'm not sure what modprobe --dump-modversions is supposed to do, 
>> but it doesn't:
>>
>> #modprobe --dump-modversions r8152
>> modprobe: FATAL: Module r8152 not found.
>> # modprobe --dump-modversions r8152.ko
>> modprobe: FATAL: Module r8152.ko not found.
>> #lsmod | grep 8152
>> r8152                  49646  0
>>
> 
> "--dump-modversions" will probably show the same error for any module.
> 
> 
>> Thanks for all your help.
>>
>> sean
>>
> 
> YW
> 
> 
> 

Mr. Sean,
is your problem with r8152 resolved, are
"kernel: r8152 2-2:1.0 internal: Tx timeout"
still present?


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

* Re: [PATCH v2 01/18] netlink: make the check for "send from tx_ring" deterministic
From: David Miller @ 2015-02-04  0:21 UTC (permalink / raw)
  To: sergei.shtylyov; +Cc: viro, netdev
In-Reply-To: <54CF7828.6040605@cogentembedded.com>

From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Date: Mon, 02 Feb 2015 16:14:16 +0300

> On 2/2/2015 10:59 AM, Al Viro wrote:
> 
>> From: Al Viro <viro@zeniv.linux.org.uk>
> 
>> + /* It's a really convoluted way for userland to ask for mmaped
>> +	 * sendmsg(), but that's what we've got...  */
> 
>    Hmm, not sure why DaveM hasn't commented on this broken comment
>    formatting (perhaps he was going to fix it while applying?). The
>    preferred comment style in the networking code is:
> 
> /* bla
>  * bla
>  */

Indeed, Al can you please audit your whole series for this issue and
respin?

Please also explicitly give me the GIT url to pull from each time you
post the series.

Thanks.

^ permalink raw reply

* [RFC] Possible data stall with RPS and CPU hotplug
From: subashab @ 2015-02-04  0:52 UTC (permalink / raw)
  To: netdev; +Cc: eric.dumazet, therbert

We have an RPS configuration to process packets on Core3 while hardware
interrupts arrive on Core0. We see an occasional stall when Core3 is hot
plugged out and comes back up at a later point in time. At the time of
this stall, we notice that the maximum backlog queue size of 1000 is
reached and subsequent packets are dropped, NAPI is scheduled on Core3,
but softIRQ NET_RX is not raised on Core3.

This leads me to think that possibly the Core3 went offline just before
hitting this conditional cpu_online() check in
net_rps_action_and_irq_enable(), so the IPI was not delivered to Core3.

	/* Send pending IPI's to kick RPS processing on remote cpus. */
	while (remsd) {
		struct softnet_data *next = remsd->rps_ipi_next;
		if (cpu_online(remsd->cpu))
			__smp_call_function_single(remsd->cpu,
						   &remsd->csd, 0);
		remsd = next;
	}

Later when the Core3 comes back online packets start getting enqueued to
Core3 but IPI's are not delivered because NAPI_STATE_SCHED is never
cleared on sofnet_data for Core3.

enqueue_to_backlog()

	/* Schedule NAPI for backlog device
	 * We can use non atomic operation since we own the queue lock
	 */
	if (!__test_and_set_bit(NAPI_STATE_SCHED, &sd->backlog.state)) {
		if (!rps_ipi_queued(sd))
			____napi_schedule(sd, &sd->backlog);
	}
	goto enqueue;
}

Is this analysis correct and does the following patch makes sense?

Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
---
 net/core/dev.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/core/dev.c b/net/core/dev.c
index 171420e..57663c9 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -7101,6 +7101,7 @@ static int dev_cpu_callback(struct notifier_block *nfb,
 		input_queue_head_incr(oldsd);
 	}

+	clear_bit(NAPI_STATE_SCHED, oldsd->backlog.state);
 	return NOTIFY_OK;
 }

-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
 a Linux Foundation Collaborative Project

^ permalink raw reply related

* Re: [RFC] Possible data stall with RPS and CPU hotplug
From: Eric Dumazet @ 2015-02-04  1:19 UTC (permalink / raw)
  To: subashab; +Cc: netdev, therbert
In-Reply-To: <90b4251bdb040907ea73f992e1bb96df.squirrel@www.codeaurora.org>

On Wed, 2015-02-04 at 00:52 +0000, subashab@codeaurora.org wrote:
> We have an RPS configuration to process packets on Core3 while hardware
> interrupts arrive on Core0. We see an occasional stall when Core3 is hot
> plugged out and comes back up at a later point in time. At the time of
> this stall, we notice that the maximum backlog queue size of 1000 is
> reached and subsequent packets are dropped, NAPI is scheduled on Core3,
> but softIRQ NET_RX is not raised on Core3.
> 
> This leads me to think that possibly the Core3 went offline just before
> hitting this conditional cpu_online() check in
> net_rps_action_and_irq_enable(), so the IPI was not delivered to Core3.
> 
> 	/* Send pending IPI's to kick RPS processing on remote cpus. */
> 	while (remsd) {
> 		struct softnet_data *next = remsd->rps_ipi_next;
> 		if (cpu_online(remsd->cpu))
> 			__smp_call_function_single(remsd->cpu,
> 						   &remsd->csd, 0);
> 		remsd = next;
> 	}
> 
> Later when the Core3 comes back online packets start getting enqueued to
> Core3 but IPI's are not delivered because NAPI_STATE_SCHED is never
> cleared on sofnet_data for Core3.
> 
> enqueue_to_backlog()
> 
> 	/* Schedule NAPI for backlog device
> 	 * We can use non atomic operation since we own the queue lock
> 	 */
> 	if (!__test_and_set_bit(NAPI_STATE_SCHED, &sd->backlog.state)) {
> 		if (!rps_ipi_queued(sd))
> 			____napi_schedule(sd, &sd->backlog);
> 	}
> 	goto enqueue;
> }
> 
> Is this analysis correct and does the following patch makes sense?
> 
> Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
> ---
>  net/core/dev.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 171420e..57663c9 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -7101,6 +7101,7 @@ static int dev_cpu_callback(struct notifier_block *nfb,
>  		input_queue_head_incr(oldsd);
>  	}
> 
> +	clear_bit(NAPI_STATE_SCHED, oldsd->backlog.state);
>  	return NOTIFY_OK;
>  }
> 

Really, this should not be needed after commit
ac64da0b83d82abe62f78b3d0e21cca31aea24fa
("net: rps: fix cpu unplug")

If NAPI_STATE_SCHED was set on oldsd->backlog.state, then we must have
found the napi in oldsd->poll_list

So we should have hit line 7125 :

	if (napi->poll == process_backlog)
7125:		napi->state = 0;
	else
		____napi_schedule(sd, napi);

So if you find this bit set, there is another bug ?


But it looks like we do not use proper netif_rx() variant in this path.

We run from process context, so we need (at least) following patch :

diff --git a/net/core/dev.c b/net/core/dev.c
index 1d564d68e31a5f361fc233ae90a3a19e82915664..947a291223f5437bc004f7fcbb3a938ecba6ced0 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -7132,11 +7132,11 @@ static int dev_cpu_callback(struct notifier_block *nfb,
 
 	/* Process offline CPU's input_pkt_queue */
 	while ((skb = __skb_dequeue(&oldsd->process_queue))) {
-		netif_rx_internal(skb);
+		netif_rx_ni(skb);
 		input_queue_head_incr(oldsd);
 	}
 	while ((skb = skb_dequeue(&oldsd->input_pkt_queue))) {
-		netif_rx_internal(skb);
+		netif_rx_ni(skb);
 		input_queue_head_incr(oldsd);
 	}
 

^ permalink raw reply related

* Re: Question: should local address be expired when updating PMTU?
From: shengyong @ 2015-02-04  1:59 UTC (permalink / raw)
  To: Steffen Klassert; +Cc: davem, netdev, yangyingliang, hannes
In-Reply-To: <20150203120140.GU13046@secunet.com>



在 2015/2/3 20:01, Steffen Klassert 写道:
> On Tue, Feb 03, 2015 at 06:54:19PM +0800, shengyong wrote:
>>
>>
>> 在 2015/2/3 17:28, Steffen Klassert 写道:
>>> On Mon, Feb 02, 2015 at 04:20:24PM +0800, shengyong wrote:
>>>
>>> We first need to find out why you receive this Packet Too Big message,
>> The packet is sent by a commercial-off-the-shelf testcase, and I can reproduce the
>> situation by using scapy and creating a packet as the following:
>>
>> 	$ cat packet-too-big.py
>> 	#!/usr/bin/python
>> 	
>> 	from scapy.all import *
>>
>> 	# fe80::800:27ff:fe00:0 is linklocal addr of PC
>> 	# fe80::a00:27ff:fe1a:e2a0 is linklocal addr of VM
>> 	base=IPv6(src='fe80::800:27ff:fe00:0',dst='fe80::a00:27ff:fe1a:e2a0')
>> 	pkt_too_big=ICMPv6PacketTooBig(mtu=1024)
>> 	ext_base=IPv6(src='fe80::a00:27ff:fe1a:e2a0',dst='fe80::a00:27ff:fe1a:e2a0',plen=24)
>> 	ext_nd_na=ICMPv6ND_NA()
>> 	
>> 	packet=base/pkt_too_big/ext_base/ext_nd_na
>> 	send(packet)
> 
> So it is not a valid pmtu update, this make life easier.
> 
> Can you please test the patch below (compile tested only)?
Sorry, the later. I test it on 3.10-stable. It can fix this problem. So maybe this is a bug?
And the 3 approaches (different flags are used: RTF_LOCAL, IFF_LOOPBACK and RTF_CACHE) in
these mails can fix the expire of local address. I'm confused about these flags:
* RTF_LOCAL: the entries of local address, like address binded to the native NIC
* RTF_CACHE: all cached entries
* IFF_LOOPBACK: this is a device-related flag, which has the same meaning as RTF_LOCAL

Am I right? If so, I think RTF_LOCAL is appropriate, because we just want entries of local
addresses to be not expired and we don't care other entries (I think if they get expired,
a neigh discovery could find them back).

thx,
Sheng
> 
> This should fix your problem, and in combination with the two patches I sent
> out last week, it should cure the whole 'expiring of uncached routes' problem.
> 
> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
> index 49596535..4ccfb9c 100644
> --- a/net/ipv6/route.c
> +++ b/net/ipv6/route.c
> @@ -1156,7 +1156,8 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
>  	struct rt6_info *rt6 = (struct rt6_info *)dst;
>  
>  	dst_confirm(dst);
> -	if (mtu < dst_mtu(dst) && rt6->rt6i_dst.plen == 128) {
> +	if (mtu < dst_mtu(dst) && rt6->rt6i_dst.plen == 128 &&
> +	    (rt6->rt6i_flags & RTF_CACHE)) {
>  		struct net *net = dev_net(dst->dev);
>  
>  		rt6->rt6i_flags |= RTF_MODIFIED;
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> .
> 

^ permalink raw reply

* [PATCH net-next] tcp: do not pace pure ack packets
From: Eric Dumazet @ 2015-02-04  2:31 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Kenneth Klette Jonassen

From: Eric Dumazet <edumazet@google.com>

When we added pacing to TCP, we decided to let sch_fq take care
of actual pacing.

All TCP had to do was to compute sk->pacing_rate using simple formula:

sk->pacing_rate = 2 * cwnd * mss / rtt

It works well for senders (bulk flows), but not very well for receivers
or even RPC :

cwnd on the receiver can be less than 10, rtt can be around 100ms, so we
can end up pacing ACK packets, slowing down the sender.

Really, only the sender should pace, according to its own logic.

Instead of adding a new bit in skb, or call yet another flow
dissection, we tweak skb->truesize to a small value (2), and
we instruct sch_fq to use new helper and not pace pure ack.

Note this also helps TCP small queue, as ack packets present
in qdisc/NIC do not prevent sending a data packet (RPC workload)

This helps to reduce tx completion overhead, ack packets can use regular
sock_wfree() instead of tcp_wfree() which is a bit more expensive.

This has no impact in the case packets are sent to loopback interface,
as we do not coalesce ack packets (were we would detect skb->truesize
lie)

In case netem (with a delay) is used, skb_orphan_partial() also sets
skb->truesize to 1.

This patch is a combination of two patches we used for about one year at
Google.

Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 include/net/tcp.h     |   15 +++++++++++++++
 net/ipv4/tcp_output.c |   10 +++++++++-
 net/sched/sch_fq.c    |   10 ++++++++--
 3 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/include/net/tcp.h b/include/net/tcp.h
index b8fdc6bab3f3..637ee490ec81 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1713,4 +1713,19 @@ static inline struct ip_options_rcu *tcp_v4_save_options(struct sk_buff *skb)
 	return dopt;
 }
 
+/* locally generated TCP pure ACKs have skb->truesize == 2
+ * (check tcp_send_ack() in net/ipv4/tcp_output.c )
+ * This is much faster than dissecting the packet to find out.
+ * (Think of GRE encapsulations, IPv4, IPv6, ...)
+ */
+static inline bool skb_is_tcp_pure_ack(const struct sk_buff *skb)
+{
+	return skb->truesize == 2;
+}
+
+static inline void skb_set_tcp_pure_ack(struct sk_buff *skb)
+{
+	skb->truesize = 2;
+}
+
 #endif	/* _TCP_H */
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 20ab06b228ac..eae35c1ad0aa 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -948,7 +948,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
 
 	skb_orphan(skb);
 	skb->sk = sk;
-	skb->destructor = tcp_wfree;
+	skb->destructor = skb_is_tcp_pure_ack(skb) ? sock_wfree : tcp_wfree;
 	skb_set_hash_from_sk(skb, sk);
 	atomic_add(skb->truesize, &sk->sk_wmem_alloc);
 
@@ -3265,6 +3265,14 @@ void tcp_send_ack(struct sock *sk)
 	skb_reserve(buff, MAX_TCP_HEADER);
 	tcp_init_nondata_skb(buff, tcp_acceptable_seq(sk), TCPHDR_ACK);
 
+	/* We do not want pure acks influencing TCP Small Queues or fq/pacing
+	 * too much.
+	 * SKB_TRUESIZE(max(1 .. 66, MAX_TCP_HEADER)) is unfortunately ~784
+	 * We also avoid tcp_wfree() overhead (cache line miss accessing
+	 * tp->tsq_flags) by using regular sock_wfree()
+	 */
+	skb_set_tcp_pure_ack(buff);
+
 	/* Send it off, this clears delayed acks for us. */
 	skb_mstamp_get(&buff->skb_mstamp);
 	tcp_transmit_skb(sk, buff, 0, sk_gfp_atomic(sk, GFP_ATOMIC));
diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c
index 2a50f5c62070..69a3dbf55c60 100644
--- a/net/sched/sch_fq.c
+++ b/net/sched/sch_fq.c
@@ -52,6 +52,7 @@
 #include <net/pkt_sched.h>
 #include <net/sock.h>
 #include <net/tcp_states.h>
+#include <net/tcp.h>
 
 /*
  * Per flow structure, dynamically allocated
@@ -445,7 +446,9 @@ begin:
 		goto begin;
 	}
 
-	if (unlikely(f->head && now < f->time_next_packet)) {
+	skb = f->head;
+	if (unlikely(skb && now < f->time_next_packet &&
+		     !skb_is_tcp_pure_ack(skb))) {
 		head->first = f->next;
 		fq_flow_set_throttled(q, f);
 		goto begin;
@@ -464,12 +467,15 @@ begin:
 		goto begin;
 	}
 	prefetch(&skb->end);
-	f->time_next_packet = now;
 	f->credit -= qdisc_pkt_len(skb);
 
 	if (f->credit > 0 || !q->rate_enable)
 		goto out;
 
+	/* Do not pace locally generated ack packets */
+	if (skb_is_tcp_pure_ack(skb))
+		goto out;
+
 	rate = q->flow_max_rate;
 	if (skb->sk)
 		rate = min(skb->sk->sk_pacing_rate, rate);

^ permalink raw reply related

* Re: [PATCH 0/6 net-next] rhashtable fixes
From: Ying Xue @ 2015-02-04  2:32 UTC (permalink / raw)
  To: Thomas Graf; +Cc: davem, netdev
In-Reply-To: <20150203172113.GC25410@casper.infradead.org>

On 02/04/2015 01:21 AM, Thomas Graf wrote:
> On 01/30/15 at 05:56pm, Ying Xue wrote:
>> On 01/30/2015 05:29 PM, Thomas Graf wrote:
>>> Right, I see the same soft lockup. Interestingly I cannot trigger it
>>> with the rht test code. I can only trigger it with your Netlink socket
>>> creation stress test. It is definitely related to the deferred worker,
>>> when I disable growing, then the bug disappears.
>>
>> Yes, when I disable expansion, the soft lockup also disappears too.
> 
> I have found the last remaining race and can now run your test
> program successfully in an endless loop.
> 
> I will resubmit a v2 of this series.
> 
> 

Thanks! Once I receive your updates, I will test them again.

Regards,
Ying

^ permalink raw reply

* RE: [PATCH v3 3/3] stmmac: pci: add MSI support for Intel Quark X1000
From: Kweh, Hock Leong @ 2015-02-04  3:49 UTC (permalink / raw)
  To: Bryan O'Donoghue, Andy Shevchenko
  Cc: netdev@vger.kernel.org, davem@davemloft.net, Ahmad, Josef,
	Ong, Boon Leong
In-Reply-To: <54CF9CBF.7080806@nexus-software.ie>

> -----Original Message-----
> From: Bryan O'Donoghue [mailto:pure.logic@nexus-software.ie]
> Sent: Monday, February 02, 2015 11:50 PM
> To: Andy Shevchenko
> Cc: netdev@vger.kernel.org; Kweh, Hock Leong; davem@davemloft.net;
> Ahmad, Josef
> Subject: Re: [PATCH v3 3/3] stmmac: pci: add MSI support for Intel Quark
> X1000
> 
> On 02/02/15 15:46, Andy Shevchenko wrote:
> > On Mon, 2015-02-02 at 15:17 +0000, Bryan O'Donoghue wrote:
> > > Hi guys.
> > >
> > > Has the issue with PVM masking been addressed ?
> > >
> > > https://lkml.org/lkml/2014/10/1/221
> > >
> > > If not then please drop MSIs from this patchset.
> >
> > I do not see the reason why it should be done on per driver basis.
> 
> Agree.
> 
> > Care to fix this under arch/x86 then when adding new Quark platform?
> 
> Looking into that now.
> 
> Hmm - OK -let's aim to get a fix in for the bridge and leave the MSI enable in
> place.
> 

I am also agreeing on that. Thanks.

Regards,
Wilson

^ permalink raw reply

* RE: AF_NETDEV - device specific sockets
From: Zayats, Michael @ 2015-02-04  5:51 UTC (permalink / raw)
  To: John Fastabend; +Cc: netdev@vger.kernel.org, dborkman
In-Reply-To: <54CFBC14.9080908@gmail.com>

> > More specific example would be when NIC performs certain fast path
> > processing, while punting to the CPU for a slow path.
> > Slow path would be interested to know the punt reason.
> >
> > Another example would be if specific NIC strips S-tag in QinQ case and
> > would like to communicate the stripped Tag to the client.
> >
> 
> Right, maybe we need some sort of TLV scheme to pass up the relevant
> info. I'm not sure we want to necessarily bury it in the driver though.
> Perhaps passing auxdata in a TLV format is worth considering.

CMSG formatting in sockets msg_control is pretty close, right?

> 
> Just curious do you have NICs that are stripping or inserting more then
> a single tag?

No, just a single tag.

> 
> For tagging my current scheme is to strip outer tags using this
> experimental Flow  API
> 
> 	http://www.spinics.net/lists/netdev/msg313071.html
> 
> and then only report the inner tag to the stack. At the moment I haven't
> found any use cases this is not sufficient.
> 
> > There might be many types of custom functionality, agreed between the
> > NIC and the clients, which is not generic or not practical enough for
> inclusion in the kernel.
> >
> > That's why I am looking for a generic, socket like mechanism of
> > device<->client, packet + metadata communication, which wouldn't
> require core kernel modification.
> 
> hmm the question is how do the NIC and client "agree" on the format of
> the data and its meaning? If you follow the thread above and also our
> af_packet direct DMA work we are struggling with similar questions,
> 
> 	http://www.spinics.net/lists/netdev/msg311862.html
> 
> I think we need some way to "describe" the meta-data or we need to build
> some kernel/uapi standard that defines them.
> 

Agreed, some kind of standard way to describe the language is needed.
However, I don't think it should preclude us from having a generic mechanism for communicating custom metadata alongside the packets. When client knows, which NIC type it "talks to".
So far, all the custom drivers that I have seen that needed it, ended up exposing chr device and interposing a custom header between the packets. Same approach that TUN is taking for virtio.

> .John
> 
> >
> > Thanks,
> >
> > Michael
> >
> >
> >
> >
> >
> > -----Original Message-----
> > From: John Fastabend [mailto:john.fastabend@gmail.com]
> > Sent: Saturday, January 31, 2015 8:41 PM
> > To: Zayats, Michael
> > Cc: netdev@vger.kernel.org
> > Subject: Re: AF_NETDEV - device specific sockets
> >
> > On 01/31/2015 08:20 PM, Zayats, Michael wrote:
> >> Hi,
> >>
> >> I am looking for a generic mechanism that would allow network device
> >> drivers to provide socket interface to user and kernel space clients.
> >>
> >> Such an interface might be used to provide access to important
> >> sub-streams of packets, alongside with device specific packet
> >> metadata, provided through msg_control fields of recv/sendmsg.
> >>
> >> RX Metadata might include device specific information, such as
> >> queuing priorities applied, potential destination interface in case
> >> of switching hardware etc.
> >>
> >> On the transmission, metadata might be used to indicate hardware
> >> specific required optimizations, as well as any other transformation
> >> or accounting required on the packet.
> >>
> >> AF_PACKET based mechanism doesn't allow metadata to be exchanged
> >> between the client and the device driver. Extending it would require
> >> extending of sk_buff and potentially additional per packet
> operations.
> >> Generic Netlink is not intended to pass packets.
> >>
> >> As I am trying to validate generic applicability of such a mechanism,
> >> I see that TUN driver is providing custom socket interface, in order
> >> to deal with user information through msg_control. Only usable inside
> >> the kernel, through custom interface.
> >
> >> Proposed interface
> >> ------------------
> >> Kernel side:
> >> (struct proto *) should be added to struct net_device.
> >> Device driver that is interested to support socket interface would
> populate the pointer.
> >>
> >
> >> User space: After creating AF_NETDEV socket, the only successful
> >> operation would be setting SO_BINDTODEVICE option. Once set, all
> >> socket operations would be implemented by calling functions, that are
> >> registered at struct proto on the appropriate net_device.
> >>
> >> What do you think?
> >> Would you see a better approach?
> >> Some other mechanism that already exists for such a purpose?
> >
> > It might help to come up with specific examples but an alternate
> proposal would be to use skb->priority field and then mqprio to steer
> the traffic to a specific queue and then bind attributes to the queue.
> >
> > For example the NIC offloaded QOS can be mapped on to queues and then
> sockets mapped to the queues.
> >
> > Another example would be to forward all traffic from one queue to a
> virtual fuction in SR-IOV use case. We don't have an interface to do
> this but I have been working on an API that could be used for this.
> >
> > In this case you don't need to modify AF_PACKET interface but
> configure the device correctly. If you need per-packet control you could
> use 'tc' or 'nftables' to do the steering.
> >
> > .John
> >
> 
> 
> --
> John Fastabend         Intel Corporation

^ permalink raw reply

* Re: [PATCH net-next] cxgb4: Add low latency socket busy_poll support
From: Eric Dumazet @ 2015-02-04  5:58 UTC (permalink / raw)
  To: Hariprasad Shenai
  Cc: netdev, davem, leedom, anish, nirranjan, praveenm, kumaras
In-Reply-To: <1422940816-27402-1-git-send-email-hariprasad@chelsio.com>

On Tue, 2015-02-03 at 10:50 +0530, Hariprasad Shenai wrote:

> @@ -1978,9 +2016,13 @@ static int napi_rx_handler(struct napi_struct *napi, int budget)
>  {
>  	unsigned int params;
>  	struct sge_rspq *q = container_of(napi, struct sge_rspq, napi);
> -	int work_done = process_responses(q, budget);
> +	int work_done = 0;
>  	u32 val;
>  
> +	if (!cxgb_poll_lock_napi(q))
> +		return work_done;
> +


This is very suspicious. Please take a look at commits

24e579c8898aa641 ("bnx2x: fix napi poll return value for repoll") 
f104fedc0da126ab ("enic: fix rx napi poll return value")

for context.

^ permalink raw reply

* Re: [PATCH] tun: orphan an skb on tx
From: David Woodhouse @ 2015-02-04  6:35 UTC (permalink / raw)
  To: David Miller
  Cc: mst, herbert, eric.dumazet, jan.kiszka, netdev, linux-kernel,
	qemu-devel
In-Reply-To: <20150203.161955.1916354877509427788.davem@davemloft.net>

[-- Attachment #1: Type: text/plain, Size: 938 bytes --]

On Tue, 2015-02-03 at 16:19 -0800, David Miller wrote:
> From: David Woodhouse <dwmw2@infradead.org>
> Date: Mon, 02 Feb 2015 07:27:10 +0000
> 
> > I'm guessing you don't want to push the *whole* management of the TLS
> > control connection *and* the UDP transport, and probing the latter with
> > keepalives, into the kernel? I certainly don't :)
> 
> Whilst Herbert Xu and I have discussed in the past supporting
> automatic SSL handling of socket data during socket writes in the
> kernel, doing TLS stuff would be a bit of a stretch :-)

Right. For the DTLS I was thinking we'd do the handshake in userspace
and then hand the UDP socket down. At that point it's basically the same
as ESP with the bytes in a slightly different place.

So I really am looking at an option for "here's a UDP socket to send
those tun packets out on, with <this> encryption setup" as the sanest
plan I can come up with.

-- 
dwmw2


[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 5745 bytes --]

^ permalink raw reply

* Re: [PATCH v2 01/18] netlink: make the check for "send from tx_ring" deterministic
From: Al Viro @ 2015-02-04  6:37 UTC (permalink / raw)
  To: David Miller; +Cc: sergei.shtylyov, netdev
In-Reply-To: <20150203.162102.2178616439474613506.davem@davemloft.net>

On Tue, Feb 03, 2015 at 04:21:02PM -0800, David Miller wrote:
> Indeed, Al can you please audit your whole series for this issue and
> respin?

Done, will repost in followups to this one.

> Please also explicitly give me the GIT url to pull from each time you
> post the series.

OK, it's been force-pushed to
git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git for-davem

Shortlog:
Al Viro (18):
      netlink: make the check for "send from tx_ring" deterministic
      ipv4: raw_send_hdrinc(): pass msghdr
      ipv6: rawv6_send_hdrinc(): pass msghdr
      vmci: propagate msghdr all way down to __qp_memcpy_to_queue()
      rxrpc: switch rxrpc_send_data() to iov_iter primitives
      rxrpc: make the users of rxrpc_kernel_send_data() set kvec-backed msg_iter properly
      ip: stash a pointer to msghdr in struct ping_fakehdr
      ip: convert tcp_sendmsg() to iov_iter primitives
      net: switch memcpy_fromiovec()/memcpy_fromiovecend() users to copy_from_iter()
      tipc: tipc ->sendmsg() conversion
      net: bury net/core/iovec.c - nothing in there is used anymore
      crypto: switch af_alg_make_sg() to iov_iter
      net/socket.c: fold do_sock_{read,write} into callers
      net: switch sockets to ->read_iter/->write_iter
      vhost: switch vhost get_indirect() to iov_iter, kill memcpy_fromiovec()
      vhost: don't bother with copying iovec in handle_tx()
      vhost: don't bother copying iovecs in handle_rx(), kill memcpy_toiovecend()
      vhost: vhost_scsi_handle_vq() should just use copy_from_user()

Diffstat:
 crypto/af_alg.c                         |  40 ++----
 crypto/algif_hash.c                     |  45 +++---
 crypto/algif_skcipher.c                 |  74 +++++-----
 drivers/misc/vmw_vmci/vmci_queue_pair.c |  16 +--
 drivers/vhost/net.c                     |  91 ++++---------
 drivers/vhost/scsi.c                    |   2 +-
 drivers/vhost/vhost.c                   |   6 +-
 fs/afs/rxrpc.c                          |  14 +-
 include/crypto/if_alg.h                 |   3 +-
 include/linux/skbuff.h                  |  14 +-
 include/linux/socket.h                  |   7 -
 include/linux/uio.h                     |   6 -
 include/linux/vmw_vmci_api.h            |   2 +-
 include/net/ping.h                      |   2 +-
 include/net/sock.h                      |  18 ++-
 include/net/udplite.h                   |   3 +-
 lib/Makefile                            |   2 +-
 lib/iovec.c                             |  87 ------------
 net/core/Makefile                       |   2 +-
 net/core/iovec.c                        | 137 -------------------
 net/ipv4/ip_output.c                    |   6 +-
 net/ipv4/ping.c                         |  17 ++-
 net/ipv4/raw.c                          |   7 +-
 net/ipv4/tcp.c                          | 233 +++++++++++++++-----------------
 net/ipv4/tcp_output.c                   |  11 +-
 net/ipv6/ping.c                         |   3 +-
 net/ipv6/raw.c                          |   7 +-
 net/netlink/af_netlink.c                |   5 +
 net/rxrpc/ar-output.c                   |  46 ++-----
 net/socket.c                            |  76 ++++-------
 net/tipc/msg.c                          |   7 +-
 net/tipc/socket.c                       |  14 +-
 net/vmw_vsock/vmci_transport.c          |   3 +-
 33 files changed, 320 insertions(+), 686 deletions(-)
 delete mode 100644 lib/iovec.c
 delete mode 100644 net/core/iovec.c

^ permalink raw reply

* [PATCH v3 15/18] vhost: switch vhost get_indirect() to iov_iter, kill memcpy_fromiovec()
From: Al Viro @ 2015-02-04  6:40 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, virtualization, kvm, Michael S. Tsirkin
In-Reply-To: <20150204063730.GG29656@ZenIV.linux.org.uk>

From: Al Viro <viro@zeniv.linux.org.uk>

Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: kvm@vger.kernel.org
Cc: virtualization@lists.linux-foundation.org
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 drivers/vhost/vhost.c |  6 ++++--
 include/linux/uio.h   |  1 -
 lib/iovec.c           | 25 -------------------------
 3 files changed, 4 insertions(+), 28 deletions(-)

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index cb807d0..2ee2826 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -1125,6 +1125,7 @@ static int get_indirect(struct vhost_virtqueue *vq,
 	struct vring_desc desc;
 	unsigned int i = 0, count, found = 0;
 	u32 len = vhost32_to_cpu(vq, indirect->len);
+	struct iov_iter from;
 	int ret;
 
 	/* Sanity check */
@@ -1142,6 +1143,7 @@ static int get_indirect(struct vhost_virtqueue *vq,
 		vq_err(vq, "Translation failure %d in indirect.\n", ret);
 		return ret;
 	}
+	iov_iter_init(&from, READ, vq->indirect, ret, len);
 
 	/* We will use the result as an address to read from, so most
 	 * architectures only need a compiler barrier here. */
@@ -1164,8 +1166,8 @@ static int get_indirect(struct vhost_virtqueue *vq,
 			       i, count);
 			return -EINVAL;
 		}
-		if (unlikely(memcpy_fromiovec((unsigned char *)&desc,
-					      vq->indirect, sizeof desc))) {
+		if (unlikely(copy_from_iter(&desc, sizeof(desc), &from) !=
+			     sizeof(desc))) {
 			vq_err(vq, "Failed indirect descriptor: idx %d, %zx\n",
 			       i, (size_t)vhost64_to_cpu(vq, indirect->addr) + i * sizeof desc);
 			return -EINVAL;
diff --git a/include/linux/uio.h b/include/linux/uio.h
index 1c5e453..af3439f 100644
--- a/include/linux/uio.h
+++ b/include/linux/uio.h
@@ -135,7 +135,6 @@ static inline void iov_iter_reexpand(struct iov_iter *i, size_t count)
 size_t csum_and_copy_to_iter(void *addr, size_t bytes, __wsum *csum, struct iov_iter *i);
 size_t csum_and_copy_from_iter(void *addr, size_t bytes, __wsum *csum, struct iov_iter *i);
 
-int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
 int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
 			int offset, int len);
 int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata,
diff --git a/lib/iovec.c b/lib/iovec.c
index 2d99cb4..4a90875 100644
--- a/lib/iovec.c
+++ b/lib/iovec.c
@@ -3,31 +3,6 @@
 #include <linux/uio.h>
 
 /*
- *	Copy iovec to kernel. Returns -EFAULT on error.
- *
- *	Note: this modifies the original iovec.
- */
-
-int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len)
-{
-	while (len > 0) {
-		if (iov->iov_len) {
-			int copy = min_t(unsigned int, len, iov->iov_len);
-			if (copy_from_user(kdata, iov->iov_base, copy))
-				return -EFAULT;
-			len -= copy;
-			kdata += copy;
-			iov->iov_base += copy;
-			iov->iov_len -= copy;
-		}
-		iov++;
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(memcpy_fromiovec);
-
-/*
  *	Copy kernel to iovec. Returns -EFAULT on error.
  */
 
-- 
2.1.4

^ permalink raw reply related

* [PATCH v3 16/18] vhost: don't bother with copying iovec in handle_tx()
From: Al Viro @ 2015-02-04  6:40 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, virtualization, kvm, Michael S. Tsirkin
In-Reply-To: <20150204063730.GG29656@ZenIV.linux.org.uk>

From: Al Viro <viro@zeniv.linux.org.uk>

just advance the msg.msg_iter and be done with that.

Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: kvm@vger.kernel.org
Cc: virtualization@lists.linux-foundation.org
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 drivers/vhost/net.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 6906f76..d86cc9b 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -336,7 +336,7 @@ static void handle_tx(struct vhost_net *net)
 {
 	struct vhost_net_virtqueue *nvq = &net->vqs[VHOST_NET_VQ_TX];
 	struct vhost_virtqueue *vq = &nvq->vq;
-	unsigned out, in, s;
+	unsigned out, in;
 	int head;
 	struct msghdr msg = {
 		.msg_name = NULL,
@@ -395,16 +395,17 @@ static void handle_tx(struct vhost_net *net)
 			break;
 		}
 		/* Skip header. TODO: support TSO. */
-		s = move_iovec_hdr(vq->iov, nvq->hdr, hdr_size, out);
 		len = iov_length(vq->iov, out);
 		iov_iter_init(&msg.msg_iter, WRITE, vq->iov, out, len);
+		iov_iter_advance(&msg.msg_iter, hdr_size);
 		/* Sanity check */
-		if (!len) {
+		if (!iov_iter_count(&msg.msg_iter)) {
 			vq_err(vq, "Unexpected header len for TX: "
 			       "%zd expected %zd\n",
-			       iov_length(nvq->hdr, s), hdr_size);
+			       len, hdr_size);
 			break;
 		}
+		len = iov_iter_count(&msg.msg_iter);
 
 		zcopy_used = zcopy && len >= VHOST_GOODCOPY_LEN
 				   && (nvq->upend_idx + 1) % UIO_MAXIOV !=
-- 
2.1.4

^ permalink raw reply related

* [PATCH v3 17/18] vhost: don't bother copying iovecs in handle_rx(), kill memcpy_toiovecend()
From: Al Viro @ 2015-02-04  6:40 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, virtualization, kvm, Michael S. Tsirkin
In-Reply-To: <20150204063730.GG29656@ZenIV.linux.org.uk>

From: Al Viro <viro@zeniv.linux.org.uk>

Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: kvm@vger.kernel.org
Cc: virtualization@lists.linux-foundation.org
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 drivers/vhost/net.c | 82 +++++++++++++++--------------------------------------
 include/linux/uio.h |  3 --
 lib/iovec.c         | 26 -----------------
 3 files changed, 23 insertions(+), 88 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index d86cc9b..e022cc4 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -84,10 +84,6 @@ struct vhost_net_ubuf_ref {
 
 struct vhost_net_virtqueue {
 	struct vhost_virtqueue vq;
-	/* hdr is used to store the virtio header.
-	 * Since each iovec has >= 1 byte length, we never need more than
-	 * header length entries to store the header. */
-	struct iovec hdr[sizeof(struct virtio_net_hdr_mrg_rxbuf)];
 	size_t vhost_hlen;
 	size_t sock_hlen;
 	/* vhost zerocopy support fields below: */
@@ -235,44 +231,6 @@ static bool vhost_sock_zcopy(struct socket *sock)
 		sock_flag(sock->sk, SOCK_ZEROCOPY);
 }
 
-/* Pop first len bytes from iovec. Return number of segments used. */
-static int move_iovec_hdr(struct iovec *from, struct iovec *to,
-			  size_t len, int iov_count)
-{
-	int seg = 0;
-	size_t size;
-
-	while (len && seg < iov_count) {
-		size = min(from->iov_len, len);
-		to->iov_base = from->iov_base;
-		to->iov_len = size;
-		from->iov_len -= size;
-		from->iov_base += size;
-		len -= size;
-		++from;
-		++to;
-		++seg;
-	}
-	return seg;
-}
-/* Copy iovec entries for len bytes from iovec. */
-static void copy_iovec_hdr(const struct iovec *from, struct iovec *to,
-			   size_t len, int iovcount)
-{
-	int seg = 0;
-	size_t size;
-
-	while (len && seg < iovcount) {
-		size = min(from->iov_len, len);
-		to->iov_base = from->iov_base;
-		to->iov_len = size;
-		len -= size;
-		++from;
-		++to;
-		++seg;
-	}
-}
-
 /* In case of DMA done not in order in lower device driver for some reason.
  * upend_idx is used to track end of used idx, done_idx is used to track head
  * of used idx. Once lower device DMA done contiguously, we will signal KVM
@@ -570,9 +528,9 @@ static void handle_rx(struct vhost_net *net)
 		.msg_controllen = 0,
 		.msg_flags = MSG_DONTWAIT,
 	};
-	struct virtio_net_hdr_mrg_rxbuf hdr = {
-		.hdr.flags = 0,
-		.hdr.gso_type = VIRTIO_NET_HDR_GSO_NONE
+	struct virtio_net_hdr hdr = {
+		.flags = 0,
+		.gso_type = VIRTIO_NET_HDR_GSO_NONE
 	};
 	size_t total_len = 0;
 	int err, mergeable;
@@ -580,6 +538,7 @@ static void handle_rx(struct vhost_net *net)
 	size_t vhost_hlen, sock_hlen;
 	size_t vhost_len, sock_len;
 	struct socket *sock;
+	struct iov_iter fixup;
 
 	mutex_lock(&vq->mutex);
 	sock = vq->private_data;
@@ -624,14 +583,19 @@ static void handle_rx(struct vhost_net *net)
 			break;
 		}
 		/* We don't need to be notified again. */
-		if (unlikely((vhost_hlen)))
-			/* Skip header. TODO: support TSO. */
-			move_iovec_hdr(vq->iov, nvq->hdr, vhost_hlen, in);
-		else
-			/* Copy the header for use in VIRTIO_NET_F_MRG_RXBUF:
-			 * needed because recvmsg can modify msg_iov. */
-			copy_iovec_hdr(vq->iov, nvq->hdr, sock_hlen, in);
-		iov_iter_init(&msg.msg_iter, READ, vq->iov, in, sock_len);
+		iov_iter_init(&msg.msg_iter, READ, vq->iov, in, vhost_len);
+		fixup = msg.msg_iter;
+		if (unlikely((vhost_hlen))) {
+			/* We will supply the header ourselves
+			 * TODO: support TSO.
+			 */
+			iov_iter_advance(&msg.msg_iter, vhost_hlen);
+		} else {
+			/* It'll come from socket; we'll need to patch
+			 * ->num_buffers over if VIRTIO_NET_F_MRG_RXBUF
+			 */
+			iov_iter_advance(&fixup, sizeof(hdr));
+		}
 		err = sock->ops->recvmsg(NULL, sock, &msg,
 					 sock_len, MSG_DONTWAIT | MSG_TRUNC);
 		/* Userspace might have consumed the packet meanwhile:
@@ -643,18 +607,18 @@ static void handle_rx(struct vhost_net *net)
 			vhost_discard_vq_desc(vq, headcount);
 			continue;
 		}
+		/* Supply virtio_net_hdr if VHOST_NET_F_VIRTIO_NET_HDR */
 		if (unlikely(vhost_hlen) &&
-		    memcpy_toiovecend(nvq->hdr, (unsigned char *)&hdr, 0,
-				      vhost_hlen)) {
+		    copy_to_iter(&hdr, sizeof(hdr), &fixup) != sizeof(hdr)) {
 			vq_err(vq, "Unable to write vnet_hdr at addr %p\n",
 			       vq->iov->iov_base);
 			break;
 		}
-		/* TODO: Should check and handle checksum. */
+		/* Supply (or replace) ->num_buffers if VIRTIO_NET_F_MRG_RXBUF
+		 * TODO: Should check and handle checksum.
+		 */
 		if (likely(mergeable) &&
-		    memcpy_toiovecend(nvq->hdr, (unsigned char *)&headcount,
-				      offsetof(typeof(hdr), num_buffers),
-				      sizeof hdr.num_buffers)) {
+		    copy_to_iter(&headcount, 2, &fixup) != 2) {
 			vq_err(vq, "Failed num_buffers write");
 			vhost_discard_vq_desc(vq, headcount);
 			break;
diff --git a/include/linux/uio.h b/include/linux/uio.h
index af3439f..02bd8a9 100644
--- a/include/linux/uio.h
+++ b/include/linux/uio.h
@@ -137,7 +137,4 @@ size_t csum_and_copy_from_iter(void *addr, size_t bytes, __wsum *csum, struct io
 
 int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
 			int offset, int len);
-int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata,
-		      int offset, int len);
-
 #endif
diff --git a/lib/iovec.c b/lib/iovec.c
index 4a90875..d8f17a9 100644
--- a/lib/iovec.c
+++ b/lib/iovec.c
@@ -3,32 +3,6 @@
 #include <linux/uio.h>
 
 /*
- *	Copy kernel to iovec. Returns -EFAULT on error.
- */
-
-int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata,
-		      int offset, int len)
-{
-	int copy;
-	for (; len > 0; ++iov) {
-		/* Skip over the finished iovecs */
-		if (unlikely(offset >= iov->iov_len)) {
-			offset -= iov->iov_len;
-			continue;
-		}
-		copy = min_t(unsigned int, iov->iov_len - offset, len);
-		if (copy_to_user(iov->iov_base + offset, kdata, copy))
-			return -EFAULT;
-		offset = 0;
-		kdata += copy;
-		len -= copy;
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(memcpy_toiovecend);
-
-/*
  *	Copy iovec to kernel. Returns -EFAULT on error.
  */
 
-- 
2.1.4

^ permalink raw reply related

* [PATCH v3 18/18] vhost: vhost_scsi_handle_vq() should just use copy_from_user()
From: Al Viro @ 2015-02-04  6:40 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, virtualization, kvm, Michael S. Tsirkin
In-Reply-To: <20150204063730.GG29656@ZenIV.linux.org.uk>

From: Al Viro <viro@zeniv.linux.org.uk>

it has just verified that it asks no more than the length of the
first segment of iovec.

And with that the last user of stuff in lib/iovec.c is gone.
RIP.

Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Nicholas A. Bellinger <nab@linux-iscsi.org>
Cc: kvm@vger.kernel.org
Cc: virtualization@lists.linux-foundation.org
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 drivers/vhost/scsi.c |  2 +-
 include/linux/uio.h  |  2 --
 lib/Makefile         |  2 +-
 lib/iovec.c          | 36 ------------------------------------
 4 files changed, 2 insertions(+), 40 deletions(-)
 delete mode 100644 lib/iovec.c

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index d695b16..dc78d87 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -1079,7 +1079,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
 			       req_size, vq->iov[0].iov_len);
 			break;
 		}
-		ret = memcpy_fromiovecend(req, &vq->iov[0], 0, req_size);
+		ret = copy_from_user(req, vq->iov[0].iov_base, req_size);
 		if (unlikely(ret)) {
 			vq_err(vq, "Faulted on virtio_scsi_cmd_req\n");
 			break;
diff --git a/include/linux/uio.h b/include/linux/uio.h
index 02bd8a9..3e0cb4e 100644
--- a/include/linux/uio.h
+++ b/include/linux/uio.h
@@ -135,6 +135,4 @@ static inline void iov_iter_reexpand(struct iov_iter *i, size_t count)
 size_t csum_and_copy_to_iter(void *addr, size_t bytes, __wsum *csum, struct iov_iter *i);
 size_t csum_and_copy_from_iter(void *addr, size_t bytes, __wsum *csum, struct iov_iter *i);
 
-int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
-			int offset, int len);
 #endif
diff --git a/lib/Makefile b/lib/Makefile
index 3c3b30b..1071d06 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -24,7 +24,7 @@ obj-y	+= lockref.o
 
 obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
 	 bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
-	 gcd.o lcm.o list_sort.o uuid.o flex_array.o iovec.o clz_ctz.o \
+	 gcd.o lcm.o list_sort.o uuid.o flex_array.o clz_ctz.o \
 	 bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o \
 	 percpu-refcount.o percpu_ida.o rhashtable.o reciprocal_div.o
 obj-y += string_helpers.o
diff --git a/lib/iovec.c b/lib/iovec.c
deleted file mode 100644
index d8f17a9..0000000
--- a/lib/iovec.c
+++ /dev/null
@@ -1,36 +0,0 @@
-#include <linux/uaccess.h>
-#include <linux/export.h>
-#include <linux/uio.h>
-
-/*
- *	Copy iovec to kernel. Returns -EFAULT on error.
- */
-
-int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
-			int offset, int len)
-{
-	/* No data? Done! */
-	if (len == 0)
-		return 0;
-
-	/* Skip over the finished iovecs */
-	while (offset >= iov->iov_len) {
-		offset -= iov->iov_len;
-		iov++;
-	}
-
-	while (len > 0) {
-		u8 __user *base = iov->iov_base + offset;
-		int copy = min_t(unsigned int, len, iov->iov_len - offset);
-
-		offset = 0;
-		if (copy_from_user(kdata, base, copy))
-			return -EFAULT;
-		len -= copy;
-		kdata += copy;
-		iov++;
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(memcpy_fromiovecend);
-- 
2.1.4

^ permalink raw reply related

* [PATCH v3 01/18] netlink: make the check for "send from tx_ring" deterministic
From: Al Viro @ 2015-02-04  6:39 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20150204063730.GG29656@ZenIV.linux.org.uk>

From: Al Viro <viro@zeniv.linux.org.uk>

As it is, zero msg_iovlen means that the first iovec in the kernel
array of iovecs is left uninitialized, so checking if its ->iov_base
is NULL is random.  Since the real users of that thing are doing
sendto(fd, NULL, 0, ...), they are getting msg_iovlen = 1 and
msg_iov[0] = {NULL, 0}, which is what this test is trying to catch.
As suggested by davem, let's just check that msg_iovlen was 1 and
msg_iov[0].iov_base was NULL - _that_ is well-defined and it catches
what we want to catch.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 net/netlink/af_netlink.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index a36777b..4fd38a6 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -2298,7 +2298,12 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
 			goto out;
 	}
 
+	/* It's a really convoluted way for userland to ask for mmaped
+	 * sendmsg(), but that's what we've got...
+	 */
 	if (netlink_tx_is_mmaped(sk) &&
+	    msg->msg_iter.type == ITER_IOVEC &&
+	    msg->msg_iter.nr_segs == 1 &&
 	    msg->msg_iter.iov->iov_base == NULL) {
 		err = netlink_mmap_sendmsg(sk, msg, dst_portid, dst_group,
 					   &scm);
-- 
2.1.4

^ permalink raw reply related

* [PATCH v3 03/18] ipv6: rawv6_send_hdrinc(): pass msghdr
From: Al Viro @ 2015-02-04  6:39 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20150204063730.GG29656@ZenIV.linux.org.uk>

From: Al Viro <viro@zeniv.linux.org.uk>

Switch from passing msg->iov_iter.iov to passing msg itself

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 net/ipv6/raw.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index ee25631..0dbb328 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -609,7 +609,7 @@ out:
 	return err;
 }
 
-static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
+static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length,
 			struct flowi6 *fl6, struct dst_entry **dstp,
 			unsigned int flags)
 {
@@ -648,7 +648,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
 	skb->ip_summed = CHECKSUM_NONE;
 
 	skb->transport_header = skb->network_header;
-	err = memcpy_fromiovecend((void *)iph, from, 0, length);
+	err = memcpy_fromiovecend((void *)iph, msg->msg_iter.iov, 0, length);
 	if (err)
 		goto error_fault;
 
@@ -886,8 +886,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
 
 back_from_confirm:
 	if (inet->hdrincl)
-		/* XXX: stripping const */
-		err = rawv6_send_hdrinc(sk, (struct iovec *)msg->msg_iter.iov, len, &fl6, &dst, msg->msg_flags);
+		err = rawv6_send_hdrinc(sk, msg, len, &fl6, &dst, msg->msg_flags);
 	else {
 		lock_sock(sk);
 		err = ip6_append_data(sk, raw6_getfrag, &rfv,
-- 
2.1.4

^ permalink raw reply related

* [PATCH v3 02/18] ipv4: raw_send_hdrinc(): pass msghdr
From: Al Viro @ 2015-02-04  6:39 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20150204063730.GG29656@ZenIV.linux.org.uk>

From: Al Viro <viro@zeniv.linux.org.uk>

Switch from passing msg->iov_iter.iov to passing msg itself

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 net/ipv4/raw.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 0bb68df..2c9d252 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -337,7 +337,7 @@ int raw_rcv(struct sock *sk, struct sk_buff *skb)
 }
 
 static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
-			   void *from, size_t length,
+			   struct msghdr *msg, size_t length,
 			   struct rtable **rtp,
 			   unsigned int flags)
 {
@@ -382,7 +382,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
 
 	skb->transport_header = skb->network_header;
 	err = -EFAULT;
-	if (memcpy_fromiovecend((void *)iph, from, 0, length))
+	if (memcpy_fromiovecend((void *)iph, msg->msg_iter.iov, 0, length))
 		goto error_free;
 
 	iphlen = iph->ihl * 4;
@@ -625,8 +625,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 back_from_confirm:
 
 	if (inet->hdrincl)
-		/* XXX: stripping const */
-		err = raw_send_hdrinc(sk, &fl4, (struct iovec *)msg->msg_iter.iov, len,
+		err = raw_send_hdrinc(sk, &fl4, msg, len,
 				      &rt, msg->msg_flags);
 
 	 else {
-- 
2.1.4

^ permalink raw reply related

* [PATCH v3 04/18] vmci: propagate msghdr all way down to __qp_memcpy_to_queue()
From: Al Viro @ 2015-02-04  6:39 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20150204063730.GG29656@ZenIV.linux.org.uk>

From: Al Viro <viro@zeniv.linux.org.uk>

Switch from passing msg->iov_iter.iov to passing msg itself

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 drivers/misc/vmw_vmci/vmci_queue_pair.c | 16 ++++++++--------
 include/linux/vmw_vmci_api.h            |  2 +-
 net/vmw_vsock/vmci_transport.c          |  3 +--
 3 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/misc/vmw_vmci/vmci_queue_pair.c b/drivers/misc/vmw_vmci/vmci_queue_pair.c
index 7aaaf51..35f19a6 100644
--- a/drivers/misc/vmw_vmci/vmci_queue_pair.c
+++ b/drivers/misc/vmw_vmci/vmci_queue_pair.c
@@ -370,12 +370,12 @@ static int __qp_memcpy_to_queue(struct vmci_queue *queue,
 			to_copy = size - bytes_copied;
 
 		if (is_iovec) {
-			struct iovec *iov = (struct iovec *)src;
+			struct msghdr *msg = (struct msghdr *)src;
 			int err;
 
 			/* The iovec will track bytes_copied internally. */
-			err = memcpy_fromiovec((u8 *)va + page_offset,
-					       iov, to_copy);
+			err = memcpy_from_msg((u8 *)va + page_offset,
+					      msg, to_copy);
 			if (err != 0) {
 				if (kernel_if->host)
 					kunmap(kernel_if->u.h.page[page_index]);
@@ -580,7 +580,7 @@ static int qp_memcpy_from_queue(void *dest,
  */
 static int qp_memcpy_to_queue_iov(struct vmci_queue *queue,
 				  u64 queue_offset,
-				  const void *src,
+				  const void *msg,
 				  size_t src_offset, size_t size)
 {
 
@@ -588,7 +588,7 @@ static int qp_memcpy_to_queue_iov(struct vmci_queue *queue,
 	 * We ignore src_offset because src is really a struct iovec * and will
 	 * maintain offset internally.
 	 */
-	return __qp_memcpy_to_queue(queue, queue_offset, src, size, true);
+	return __qp_memcpy_to_queue(queue, queue_offset, msg, size, true);
 }
 
 /*
@@ -3223,13 +3223,13 @@ EXPORT_SYMBOL_GPL(vmci_qpair_peek);
  * of bytes enqueued or < 0 on error.
  */
 ssize_t vmci_qpair_enquev(struct vmci_qp *qpair,
-			  void *iov,
+			  struct msghdr *msg,
 			  size_t iov_size,
 			  int buf_type)
 {
 	ssize_t result;
 
-	if (!qpair || !iov)
+	if (!qpair)
 		return VMCI_ERROR_INVALID_ARGS;
 
 	qp_lock(qpair);
@@ -3238,7 +3238,7 @@ ssize_t vmci_qpair_enquev(struct vmci_qp *qpair,
 		result = qp_enqueue_locked(qpair->produce_q,
 					   qpair->consume_q,
 					   qpair->produce_q_size,
-					   iov, iov_size,
+					   msg, iov_size,
 					   qp_memcpy_to_queue_iov);
 
 		if (result == VMCI_ERROR_QUEUEPAIR_NOT_READY &&
diff --git a/include/linux/vmw_vmci_api.h b/include/linux/vmw_vmci_api.h
index 5691f75..63df3a2a 100644
--- a/include/linux/vmw_vmci_api.h
+++ b/include/linux/vmw_vmci_api.h
@@ -74,7 +74,7 @@ ssize_t vmci_qpair_dequeue(struct vmci_qp *qpair,
 ssize_t vmci_qpair_peek(struct vmci_qp *qpair, void *buf, size_t buf_size,
 			int mode);
 ssize_t vmci_qpair_enquev(struct vmci_qp *qpair,
-			  void *iov, size_t iov_size, int mode);
+			  struct msghdr *msg, size_t iov_size, int mode);
 ssize_t vmci_qpair_dequev(struct vmci_qp *qpair,
 			  struct msghdr *msg, size_t iov_size, int mode);
 ssize_t vmci_qpair_peekv(struct vmci_qp *qpair, struct msghdr *msg, size_t iov_size,
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
index 02d2e52..7f32550 100644
--- a/net/vmw_vsock/vmci_transport.c
+++ b/net/vmw_vsock/vmci_transport.c
@@ -1850,8 +1850,7 @@ static ssize_t vmci_transport_stream_enqueue(
 	struct msghdr *msg,
 	size_t len)
 {
-	/* XXX: stripping const */
-	return vmci_qpair_enquev(vmci_trans(vsk)->qpair, (struct iovec *)msg->msg_iter.iov, len, 0);
+	return vmci_qpair_enquev(vmci_trans(vsk)->qpair, msg, len, 0);
 }
 
 static s64 vmci_transport_stream_has_data(struct vsock_sock *vsk)
-- 
2.1.4

^ permalink raw reply related

* [PATCH v3 06/18] rxrpc: make the users of rxrpc_kernel_send_data() set kvec-backed msg_iter properly
From: Al Viro @ 2015-02-04  6:39 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20150204063730.GG29656@ZenIV.linux.org.uk>

From: Al Viro <viro@zeniv.linux.org.uk>

Use iov_iter_kvec() there, get rid of set_fs() games - now that
rxrpc_send_data() uses iov_iter primitives, it'll handle ITER_KVEC just
fine.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/afs/rxrpc.c        | 14 +++++++-------
 net/rxrpc/ar-output.c |  3 ---
 2 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c
index 06e14bf..dbc732e 100644
--- a/fs/afs/rxrpc.c
+++ b/fs/afs/rxrpc.c
@@ -306,8 +306,8 @@ static int afs_send_pages(struct afs_call *call, struct msghdr *msg,
 
 			_debug("- range %u-%u%s",
 			       offset, to, msg->msg_flags ? " [more]" : "");
-			iov_iter_init(&msg->msg_iter, WRITE,
-				      (struct iovec *) iov, 1, to - offset);
+			iov_iter_kvec(&msg->msg_iter, WRITE | ITER_KVEC,
+				      iov, 1, to - offset);
 
 			/* have to change the state *before* sending the last
 			 * packet as RxRPC might give us the reply before it
@@ -384,7 +384,7 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp,
 
 	msg.msg_name		= NULL;
 	msg.msg_namelen		= 0;
-	iov_iter_init(&msg.msg_iter, WRITE, (struct iovec *)iov, 1,
+	iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, iov, 1,
 		      call->request_size);
 	msg.msg_control		= NULL;
 	msg.msg_controllen	= 0;
@@ -770,7 +770,7 @@ static int afs_deliver_cm_op_id(struct afs_call *call, struct sk_buff *skb,
 void afs_send_empty_reply(struct afs_call *call)
 {
 	struct msghdr msg;
-	struct iovec iov[1];
+	struct kvec iov[1];
 
 	_enter("");
 
@@ -778,7 +778,7 @@ void afs_send_empty_reply(struct afs_call *call)
 	iov[0].iov_len		= 0;
 	msg.msg_name		= NULL;
 	msg.msg_namelen		= 0;
-	iov_iter_init(&msg.msg_iter, WRITE, iov, 0, 0);	/* WTF? */
+	iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, iov, 0, 0);	/* WTF? */
 	msg.msg_control		= NULL;
 	msg.msg_controllen	= 0;
 	msg.msg_flags		= 0;
@@ -805,7 +805,7 @@ void afs_send_empty_reply(struct afs_call *call)
 void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len)
 {
 	struct msghdr msg;
-	struct iovec iov[1];
+	struct kvec iov[1];
 	int n;
 
 	_enter("");
@@ -814,7 +814,7 @@ void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len)
 	iov[0].iov_len		= len;
 	msg.msg_name		= NULL;
 	msg.msg_namelen		= 0;
-	iov_iter_init(&msg.msg_iter, WRITE, iov, 1, len);
+	iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, iov, 1, len);
 	msg.msg_control		= NULL;
 	msg.msg_controllen	= 0;
 	msg.msg_flags		= 0;
diff --git a/net/rxrpc/ar-output.c b/net/rxrpc/ar-output.c
index 963a5b9..8331c95 100644
--- a/net/rxrpc/ar-output.c
+++ b/net/rxrpc/ar-output.c
@@ -232,10 +232,7 @@ int rxrpc_kernel_send_data(struct rxrpc_call *call, struct msghdr *msg,
 		   call->state != RXRPC_CALL_SERVER_SEND_REPLY) {
 		ret = -EPROTO; /* request phase complete for this client call */
 	} else {
-		mm_segment_t oldfs = get_fs();
-		set_fs(KERNEL_DS);
 		ret = rxrpc_send_data(NULL, call->socket, call, msg, len);
-		set_fs(oldfs);
 	}
 
 	release_sock(&call->socket->sk);
-- 
2.1.4

^ permalink raw reply related

* [PATCH v3 05/18] rxrpc: switch rxrpc_send_data() to iov_iter primitives
From: Al Viro @ 2015-02-04  6:39 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20150204063730.GG29656@ZenIV.linux.org.uk>

From: Al Viro <viro@zeniv.linux.org.uk>

Convert skb_add_data() to iov_iter; allows to get rid of the explicit
messing with iovec in its only caller - skb_add_data() will keep advancing
->msg_iter for us, so there's no need to similate that manually.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 include/linux/skbuff.h | 11 +++++------
 net/rxrpc/ar-output.c  | 43 ++++++++++---------------------------------
 2 files changed, 15 insertions(+), 39 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 85ab7d7..9a8bafe 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2484,19 +2484,18 @@ static inline int skb_put_padto(struct sk_buff *skb, unsigned int len)
 }
 
 static inline int skb_add_data(struct sk_buff *skb,
-			       char __user *from, int copy)
+			       struct iov_iter *from, int copy)
 {
 	const int off = skb->len;
 
 	if (skb->ip_summed == CHECKSUM_NONE) {
-		int err = 0;
-		__wsum csum = csum_and_copy_from_user(from, skb_put(skb, copy),
-							    copy, 0, &err);
-		if (!err) {
+		__wsum csum = 0;
+		if (csum_and_copy_from_iter(skb_put(skb, copy), copy,
+					    &csum, from) == copy) {
 			skb->csum = csum_block_add(skb->csum, csum, off);
 			return 0;
 		}
-	} else if (!copy_from_user(skb_put(skb, copy), from, copy))
+	} else if (copy_from_iter(skb_put(skb, copy), copy, from) == copy)
 		return 0;
 
 	__skb_trim(skb, off);
diff --git a/net/rxrpc/ar-output.c b/net/rxrpc/ar-output.c
index e1a9373..963a5b9 100644
--- a/net/rxrpc/ar-output.c
+++ b/net/rxrpc/ar-output.c
@@ -529,13 +529,11 @@ static int rxrpc_send_data(struct kiocb *iocb,
 			   struct msghdr *msg, size_t len)
 {
 	struct rxrpc_skb_priv *sp;
-	unsigned char __user *from;
 	struct sk_buff *skb;
-	const struct iovec *iov;
 	struct sock *sk = &rx->sk;
 	long timeo;
 	bool more;
-	int ret, ioc, segment, copied;
+	int ret, copied;
 
 	timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
 
@@ -545,25 +543,17 @@ static int rxrpc_send_data(struct kiocb *iocb,
 	if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
 		return -EPIPE;
 
-	iov = msg->msg_iter.iov;
-	ioc = msg->msg_iter.nr_segs - 1;
-	from = iov->iov_base;
-	segment = iov->iov_len;
-	iov++;
 	more = msg->msg_flags & MSG_MORE;
 
 	skb = call->tx_pending;
 	call->tx_pending = NULL;
 
 	copied = 0;
-	do {
+	if (len > iov_iter_count(&msg->msg_iter))
+		len = iov_iter_count(&msg->msg_iter);
+	while (len) {
 		int copy;
 
-		if (segment > len)
-			segment = len;
-
-		_debug("SEGMENT %d @%p", segment, from);
-
 		if (!skb) {
 			size_t size, chunk, max, space;
 
@@ -631,13 +621,13 @@ static int rxrpc_send_data(struct kiocb *iocb,
 		/* append next segment of data to the current buffer */
 		copy = skb_tailroom(skb);
 		ASSERTCMP(copy, >, 0);
-		if (copy > segment)
-			copy = segment;
+		if (copy > len)
+			copy = len;
 		if (copy > sp->remain)
 			copy = sp->remain;
 
 		_debug("add");
-		ret = skb_add_data(skb, from, copy);
+		ret = skb_add_data(skb, &msg->msg_iter, copy);
 		_debug("added");
 		if (ret < 0)
 			goto efault;
@@ -646,18 +636,6 @@ static int rxrpc_send_data(struct kiocb *iocb,
 		copied += copy;
 
 		len -= copy;
-		segment -= copy;
-		from += copy;
-		while (segment == 0 && ioc > 0) {
-			from = iov->iov_base;
-			segment = iov->iov_len;
-			iov++;
-			ioc--;
-		}
-		if (len == 0) {
-			segment = 0;
-			ioc = 0;
-		}
 
 		/* check for the far side aborting the call or a network error
 		 * occurring */
@@ -665,7 +643,7 @@ static int rxrpc_send_data(struct kiocb *iocb,
 			goto call_aborted;
 
 		/* add the packet to the send queue if it's now full */
-		if (sp->remain <= 0 || (segment == 0 && !more)) {
+		if (sp->remain <= 0 || (!len && !more)) {
 			struct rxrpc_connection *conn = call->conn;
 			uint32_t seq;
 			size_t pad;
@@ -711,11 +689,10 @@ static int rxrpc_send_data(struct kiocb *iocb,
 
 			memcpy(skb->head, &sp->hdr,
 			       sizeof(struct rxrpc_header));
-			rxrpc_queue_packet(call, skb, segment == 0 && !more);
+			rxrpc_queue_packet(call, skb, !iov_iter_count(&msg->msg_iter) && !more);
 			skb = NULL;
 		}
-
-	} while (segment > 0);
+	}
 
 success:
 	ret = copied;
-- 
2.1.4

^ permalink raw reply related

* [PATCH v3 07/18] ip: stash a pointer to msghdr in struct ping_fakehdr
From: Al Viro @ 2015-02-04  6:39 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20150204063730.GG29656@ZenIV.linux.org.uk>

From: Al Viro <viro@zeniv.linux.org.uk>

... instead of storing its ->mgs_iter.iov there

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 include/net/ping.h | 2 +-
 net/ipv4/ping.c    | 7 +++----
 net/ipv6/ping.c    | 3 +--
 3 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/include/net/ping.h b/include/net/ping.h
index f074060..cc16d41 100644
--- a/include/net/ping.h
+++ b/include/net/ping.h
@@ -59,7 +59,7 @@ extern struct pingv6_ops pingv6_ops;
 
 struct pingfakehdr {
 	struct icmphdr icmph;
-	struct iovec *iov;
+	struct msghdr *msg;
 	sa_family_t family;
 	__wsum wcheck;
 };
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 2a3720f..9e15ba7 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -602,14 +602,14 @@ int ping_getfrag(void *from, char *to,
 		if (fraglen < sizeof(struct icmphdr))
 			BUG();
 		if (csum_partial_copy_fromiovecend(to + sizeof(struct icmphdr),
-			    pfh->iov, 0, fraglen - sizeof(struct icmphdr),
+			    pfh->msg->msg_iter.iov, 0, fraglen - sizeof(struct icmphdr),
 			    &pfh->wcheck))
 			return -EFAULT;
 	} else if (offset < sizeof(struct icmphdr)) {
 			BUG();
 	} else {
 		if (csum_partial_copy_fromiovecend
-				(to, pfh->iov, offset - sizeof(struct icmphdr),
+				(to, pfh->msg->msg_iter.iov, offset - sizeof(struct icmphdr),
 				 fraglen, &pfh->wcheck))
 			return -EFAULT;
 	}
@@ -811,8 +811,7 @@ back_from_confirm:
 	pfh.icmph.checksum = 0;
 	pfh.icmph.un.echo.id = inet->inet_sport;
 	pfh.icmph.un.echo.sequence = user_icmph.un.echo.sequence;
-	/* XXX: stripping const */
-	pfh.iov = (struct iovec *)msg->msg_iter.iov;
+	pfh.msg = msg;
 	pfh.wcheck = 0;
 	pfh.family = AF_INET;
 
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
index 2d31483..bd46f73 100644
--- a/net/ipv6/ping.c
+++ b/net/ipv6/ping.c
@@ -163,8 +163,7 @@ int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 	pfh.icmph.checksum = 0;
 	pfh.icmph.un.echo.id = inet->inet_sport;
 	pfh.icmph.un.echo.sequence = user_icmph.icmp6_sequence;
-	/* XXX: stripping const */
-	pfh.iov = (struct iovec *)msg->msg_iter.iov;
+	pfh.msg = msg;
 	pfh.wcheck = 0;
 	pfh.family = AF_INET6;
 
-- 
2.1.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