Netdev List
 help / color / mirror / Atom feed
* [PATCH v3 0/8] net: can: Use syscon regmap for TI specific RAMINIT register
From: Roger Quadros @ 2014-11-04 10:20 UTC (permalink / raw)
  To: wg, mkl
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar, nm,
	sergei.shtylyov, linux-omap, linux-can, netdev, Roger Quadros

Hi,

Some hardware (TI am43xx) has a buggy RAMINIT DONE mechanism and it might
not always set the DONE bit. This will result in a lockup in c_can_hw_raminit_wait_ti(),
so patch 1 adds a timeout mechanism there.

There is a non compliancy within TI platforms with respect to the
layout of the RAMINIT register. The patches 2 and 3 address this issue
and make a flexible but standard way of defining the RAMINIT hardware register
layout in the device tree. The RAMINIT register is accessed using the syscon
regmap framework.

Patches available at
git@github.com:rogerq/linux.git	[for-v3.19/can]

Patches are tested on am335x-evm, am437x-gp-evm and dra7-evm.
Board support files to allow CAN testing on these boards are available at
git@github.com:rogerq/linux.git	[for-v3.19/omap-dts-dcan]

Changelog:

v3:
- allow driver data to be more than just CAN_ID
- RAMINIT register data moved to driver data instead of device tree file.

v2:
- added "ti" vendor prefix to TI specific raminit properties.
- split DTS changes into a separate series

cheers,
-roger
---

Roger Quadros (8):
  net: can: c_can: Add timeout to c_can_hw_raminit_ti()
  net: can: c_can: Introduce c_can_driver_data structure
  net: can: c_can: Add RAMINIT register information to driver data
  net: can: c_can: Add syscon/regmap RAMINIT mechanism
  net: can: c_can: Add support for START pulse in RAMINIT sequence
  net: can: c_can: Disable pins when CAN interface is down
  net: can: c_can: Add support for TI DRA7 DCAN
  net: can: c_can: Add support for TI am3352 DCAN

 .../devicetree/bindings/net/can/c_can.txt          |   5 +
 drivers/net/can/c_can/c_can.c                      |  20 ++
 drivers/net/can/c_can/c_can.h                      |  20 +-
 drivers/net/can/c_can/c_can_platform.c             | 207 +++++++++++++++------
 4 files changed, 191 insertions(+), 61 deletions(-)

-- 
1.8.3.2


^ permalink raw reply

* RE: TCP NewReno and single retransmit
From: David Laight @ 2014-11-04  9:56 UTC (permalink / raw)
  To: 'Neal Cardwell', Marcelo Ricardo Leitner
  Cc: Yuchung Cheng, netdev, Eric Dumazet
In-Reply-To: <CADVnQykXpA_A87+bFOCdbb-QLTRf-5TEgspCzE-STO49N+6waw@mail.gmail.com>

> Since there are no literal IETF-style "MUST" statements in RFC2582, I
> think the "MUST" in the code here is expressing the design philosophy
> behind the author. :-)

I wouldn't guarantee that the authors of any RFC (or other
standards document) managed to cover all possible cases.

	David


^ permalink raw reply

* Re: [PATCH net-next 3/7] bpf: add array type of eBPF maps
From: Daniel Borkmann @ 2014-11-04  9:58 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: David S. Miller, Ingo Molnar, Andy Lutomirski,
	Hannes Frederic Sowa, Eric Dumazet, linux-api, netdev,
	linux-kernel
In-Reply-To: <1415069656-14138-4-git-send-email-ast@plumgrid.com>

On 11/04/2014 03:54 AM, Alexei Starovoitov wrote:
> add new map type BPF_MAP_TYPE_ARRAY and its implementation
>
> - optimized for fastest possible lookup()
>    . in the future verifier/JIT may recognize lookup() with constant key
>      and optimize it into constant pointer. Can optimize non-constant
>      key into direct pointer arithmetic as well, since pointers and
>      value_size are constant for the life of the eBPF program.
>      In other words array_map_lookup_elem() may be 'inlined' by verifier/JIT
>      while preserving concurrent access to this map from user space
>
> - two main use cases for array type:
>    . 'global' eBPF variables: array of 1 element with key=0 and value is a
>      collection of 'global' variables which programs can use to keep the state
>      between events
>    . aggregation of tracing events into fixed set of buckets
>
> - all array elements pre-allocated and zero initialized at init time
>
> - key as an index in array and can only be 4 byte
>
> - map_delete_elem() returns EINVAL, since elements cannot be deleted
>
> - map_update_elem() replaces elements in an non-atomic way
>    (for atomic updates hashtable type should be used instead)
>
> Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>

...
> +/* Called from syscall or from eBPF program */
> +static int array_map_update_elem(struct bpf_map *map, void *key, void *value,
> +				 u64 map_flags)
> +{
> +	struct bpf_array *array = container_of(map, struct bpf_array, map);
> +	u32 index = *(u32 *)key;
> +
> +	if (map_flags > BPF_MAP_UPDATE_ONLY)
> +		/* unknown flags */
> +		return -EINVAL;
> +
> +	if (map_flags == BPF_MAP_CREATE_ONLY)
> +		return -EINVAL;
> +
> +	if (index >= array->map.max_entries)
> +		/* all elements were pre-allocated, cannot insert a new one */
> +		return -E2BIG;
> +
> +	memcpy(array->value + array->elem_size * index, value, array->elem_size);

What would protect this from concurrent updates?

> +	return 0;
> +}

^ permalink raw reply

* Re: [PATCH net-next 6/7] bpf: allow eBPF programs to use maps
From: Daniel Borkmann @ 2014-11-04  9:50 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: David S. Miller, Ingo Molnar, Andy Lutomirski,
	Hannes Frederic Sowa, Eric Dumazet,
	linux-api-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1415069656-14138-7-git-send-email-ast-uqk4Ao+rVK5Wk0Htik3J/w@public.gmane.org>

On 11/04/2014 03:54 AM, Alexei Starovoitov wrote:
> expose bpf_map_lookup_elem(), bpf_map_update_elem(), bpf_map_delete_elem()
> map accessors to eBPF programs
>
> Signed-off-by: Alexei Starovoitov <ast-uqk4Ao+rVK5Wk0Htik3J/w@public.gmane.org>
...
> +#include <linux/bpf.h>
> +#include <linux/rcupdate.h>
> +
> +/* called from eBPF program under rcu lock
> + *
> + * if kernel subsystem is allowing eBPF programs to call this function,
> + * inside its own verifier_ops->get_func_proto() callback it should return
> + * bpf_map_lookup_elem_proto, so that verifier can properly checks the arguments
> + */
> +static u64 bpf_map_lookup_elem(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
> +{
> +	/* verifier checked that R1 contains a valid pointer to bpf_map
> +	 * and R2 points to a program stack and map->key_size bytes were
> +	 * initialized
> +	 */
> +	struct bpf_map *map = (struct bpf_map *) (unsigned long) r1;
> +	void *key = (void *) (unsigned long) r2;
> +	void *value;
> +
> +	WARN_ON_ONCE(!rcu_read_lock_held());
> +
> +	value = map->ops->map_lookup_elem(map, key);
> +
> +	/* lookup() returns either pointer to element value or NULL
> +	 * which is the meaning of PTR_TO_MAP_VALUE_OR_NULL type
> +	 */
> +	return (unsigned long) value;
> +}
> +
> +struct bpf_func_proto bpf_map_lookup_elem_proto = {
> +	.func = bpf_map_lookup_elem,
> +	.gpl_only = false,
> +	.ret_type = RET_PTR_TO_MAP_VALUE_OR_NULL,
> +	.arg1_type = ARG_CONST_MAP_PTR,
> +	.arg2_type = ARG_PTR_TO_MAP_KEY,
> +};
> +
> +/* called from eBPF program under rcu lock */
> +static u64 bpf_map_update_elem(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
> +{
> +	struct bpf_map *map = (struct bpf_map *) (unsigned long) r1;
> +	void *key = (void *) (unsigned long) r2;
> +	void *value = (void *) (unsigned long) r3;
> +
> +	WARN_ON_ONCE(!rcu_read_lock_held());
> +
> +	return map->ops->map_update_elem(map, key, value, r4);
> +}
> +
> +struct bpf_func_proto bpf_map_update_elem_proto = {
> +	.func = bpf_map_update_elem,
> +	.gpl_only = false,
> +	.ret_type = RET_INTEGER,
> +	.arg1_type = ARG_CONST_MAP_PTR,
> +	.arg2_type = ARG_PTR_TO_MAP_KEY,
> +	.arg3_type = ARG_PTR_TO_MAP_VALUE,
> +	.arg4_type = ARG_ANYTHING,
> +};
> +
> +/* called from eBPF program under rcu lock */
> +static u64 bpf_map_delete_elem(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
> +{
> +	struct bpf_map *map = (struct bpf_map *) (unsigned long) r1;
> +	void *key = (void *) (unsigned long) r2;
> +
> +	WARN_ON_ONCE(!rcu_read_lock_held());
> +
> +	return map->ops->map_delete_elem(map, key);
> +}

These WARN_ON_ONCE(!rcu_read_lock_held()) seem odd. While I see the point that
you're holding RCU read lock on the lookup, can you elaborate on your RCU usage
here and why it's necessary for delete/update?

I suspect due to the synchronize_rcu() you're using and not using any RCU
accessors but plain memcpy() e.g. in case of the array ...?

> +struct bpf_func_proto bpf_map_delete_elem_proto = {
> +	.func = bpf_map_delete_elem,
> +	.gpl_only = false,
> +	.ret_type = RET_INTEGER,
> +	.arg1_type = ARG_CONST_MAP_PTR,
> +	.arg2_type = ARG_PTR_TO_MAP_KEY,
> +};
>

^ permalink raw reply

* Re: "asix: Don't reset PHY on if_up for ASIX 88772" breaks net on arndale platform
From: Riku Voipio @ 2014-11-04  9:43 UTC (permalink / raw)
  To: Stam, Michel [FINT]
  Cc: Riku Voipio, davem, linux-usb, netdev, linux-kernel,
	linux-samsung-soc, ckeepax
In-Reply-To: <C89EFD3CD56F64468D3D206D683A8D2203985F49@ldam-msx2.fugro-nl.local>

On Tue, Nov 04, 2014 at 09:19:26AM +0100, Stam, Michel [FINT] wrote:
> Interesting, as the commit itself is a revert from a kernel back to 2.6
> somewhere. The problem I had is related to the PHY being reset on
> interface-up, can you confirm that you require this?

I can't confirm what exactly is needed on arndale. I'm neither expert in 
USB or ethernet. However, I can confirm that without the PHY reset,
networking doesn't work on arndale.

I now see someone else has the same problem, adding Charles to CC.

http://www.spinics.net/lists/linux-usb/msg116656.html

> Reverting this
> breaks ethtool support in turn.

Fixing a bug (ethtool support) must not cause breakage elsewhere (in
this case on arndale). This is now a regression of functionality from
3.17.

I think it would better to revert the change now and with less hurry
introduce a ethtool fix that doesn't break arndale.
 
> Kind regards,
> 
> Michel Stam
> 
> -----Original Message-----
> From: Riku Voipio [mailto:riku.voipio@iki.fi] 
> Sent: Tuesday, November 04, 2014 8:23 AM
> To: davem@davemloft.net; Stam, Michel [FINT]
> Cc: linux-usb@vger.kernel.org; netdev@vger.kernel.org;
> linux-kernel@vger.kernel.org; linux-samsung-soc@vger.kernel.org
> Subject: "asix: Don't reset PHY on if_up for ASIX 88772" breaks net on
> arndale platform
> 
> Hi,
> 
> With 3.18-rc3, asix on arndale (samsung exynos 5250 based board), fails
> to work. Interface is initialized but network traffic seem not to pass
> through. With kernel IP config the result looks like:
> 
> [    3.323275] usb 3-3.2.4: new high-speed USB device number 4 using
> exynos-ehci
> [    3.419151] usb 3-3.2.4: New USB device found, idVendor=0b95,
> idProduct=772a
> [    3.424735] usb 3-3.2.4: New USB device strings: Mfr=1, Product=2,
> SerialNumber=3
> [    3.432196] usb 3-3.2.4: Product: AX88772 
> [    3.436279] usb 3-3.2.4: Manufacturer: ASIX Elec. Corp.
> [    3.441486] usb 3-3.2.4: SerialNumber: 000001
> [    3.447530] asix 3-3.2.4:1.0 (unnamed net_device) (uninitialized):
> invalid hw address, using random
> [    3.764352] asix 3-3.2.4:1.0 eth0: register 'asix' at
> usb-12110000.usb-3.2.4, ASIX AX88772 USB 2.0 Ethernet, de:a2:66:bf:ca:4f
> [    4.488773] asix 3-3.2.4:1.0 eth0: link down
> [    5.690025] asix 3-3.2.4:1.0 eth0: link up, 100Mbps, full-duplex, lpa
> 0xC5E1
> [    5.712947] Sending DHCP requests ...... timed out!
> [   83.165303] IP-Config: Retrying forever (NFS root)...
> [   83.170397] asix 3-3.2.4:1.0 eth0: link up, 100Mbps, full-duplex, lpa
> 0xC5E1
> [   83.192944] Sending DHCP requests .....
> 
> Similar results also with dhclient. Git bisect identified the breaking
> commit as:
> 
> commit 3cc81d85ee01e5a0b7ea2f4190e2ed1165f53c31
> Author: Michel Stam <m.stam@fugro.nl>
> Date:   Thu Oct 2 10:22:02 2014 +0200
> 
>     asix: Don't reset PHY on if_up for ASIX 88772
> 
> Taking 3.18-rc3 and that commit reverted, network works again:
> 
> [    3.303500] usb 3-3.2.4: new high-speed USB device number 4 using
> exynos-ehci
> [    3.399375] usb 3-3.2.4: New USB device found, idVendor=0b95,
> idProduct=772a
> [    3.404963] usb 3-3.2.4: New USB device strings: Mfr=1, Product=2,
> SerialNumber=3
> [    3.412424] usb 3-3.2.4: Product: AX88772 
> [    3.416508] usb 3-3.2.4: Manufacturer: ASIX Elec. Corp.
> [    3.421715] usb 3-3.2.4: SerialNumber: 000001
> [    3.427755] asix 3-3.2.4:1.0 (unnamed net_device) (uninitialized):
> invalid hw address, using random
> [    3.744837] asix 3-3.2.4:1.0 eth0: register 'asix' at
> usb-12110000.usb-3.2.4, ASIX AX88772 USB 2.0 Ethernet, 12:59:f1:a8:43:90
> [    7.098998] asix 3-3.2.4:1.0 eth0: link up, 100Mbps, full-duplex, lpa
> 0xC5E1
> [    7.118258] Sending DHCP requests ., OK
> [    9.753259] IP-Config: Got DHCP answer from 192.168.1.1, my address
> is 192.168.1.111
> 
> There might something wrong on the samsung platform code (I understand
> the USB on arndale is "funny"), but this is still an regression from
> 3.17.
> 
> Riku

^ permalink raw reply

* [PATCH 1/1] ip-link: in human readable output use dynamic precision length
From: Christian Hesse @ 2014-11-04  9:39 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Christian Hesse

Now that we use floating point numbers for human readable output we can
calculate precision length on the fly.
---
 ip/ipaddress.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index e240bb5..0ddcb0d 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -343,8 +343,8 @@ static void print_num(FILE *fp, unsigned width, uint64_t count)
 		++prefix;
 	}
 
-	snprintf(buf, sizeof(buf), "%.1f%c%s", (double) count / powi, 
-		 *prefix, use_iec ? "i" : "");
+	snprintf(buf, sizeof(buf), "%.*f%c%s", 3 - snprintf(NULL, 0, "%"PRIu64, count / powi),
+		(double) count / powi, *prefix, use_iec ? "i" : "");
 
 	fprintf(fp, "%-*s ", width, buf);
 }
-- 
2.1.3

^ permalink raw reply related

* Re: [PATCH v1 1/2] dtb: xgene: fix: Disable 10GbE and SGMII based 1GbE by default
From: Arnd Bergmann @ 2014-11-04  9:40 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Iyappan Subramanian,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, netdev,
	patches, Keyur Chudgar, David Miller
In-Reply-To: <CAKh23FkVrPdCuR6dn1S4RvW14_f4Xq8MWaChUh9DyVp44kVtSg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On Monday 03 November 2014 11:45:44 Iyappan Subramanian wrote:
> 
> On Thu, Oct 30, 2014 at 3:13 AM, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> > On Wednesday 29 October 2014 17:56:19 Iyappan Subramanian wrote:
> >> @@ -621,7 +621,7 @@
> >>                         };
> >>                 };
> >>
> >> -               sgenet0: ethernet@1f210000 {
> >> +               sgenet0: sgenet@1f210000 {
> >>                         compatible = "apm,xgene-enet";
> >>                         status = "disabled";
> >>                         reg = <0x0 0x1f210000 0x0 0x10000>,
> >>
> >
> > This looks like you accidentally reverted a bug fix made earlier.
> > Network devices should always have the name 'ethernet@...'.
> 
> Thanks for the review.  Since our firmware was patching the dtb, based
> on the node-name, we thought by changing node-name, we can avoid the
> patching and maintain backward compatibility.
> 
> Now we know that network devices should have 'ethernet@...', we will
> handle the backward compatibility in a different way and will post the
> patch v2 shortly.

It's not important enough to break backwards compatibility over this.
If you can't find a better way to handle compatibility with the old
firmware, just add a comment explaining the node name.

	Arnd
--
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 7/7] can: m_can: workaround for transmit data less than 4 bytes
From: Dong Aisheng @ 2014-11-04  9:27 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: linux-can, wg, varkabhadram, netdev, socketcan, linux-arm-kernel
In-Reply-To: <54589AC8.4010106@pengutronix.de>

On Tue, Nov 04, 2014 at 10:22:16AM +0100, Marc Kleine-Budde wrote:
> On 11/04/2014 09:25 AM, Dong Aisheng wrote:
> >>> We meet an IC issue that we have to write the full 8 bytes (whatever
> >>> value for the second word) in Message RAM to avoid bit error for transmit
> >>> data less than 4 bytes.
> >>
> >> Is this a SoC or a m_can problem? Are all versions of the SoC/m_can
> >> affected? Is there a m_can version register somewhere?
> 
> > I'm still not sure it's SoC or m_can problem.
> > Our IC guys ran the simulation code and found this issue.
> > But due to some reasons, it may be very slow for they to investigate
> > and get the conclusion.
> 
> Let's hope they will find the root cause of this problem.
> 
> >>> Without the workaround, we can easily see the following errors:
> >>> root@imx6qdlsolo:~# ip link set can0 up type can bitrate 1000000
> >>> [   66.882520] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
> >>> root@imx6qdlsolo:~# cansend can0 123#112233
> >>> [   66.935640] m_can 20e8000.can can0: Bit Error Uncorrected
> >>>
> >>> Signed-off-by: Dong Aisheng <b29396@freescale.com>
> >>> ---
> >>>  drivers/net/can/m_can/m_can.c | 11 ++++++++++-
> >>>  1 file changed, 10 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
> >>> index 219e0e3..f2d9ebe 100644
> >>> --- a/drivers/net/can/m_can/m_can.c
> >>> +++ b/drivers/net/can/m_can/m_can.c
> >>> @@ -1058,10 +1058,19 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb,
> >>>  	m_can_fifo_write(priv, 0, M_CAN_FIFO_ID, id);
> >>>  	m_can_fifo_write(priv, 0, M_CAN_FIFO_DLC, can_len2dlc(cf->len) << 16);
> >>>  
> >>> -	for (i = 0; i < cf->len; i += 4)
> >>> +	for (i = 0; i < cf->len; i += 4) {
> >>>  		m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(i / 4),
> >>>  				 *(u32 *)(cf->data + i));
> >>>  
> >>> +		/* FIXME: we meet an IC issue that we have to write the full 8
> >>
> >> FIXME usually indicates that the driver needs some work here. Just
> >> describe your hardware bug, you might add a reference to an errata if
> >> available, though.
> >
> > We don't have an errata for it now.
> > Because i'm not sure this is the final workaround and also not sure if other
> > SoC vendors having the same issue, so i used FIXME here firstly.
> > Since the code is harmless, so i wish we could put it here first
> > until we find evidence no need for other SoC or only belong to specific
> > IP version.
> 
> It's better to write this in the comment than a FIXME, which is much
> harder to interpret....
> 
> >>> +		 * bytes (whatever value for the second word) in Message RAM to
> >>> +		 * avoid bit error for transmit data less than 4 bytes
> >>> +		 */
> >>> +		if (cf->len <= 4)
> >>> +			m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(i / 4 + 1),
> >>> +					 0x0);
> >>
> >> This workaround doesn't handle the dlc == 0 case, your error description
> >> isn't completely if this is a problem, too.
> 
> > You're right.
> > I just checked the dlc == 0 case also had such issue and it also needs
> > the extra 8 bytes write to avoid such issue.
> > 
> > BTW the issue only happened on the first time when you send a frame with no
> > data(dlc == 0) at the first time.
> > e.g.
> > root@imx6sxsabresd:~# ip link set can0 up type can bitrate 1000000
> > [   62.326014] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
> > root@imx6sxsabresd:~# cansend can0 123#R
> > [   69.233645] m_can 20e8000.can can0: Bit Error Uncorrected
> > [   69.239167] m_can 20e8000.can can0: Bit Error Corrected
> > 
> > If we send a frame success first (e.g. 5 bytes data), it will not fail
> > again even you send no data frame (dlc == 0) later.
> > 
> > The former failure of sending data less than 4 bytes is similar.
> > 
> > Looks like the first 8 bytes of message ram has to be initialised
> > for the first using.
> 
> What about putting
> 
> /* errata description goes here */
> m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(0), 0x0);
> m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(1), 0x0);
> 
> into the open() function? Can you ask the hardware colleges if this is a
> functional workaround.
> 
> >> It should be possible to change the for loop to go always to 8, or
> >> simply unroll the loop:
> >>
> >> /* errata description goes here */
> >> m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(0), *(u32 *)(cf->data + 0));
> >> m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(1), *(u32 *)(cf->data + 4));
> >>
> > 
> > Yes, i tried to fix it as follows.
> > 
> > /* FIXME: we meet an IC issue that we have to write the full 8
> >  * bytes (whatever value for the second word) in Message RAM to
> >  * avoid bit error for transmit data less than 4 bytes
> >  */
> > if (cf->len <= 4) {
> >         m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(0),
> >                          *(u32 *)(cf->data + 0));
> >         m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(1),
> >                          *(u32 *)(cf->data + 4));
> > } else {
> >         for (i = 0; i < cf->len; i += 4)
> >                 m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(i / 4),
> >                                  *(u32 *)(cf->data + i));
> > 
> > Will update the patch.
> 
> Both branches of the above if are doing the same thing, I think you can
> replace the while if ... else ... for with this:
> 

Not the same thing.
The later one will cover payload up to 64 bytes.

> /* errata description goes here */
> m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(0), *(u32 *)(cf->data + 0));
> m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(1), *(u32 *)(cf->data + 4));
> 
> However if writing to DATA(0) and DATA(1) once in the open() function is
> enough this code should stay as it is.

I tried put them into open() function and the quick test showed it worked.

Do you think it's ok to put things into open() function for this issue
as follows?

diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index 065e4f1..ca55988 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -901,6 +901,15 @@ static void m_can_chip_config(struct net_device *dev)
        /* set bittiming params */
        m_can_set_bittiming(dev);

+       /* We meet an IC issue that we have to write the full 8
+        * bytes (whatever value for the second word) in Message RAM to
+        * avoid bit error for transmit data less than 4 bytes at the first
+        * time. By initializing the first 8 bytes of tx buffer before using
+        * it can avoid such issue.
+        */
+       m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(0), 0x0);
+       m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(1), 0x0);
+
        m_can_config_endisable(priv, false);
 }

Regards
Dong Aisheng

> 
> Marc
> -- 
> Pengutronix e.K.                  | Marc Kleine-Budde           |
> Industrial Linux Solutions        | Phone: +49-231-2826-924     |
> Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |
> 



^ permalink raw reply related

* Re: [PATCH net-next 1/7] bpf: add 'flags' attribute to BPF_MAP_UPDATE_ELEM command
From: Daniel Borkmann @ 2014-11-04  9:25 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: David S. Miller, Ingo Molnar, Andy Lutomirski,
	Hannes Frederic Sowa, Eric Dumazet, linux-api, netdev,
	linux-kernel
In-Reply-To: <1415069656-14138-2-git-send-email-ast@plumgrid.com>

On 11/04/2014 03:54 AM, Alexei Starovoitov wrote:
> the current meaning of BPF_MAP_UPDATE_ELEM syscall command is:
> either update existing map element or create a new one.
> Initially the plan was to add a new command to handle the case of
> 'create new element if it didn't exist', but 'flags' style looks
> cleaner and overall diff is much smaller (more code reused), so add 'flags'
> attribute to BPF_MAP_UPDATE_ELEM command with the following meaning:
> enum {
>    BPF_MAP_UPDATE_OR_CREATE = 0, /* add new element or update existing */
>    BPF_MAP_CREATE_ONLY,          /* add new element if it didn't exist */
>    BPF_MAP_UPDATE_ONLY           /* update existing element */
> };

 From you commit message/code I currently don't see an explanation why
it cannot be done in typical ``flags style'' as various syscalls do,
i.e. BPF_MAP_UPDATE_OR_CREATE rather represented as ...

   BPF_MAP_CREATE | BPF_MAP_UPDATE

Do you expect more than 64 different flags to be passed from user space
for BPF_MAP?

> BPF_MAP_CREATE_ONLY can fail with EEXIST if element already exists.
> BPF_MAP_UPDATE_ONLY can fail with ENOENT if element doesn't exist.
>
> Userspace will call it as:
> int bpf_update_elem(int fd, void *key, void *value, __u64 flags)
> {
>      union bpf_attr attr = {
>          .map_fd = fd,
>          .key = ptr_to_u64(key),
>          .value = ptr_to_u64(value),
>          .flags = flags;
>      };
>
>      return bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
> }
>
> Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>

^ permalink raw reply

* Re: [PATCH 7/7] can: m_can: workaround for transmit data less than 4 bytes
From: Marc Kleine-Budde @ 2014-11-04  9:22 UTC (permalink / raw)
  To: Dong Aisheng
  Cc: linux-can, wg, varkabhadram, netdev, socketcan, linux-arm-kernel
In-Reply-To: <20141104082505.GA8060@shlinux1.ap.freescale.net>

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

On 11/04/2014 09:25 AM, Dong Aisheng wrote:
>>> We meet an IC issue that we have to write the full 8 bytes (whatever
>>> value for the second word) in Message RAM to avoid bit error for transmit
>>> data less than 4 bytes.
>>
>> Is this a SoC or a m_can problem? Are all versions of the SoC/m_can
>> affected? Is there a m_can version register somewhere?

> I'm still not sure it's SoC or m_can problem.
> Our IC guys ran the simulation code and found this issue.
> But due to some reasons, it may be very slow for they to investigate
> and get the conclusion.

Let's hope they will find the root cause of this problem.

>>> Without the workaround, we can easily see the following errors:
>>> root@imx6qdlsolo:~# ip link set can0 up type can bitrate 1000000
>>> [   66.882520] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
>>> root@imx6qdlsolo:~# cansend can0 123#112233
>>> [   66.935640] m_can 20e8000.can can0: Bit Error Uncorrected
>>>
>>> Signed-off-by: Dong Aisheng <b29396@freescale.com>
>>> ---
>>>  drivers/net/can/m_can/m_can.c | 11 ++++++++++-
>>>  1 file changed, 10 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
>>> index 219e0e3..f2d9ebe 100644
>>> --- a/drivers/net/can/m_can/m_can.c
>>> +++ b/drivers/net/can/m_can/m_can.c
>>> @@ -1058,10 +1058,19 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb,
>>>  	m_can_fifo_write(priv, 0, M_CAN_FIFO_ID, id);
>>>  	m_can_fifo_write(priv, 0, M_CAN_FIFO_DLC, can_len2dlc(cf->len) << 16);
>>>  
>>> -	for (i = 0; i < cf->len; i += 4)
>>> +	for (i = 0; i < cf->len; i += 4) {
>>>  		m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(i / 4),
>>>  				 *(u32 *)(cf->data + i));
>>>  
>>> +		/* FIXME: we meet an IC issue that we have to write the full 8
>>
>> FIXME usually indicates that the driver needs some work here. Just
>> describe your hardware bug, you might add a reference to an errata if
>> available, though.
>
> We don't have an errata for it now.
> Because i'm not sure this is the final workaround and also not sure if other
> SoC vendors having the same issue, so i used FIXME here firstly.
> Since the code is harmless, so i wish we could put it here first
> until we find evidence no need for other SoC or only belong to specific
> IP version.

It's better to write this in the comment than a FIXME, which is much
harder to interpret....

>>> +		 * bytes (whatever value for the second word) in Message RAM to
>>> +		 * avoid bit error for transmit data less than 4 bytes
>>> +		 */
>>> +		if (cf->len <= 4)
>>> +			m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(i / 4 + 1),
>>> +					 0x0);
>>
>> This workaround doesn't handle the dlc == 0 case, your error description
>> isn't completely if this is a problem, too.

> You're right.
> I just checked the dlc == 0 case also had such issue and it also needs
> the extra 8 bytes write to avoid such issue.
> 
> BTW the issue only happened on the first time when you send a frame with no
> data(dlc == 0) at the first time.
> e.g.
> root@imx6sxsabresd:~# ip link set can0 up type can bitrate 1000000
> [   62.326014] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
> root@imx6sxsabresd:~# cansend can0 123#R
> [   69.233645] m_can 20e8000.can can0: Bit Error Uncorrected
> [   69.239167] m_can 20e8000.can can0: Bit Error Corrected
> 
> If we send a frame success first (e.g. 5 bytes data), it will not fail
> again even you send no data frame (dlc == 0) later.
> 
> The former failure of sending data less than 4 bytes is similar.
> 
> Looks like the first 8 bytes of message ram has to be initialised
> for the first using.

What about putting

/* errata description goes here */
m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(0), 0x0);
m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(1), 0x0);

into the open() function? Can you ask the hardware colleges if this is a
functional workaround.

>> It should be possible to change the for loop to go always to 8, or
>> simply unroll the loop:
>>
>> /* errata description goes here */
>> m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(0), *(u32 *)(cf->data + 0));
>> m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(1), *(u32 *)(cf->data + 4));
>>
> 
> Yes, i tried to fix it as follows.
> 
> /* FIXME: we meet an IC issue that we have to write the full 8
>  * bytes (whatever value for the second word) in Message RAM to
>  * avoid bit error for transmit data less than 4 bytes
>  */
> if (cf->len <= 4) {
>         m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(0),
>                          *(u32 *)(cf->data + 0));
>         m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(1),
>                          *(u32 *)(cf->data + 4));
> } else {
>         for (i = 0; i < cf->len; i += 4)
>                 m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(i / 4),
>                                  *(u32 *)(cf->data + i));
> 
> Will update the patch.

Both branches of the above if are doing the same thing, I think you can
replace the while if ... else ... for with this:

/* errata description goes here */
m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(0), *(u32 *)(cf->data + 0));
m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(1), *(u32 *)(cf->data + 4));

However if writing to DATA(0) and DATA(1) once in the open() function is
enough this code should stay as it is.

Marc
-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply

* Re: [PATCH v2 5/5] stmmac: pci: remove FSF address
From: Andy Shevchenko @ 2014-11-04  9:06 UTC (permalink / raw)
  To: David Miller
  Cc: peppe.cavallaro, netdev, hock.leong.kweh, vbridgers2013, rayagond
In-Reply-To: <20141103.155708.1102581898193715225.davem@davemloft.net>

On Mon, 2014-11-03 at 15:57 -0500, David Miller wrote:
> From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Date: Mon,  3 Nov 2014 15:02:17 +0200
> 
> > The FSF address is subject to change, thus remove it from the file.
> > 
> > Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> 
> I cound 90t instances of this under drivers/net, therefore if this change is
> appropriate 

Can't find fast the discussion, but there is the commit
4783f894d0f3bfb107cf3b1d9aed1f1a0672ee1d "checkpatch.pl: check for the
FSF mailing address".


> I'd rather someone script this and kill it across entire
> subdirectories.

I'm okay if you don't apply this patch now.


-- 
Andy Shevchenko <andriy.shevchenko@intel.com>
Intel Finland Oy

^ permalink raw reply

* Re: [PATCH 2/4] tun: Use iovec iterators
From: Herbert Xu @ 2014-11-04  8:37 UTC (permalink / raw)
  To: Al Viro, David S. Miller, netdev, Linux Kernel Mailing List,
	Benjamin LaHaise
In-Reply-To: <E1XlZWY-0003Hk-Qu@gondolin.me.apana.org.au>

Oops, this patch had a left-over skb_pull which made it broken.
Here is a fixed version.

tun: Use iovec iterators

This patch removes the use of skb_copy_datagram_const_iovec in
favour of the iovec iterator-based skb_copy_datagram_iter.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 9dd3746..ff955cdb 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -71,6 +71,7 @@
 #include <net/rtnetlink.h>
 #include <net/sock.h>
 #include <linux/seq_file.h>
+#include <linux/uio.h>
 
 #include <asm/uaccess.h>
 
@@ -1230,11 +1231,11 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
 static ssize_t tun_put_user(struct tun_struct *tun,
 			    struct tun_file *tfile,
 			    struct sk_buff *skb,
-			    const struct iovec *iv, int len)
+			    struct iov_iter *iter)
 {
 	struct tun_pi pi = { 0, skb->protocol };
-	ssize_t total = 0;
-	int vlan_offset = 0, copied;
+	ssize_t total;
+	int vlan_offset;
 	int vlan_hlen = 0;
 	int vnet_hdr_sz = 0;
 
@@ -1244,23 +1245,25 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 	if (tun->flags & TUN_VNET_HDR)
 		vnet_hdr_sz = tun->vnet_hdr_sz;
 
+	total = skb->len + vlan_hlen + vnet_hdr_sz;
+
 	if (!(tun->flags & TUN_NO_PI)) {
-		if ((len -= sizeof(pi)) < 0)
+		if (iov_iter_count(iter) < sizeof(pi))
 			return -EINVAL;
 
-		if (len < skb->len + vlan_hlen + vnet_hdr_sz) {
+		if (iov_iter_count(iter) < total) {
 			/* Packet will be striped */
 			pi.flags |= TUN_PKT_STRIP;
 		}
 
-		if (memcpy_toiovecend(iv, (void *) &pi, 0, sizeof(pi)))
+		if (copy_to_iter(&pi, sizeof(pi), iter))
 			return -EFAULT;
 		total += sizeof(pi);
 	}
 
 	if (vnet_hdr_sz) {
 		struct virtio_net_hdr gso = { 0 }; /* no info leak */
-		if ((len -= vnet_hdr_sz) < 0)
+		if (iov_iter_count(iter) < vnet_hdr_sz)
 			return -EINVAL;
 
 		if (skb_is_gso(skb)) {
@@ -1299,17 +1302,12 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 			gso.flags = VIRTIO_NET_HDR_F_DATA_VALID;
 		} /* else everything is zero */
 
-		if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total,
-					       sizeof(gso))))
+		if (copy_to_iter(&gso, sizeof(gso), iter))
 			return -EFAULT;
-		total += vnet_hdr_sz;
 	}
 
-	copied = total;
-	len = min_t(int, skb->len + vlan_hlen, len);
-	total += skb->len + vlan_hlen;
 	if (vlan_hlen) {
-		int copy, ret;
+		int ret;
 		struct {
 			__be16 h_vlan_proto;
 			__be16 h_vlan_TCI;
@@ -1320,36 +1318,32 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 
 		vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto);
 
-		copy = min_t(int, vlan_offset, len);
-		ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy);
-		len -= copy;
-		copied += copy;
-		if (ret || !len)
+		ret = skb_copy_datagram_iter(skb, 0, iter, vlan_offset);
+		if (ret || !iov_iter_count(iter))
 			goto done;
 
-		copy = min_t(int, sizeof(veth), len);
-		ret = memcpy_toiovecend(iv, (void *)&veth, copied, copy);
-		len -= copy;
-		copied += copy;
-		if (ret || !len)
+		ret = copy_to_iter(&veth, sizeof(veth), iter);
+		if (ret || !iov_iter_count(iter))
 			goto done;
 	}
 
-	skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len);
+	skb_copy_datagram_iter(skb, vlan_offset, iter, skb->len - vlan_offset);
 
 done:
 	tun->dev->stats.tx_packets++;
-	tun->dev->stats.tx_bytes += len;
+	tun->dev->stats.tx_bytes += skb->len + vlan_hlen;
 
 	return total;
 }
 
 static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile,
-			   const struct iovec *iv, ssize_t len, int noblock)
+			   const struct iovec *iv, unsigned long segs,
+			   ssize_t len, int noblock)
 {
 	struct sk_buff *skb;
 	ssize_t ret = 0;
 	int peeked, err, off = 0;
+	struct iov_iter iter;
 
 	tun_debug(KERN_INFO, tun, "tun_do_read\n");
 
@@ -1362,11 +1356,12 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile,
 	/* Read frames from queue */
 	skb = __skb_recv_datagram(tfile->socket.sk, noblock ? MSG_DONTWAIT : 0,
 				  &peeked, &off, &err);
-	if (skb) {
-		ret = tun_put_user(tun, tfile, skb, iv, len);
-		kfree_skb(skb);
-	} else
-		ret = err;
+	if (!skb)
+		return ret;
+
+	iov_iter_init(&iter, READ, iv, segs, len);
+	ret = tun_put_user(tun, tfile, skb, &iter);
+	kfree_skb(skb);
 
 	return ret;
 }
@@ -1387,7 +1382,7 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
 		goto out;
 	}
 
-	ret = tun_do_read(tun, tfile, iv, len,
+	ret = tun_do_read(tun, tfile, iv, count, len,
 			  file->f_flags & O_NONBLOCK);
 	ret = min_t(ssize_t, ret, len);
 	if (ret > 0)
@@ -1488,7 +1483,7 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock,
 					 SOL_PACKET, TUN_TX_TIMESTAMP);
 		goto out;
 	}
-	ret = tun_do_read(tun, tfile, m->msg_iov, total_len,
+	ret = tun_do_read(tun, tfile, m->msg_iov, m->msg_iovlen, total_len,
 			  flags & MSG_DONTWAIT);
 	if (ret > total_len) {
 		m->msg_flags |= MSG_TRUNC;

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply related

* [PATCH 3/4] macvtap: Use iovec iterators
From: Herbert Xu @ 2014-11-04  8:31 UTC (permalink / raw)
  To: Al Viro, David S. Miller, netdev, Linux Kernel Mailing List,
	Benjamin LaHaise
In-Reply-To: <20141104033818.GA11149@gondor.apana.org.au>

This patch removes the use of skb_copy_datagram_const_iovec in
favour of the iovec iterator-based skb_copy_datagram_iter.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 drivers/net/macvtap.c |   45 ++++++++++++++++++++-------------------------
 1 file changed, 20 insertions(+), 25 deletions(-)

diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 880cc09..a0e1dd7 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -15,6 +15,7 @@
 #include <linux/cdev.h>
 #include <linux/idr.h>
 #include <linux/fs.h>
+#include <linux/uio.h>
 
 #include <net/ipv6.h>
 #include <net/net_namespace.h>
@@ -778,31 +779,28 @@ static ssize_t macvtap_aio_write(struct kiocb *iocb, const struct iovec *iv,
 /* Put packet to the user space buffer */
 static ssize_t macvtap_put_user(struct macvtap_queue *q,
 				const struct sk_buff *skb,
-				const struct iovec *iv, int len)
+				struct iov_iter *iter)
 {
 	int ret;
 	int vnet_hdr_len = 0;
 	int vlan_offset = 0;
-	int copied, total;
+	int total;
 
 	if (q->flags & IFF_VNET_HDR) {
 		struct virtio_net_hdr vnet_hdr;
 		vnet_hdr_len = q->vnet_hdr_sz;
-		if ((len -= vnet_hdr_len) < 0)
+		if (iov_iter_count(iter) < vnet_hdr_len)
 			return -EINVAL;
 
 		macvtap_skb_to_vnet_hdr(skb, &vnet_hdr);
 
-		if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, sizeof(vnet_hdr)))
+		if (copy_to_iter(&vnet_hdr, sizeof(vnet_hdr), iter))
 			return -EFAULT;
 	}
-	total = copied = vnet_hdr_len;
+	total = vnet_hdr_len;
 	total += skb->len;
 
-	if (!vlan_tx_tag_present(skb))
-		len = min_t(int, skb->len, len);
-	else {
-		int copy;
+	if (vlan_tx_tag_present(skb)) {
 		struct {
 			__be16 h_vlan_proto;
 			__be16 h_vlan_TCI;
@@ -811,37 +809,33 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
 		veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb));
 
 		vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto);
-		len = min_t(int, skb->len + VLAN_HLEN, len);
 		total += VLAN_HLEN;
 
-		copy = min_t(int, vlan_offset, len);
-		ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy);
-		len -= copy;
-		copied += copy;
-		if (ret || !len)
+		ret = skb_copy_datagram_iter(skb, 0, iter, vlan_offset);
+		if (ret || !iov_iter_count(iter))
 			goto done;
 
-		copy = min_t(int, sizeof(veth), len);
-		ret = memcpy_toiovecend(iv, (void *)&veth, copied, copy);
-		len -= copy;
-		copied += copy;
-		if (ret || !len)
+		ret = copy_to_iter(&veth, sizeof(veth), iter);
+		if (ret || !iov_iter_count(iter))
 			goto done;
 	}
 
-	ret = skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len);
+	ret = skb_copy_datagram_iter(skb, vlan_offset, iter,
+				     skb->len - vlan_offset);
 
 done:
 	return ret ? ret : total;
 }
 
 static ssize_t macvtap_do_read(struct macvtap_queue *q,
-			       const struct iovec *iv, unsigned long len,
+			       const struct iovec *iv, unsigned long segs,
+			       unsigned long len,
 			       int noblock)
 {
 	DEFINE_WAIT(wait);
 	struct sk_buff *skb;
 	ssize_t ret = 0;
+	struct iov_iter iter;
 
 	while (len) {
 		if (!noblock)
@@ -863,7 +857,8 @@ static ssize_t macvtap_do_read(struct macvtap_queue *q,
 			schedule();
 			continue;
 		}
-		ret = macvtap_put_user(q, skb, iv, len);
+		iov_iter_init(&iter, READ, iv, segs, len);
+		ret = macvtap_put_user(q, skb, &iter);
 		kfree_skb(skb);
 		break;
 	}
@@ -886,7 +881,7 @@ static ssize_t macvtap_aio_read(struct kiocb *iocb, const struct iovec *iv,
 		goto out;
 	}
 
-	ret = macvtap_do_read(q, iv, len, file->f_flags & O_NONBLOCK);
+	ret = macvtap_do_read(q, iv, count, len, file->f_flags & O_NONBLOCK);
 	ret = min_t(ssize_t, ret, len);
 	if (ret > 0)
 		iocb->ki_pos = ret;
@@ -1117,7 +1112,7 @@ static int macvtap_recvmsg(struct kiocb *iocb, struct socket *sock,
 	int ret;
 	if (flags & ~(MSG_DONTWAIT|MSG_TRUNC))
 		return -EINVAL;
-	ret = macvtap_do_read(q, m->msg_iov, total_len,
+	ret = macvtap_do_read(q, m->msg_iov, m->msg_iovlen, total_len,
 			  flags & MSG_DONTWAIT);
 	if (ret > total_len) {
 		m->msg_flags |= MSG_TRUNC;

^ permalink raw reply related

* [PATCH 4/4] net: Kill skb_copy_datagram_const_iovec
From: Herbert Xu @ 2014-11-04  8:31 UTC (permalink / raw)
  To: Al Viro, David S. Miller, netdev, Linux Kernel Mailing List,
	Benjamin LaHaise
In-Reply-To: <20141104033818.GA11149@gondor.apana.org.au>

Now that both macvtap and tun are using skb_copy_datagram_iter, we
can kill the abomination that is skb_copy_datagram_const_iovec.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/linux/skbuff.h |    3 -
 net/core/datagram.c    |   89 -------------------------------------------------
 2 files changed, 92 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 5ff7054..dfd8623 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2639,9 +2639,6 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
 				 int len);
 int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *frm,
 			   int offset, size_t count);
-int skb_copy_datagram_const_iovec(const struct sk_buff *from, int offset,
-				  const struct iovec *to, int to_offset,
-				  int size);
 int skb_copy_datagram_iter(const struct sk_buff *from, int offset,
 			   struct iov_iter *to, int size);
 void skb_free_datagram(struct sock *sk, struct sk_buff *skb);
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 45a9d4d..93054b9 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -394,95 +394,6 @@ fault:
 EXPORT_SYMBOL(skb_copy_datagram_iovec);
 
 /**
- *	skb_copy_datagram_const_iovec - Copy a datagram to an iovec.
- *	@skb: buffer to copy
- *	@offset: offset in the buffer to start copying from
- *	@to: io vector to copy to
- *	@to_offset: offset in the io vector to start copying to
- *	@len: amount of data to copy from buffer to iovec
- *
- *	Returns 0 or -EFAULT.
- *	Note: the iovec is not modified during the copy.
- */
-int skb_copy_datagram_const_iovec(const struct sk_buff *skb, int offset,
-				  const struct iovec *to, int to_offset,
-				  int len)
-{
-	int start = skb_headlen(skb);
-	int i, copy = start - offset;
-	struct sk_buff *frag_iter;
-
-	/* Copy header. */
-	if (copy > 0) {
-		if (copy > len)
-			copy = len;
-		if (memcpy_toiovecend(to, skb->data + offset, to_offset, copy))
-			goto fault;
-		if ((len -= copy) == 0)
-			return 0;
-		offset += copy;
-		to_offset += copy;
-	}
-
-	/* Copy paged appendix. Hmm... why does this look so complicated? */
-	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-		int end;
-		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-
-		WARN_ON(start > offset + len);
-
-		end = start + skb_frag_size(frag);
-		if ((copy = end - offset) > 0) {
-			int err;
-			u8  *vaddr;
-			struct page *page = skb_frag_page(frag);
-
-			if (copy > len)
-				copy = len;
-			vaddr = kmap(page);
-			err = memcpy_toiovecend(to, vaddr + frag->page_offset +
-						offset - start, to_offset, copy);
-			kunmap(page);
-			if (err)
-				goto fault;
-			if (!(len -= copy))
-				return 0;
-			offset += copy;
-			to_offset += copy;
-		}
-		start = end;
-	}
-
-	skb_walk_frags(skb, frag_iter) {
-		int end;
-
-		WARN_ON(start > offset + len);
-
-		end = start + frag_iter->len;
-		if ((copy = end - offset) > 0) {
-			if (copy > len)
-				copy = len;
-			if (skb_copy_datagram_const_iovec(frag_iter,
-							  offset - start,
-							  to, to_offset,
-							  copy))
-				goto fault;
-			if ((len -= copy) == 0)
-				return 0;
-			offset += copy;
-			to_offset += copy;
-		}
-		start = end;
-	}
-	if (!len)
-		return 0;
-
-fault:
-	return -EFAULT;
-}
-EXPORT_SYMBOL(skb_copy_datagram_const_iovec);
-
-/**
  *	skb_copy_datagram_iter - Copy a datagram to an iovec iterator.
  *	@skb: buffer to copy
  *	@offset: offset in the buffer to start copying from

^ permalink raw reply related

* [PATCH 2/4] tun: Use iovec iterators
From: Herbert Xu @ 2014-11-04  8:31 UTC (permalink / raw)
  To: Al Viro, David S. Miller, netdev, Linux Kernel Mailing List,
	Benjamin LaHaise
In-Reply-To: <20141104033818.GA11149@gondor.apana.org.au>

This patch removes the use of skb_copy_datagram_const_iovec in
favour of the iovec iterator-based skb_copy_datagram_iter.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 drivers/net/tun.c |   65 +++++++++++++++++++++++++-----------------------------
 1 file changed, 31 insertions(+), 34 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 9dd3746..cfb81ca 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -71,6 +71,7 @@
 #include <net/rtnetlink.h>
 #include <net/sock.h>
 #include <linux/seq_file.h>
+#include <linux/uio.h>
 
 #include <asm/uaccess.h>
 
@@ -1230,11 +1231,11 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
 static ssize_t tun_put_user(struct tun_struct *tun,
 			    struct tun_file *tfile,
 			    struct sk_buff *skb,
-			    const struct iovec *iv, int len)
+			    struct iov_iter *iter)
 {
 	struct tun_pi pi = { 0, skb->protocol };
-	ssize_t total = 0;
-	int vlan_offset = 0, copied;
+	ssize_t total;
+	int vlan_offset;
 	int vlan_hlen = 0;
 	int vnet_hdr_sz = 0;
 
@@ -1244,23 +1245,25 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 	if (tun->flags & TUN_VNET_HDR)
 		vnet_hdr_sz = tun->vnet_hdr_sz;
 
+	total = skb->len + vlan_hlen + vnet_hdr_sz;
+
 	if (!(tun->flags & TUN_NO_PI)) {
-		if ((len -= sizeof(pi)) < 0)
+		if (iov_iter_count(iter) < sizeof(pi))
 			return -EINVAL;
 
-		if (len < skb->len + vlan_hlen + vnet_hdr_sz) {
+		if (iov_iter_count(iter) < total) {
 			/* Packet will be striped */
 			pi.flags |= TUN_PKT_STRIP;
 		}
 
-		if (memcpy_toiovecend(iv, (void *) &pi, 0, sizeof(pi)))
+		if (copy_to_iter(&pi, sizeof(pi), iter))
 			return -EFAULT;
 		total += sizeof(pi);
 	}
 
 	if (vnet_hdr_sz) {
 		struct virtio_net_hdr gso = { 0 }; /* no info leak */
-		if ((len -= vnet_hdr_sz) < 0)
+		if (iov_iter_count(iter) < vnet_hdr_sz)
 			return -EINVAL;
 
 		if (skb_is_gso(skb)) {
@@ -1299,17 +1302,12 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 			gso.flags = VIRTIO_NET_HDR_F_DATA_VALID;
 		} /* else everything is zero */
 
-		if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total,
-					       sizeof(gso))))
+		if (copy_to_iter(&gso, sizeof(gso), iter))
 			return -EFAULT;
-		total += vnet_hdr_sz;
 	}
 
-	copied = total;
-	len = min_t(int, skb->len + vlan_hlen, len);
-	total += skb->len + vlan_hlen;
 	if (vlan_hlen) {
-		int copy, ret;
+		int ret;
 		struct {
 			__be16 h_vlan_proto;
 			__be16 h_vlan_TCI;
@@ -1320,36 +1318,34 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 
 		vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto);
 
-		copy = min_t(int, vlan_offset, len);
-		ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy);
-		len -= copy;
-		copied += copy;
-		if (ret || !len)
+		ret = skb_copy_datagram_iter(skb, 0, iter, vlan_offset);
+		if (ret || !iov_iter_count(iter))
 			goto done;
 
-		copy = min_t(int, sizeof(veth), len);
-		ret = memcpy_toiovecend(iv, (void *)&veth, copied, copy);
-		len -= copy;
-		copied += copy;
-		if (ret || !len)
+		ret = copy_to_iter(&veth, sizeof(veth), iter);
+		if (ret || !iov_iter_count(iter))
 			goto done;
+
+		__skb_pull(skb, vlan_offset);
 	}
 
-	skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len);
+	skb_copy_datagram_iter(skb, vlan_offset, iter, skb->len - vlan_offset);
 
 done:
 	tun->dev->stats.tx_packets++;
-	tun->dev->stats.tx_bytes += len;
+	tun->dev->stats.tx_bytes += skb->len + vlan_hlen;
 
 	return total;
 }
 
 static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile,
-			   const struct iovec *iv, ssize_t len, int noblock)
+			   const struct iovec *iv, unsigned long segs,
+			   ssize_t len, int noblock)
 {
 	struct sk_buff *skb;
 	ssize_t ret = 0;
 	int peeked, err, off = 0;
+	struct iov_iter iter;
 
 	tun_debug(KERN_INFO, tun, "tun_do_read\n");
 
@@ -1362,11 +1358,12 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile,
 	/* Read frames from queue */
 	skb = __skb_recv_datagram(tfile->socket.sk, noblock ? MSG_DONTWAIT : 0,
 				  &peeked, &off, &err);
-	if (skb) {
-		ret = tun_put_user(tun, tfile, skb, iv, len);
-		kfree_skb(skb);
-	} else
-		ret = err;
+	if (!skb)
+		return ret;
+
+	iov_iter_init(&iter, READ, iv, segs, len);
+	ret = tun_put_user(tun, tfile, skb, &iter);
+	kfree_skb(skb);
 
 	return ret;
 }
@@ -1387,7 +1384,7 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
 		goto out;
 	}
 
-	ret = tun_do_read(tun, tfile, iv, len,
+	ret = tun_do_read(tun, tfile, iv, count, len,
 			  file->f_flags & O_NONBLOCK);
 	ret = min_t(ssize_t, ret, len);
 	if (ret > 0)
@@ -1488,7 +1485,7 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock,
 					 SOL_PACKET, TUN_TX_TIMESTAMP);
 		goto out;
 	}
-	ret = tun_do_read(tun, tfile, m->msg_iov, total_len,
+	ret = tun_do_read(tun, tfile, m->msg_iov, m->msg_iovlen, total_len,
 			  flags & MSG_DONTWAIT);
 	if (ret > total_len) {
 		m->msg_flags |= MSG_TRUNC;

^ permalink raw reply related

* [PATCH 1/4] inet: Add skb_copy_datagram_iter
From: Herbert Xu @ 2014-11-04  8:31 UTC (permalink / raw)
  To: Al Viro, David S. Miller, netdev, Linux Kernel Mailing List,
	Benjamin LaHaise
In-Reply-To: <20141104033818.GA11149@gondor.apana.org.au>

This patch adds skb_copy_datagram_iter, which is identical to
skb_copy_datagram_iovec except that it operates on iov_iter
instead of iovec.

Eventually all users of skb_copy_datagram_iovec should switch
over to iov_iter and then we can remove skb_copy_datagram_iovec.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/linux/skbuff.h |    3 +
 net/core/datagram.c    |   82 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 85 insertions(+)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 6c8b6f6..5ff7054 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -148,6 +148,7 @@
 struct net_device;
 struct scatterlist;
 struct pipe_inode_info;
+struct iov_iter;
 
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
 struct nf_conntrack {
@@ -2641,6 +2642,8 @@ int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *frm,
 int skb_copy_datagram_const_iovec(const struct sk_buff *from, int offset,
 				  const struct iovec *to, int to_offset,
 				  int size);
+int skb_copy_datagram_iter(const struct sk_buff *from, int offset,
+			   struct iov_iter *to, int size);
 void skb_free_datagram(struct sock *sk, struct sk_buff *skb);
 void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb);
 int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags);
diff --git a/net/core/datagram.c b/net/core/datagram.c
index fdbc9a8..45a9d4d 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -49,6 +49,7 @@
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/pagemap.h>
+#include <linux/uio.h>
 
 #include <net/protocol.h>
 #include <linux/skbuff.h>
@@ -482,6 +483,87 @@ fault:
 EXPORT_SYMBOL(skb_copy_datagram_const_iovec);
 
 /**
+ *	skb_copy_datagram_iter - Copy a datagram to an iovec iterator.
+ *	@skb: buffer to copy
+ *	@offset: offset in the buffer to start copying from
+ *	@to: iovec iterator to copy to
+ *	@len: amount of data to copy from buffer to iovec
+ */
+int skb_copy_datagram_iter(const struct sk_buff *skb, int offset,
+			   struct iov_iter *to, int len)
+{
+	int start = skb_headlen(skb);
+	int i, copy = start - offset;
+	struct sk_buff *frag_iter;
+
+	trace_skb_copy_datagram_iovec(skb, len);
+
+	/* Copy header. */
+	if (copy > 0) {
+		if (copy > len)
+			copy = len;
+		if (copy_to_iter(skb->data + offset, copy, to))
+			goto fault;
+		if ((len -= copy) == 0)
+			return 0;
+		offset += copy;
+	}
+
+	/* Copy paged appendix. Hmm... why does this look so complicated? */
+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+		int end;
+		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+		WARN_ON(start > offset + len);
+
+		end = start + skb_frag_size(frag);
+		if ((copy = end - offset) > 0) {
+			int err;
+			u8  *vaddr;
+			struct page *page = skb_frag_page(frag);
+
+			if (copy > len)
+				copy = len;
+			vaddr = kmap(page);
+			err = copy_to_iter(vaddr + frag->page_offset +
+					   offset - start, copy, to);
+			kunmap(page);
+			if (err)
+				goto fault;
+			if (!(len -= copy))
+				return 0;
+			offset += copy;
+		}
+		start = end;
+	}
+
+	skb_walk_frags(skb, frag_iter) {
+		int end;
+
+		WARN_ON(start > offset + len);
+
+		end = start + frag_iter->len;
+		if ((copy = end - offset) > 0) {
+			if (copy > len)
+				copy = len;
+			if (skb_copy_datagram_iter(frag_iter, offset - start,
+						   to, copy))
+				goto fault;
+			if ((len -= copy) == 0)
+				return 0;
+			offset += copy;
+		}
+		start = end;
+	}
+	if (!len)
+		return 0;
+
+fault:
+	return -EFAULT;
+}
+EXPORT_SYMBOL(skb_copy_datagram_iter);
+
+/**
  *	skb_copy_datagram_from_iovec - Copy a datagram from an iovec.
  *	@skb: buffer to copy
  *	@offset: offset in the buffer to start copying to

^ permalink raw reply related

* Re: [PATCH 5/7] can: clear ctrlmode when close candev
From: Dong Aisheng @ 2014-11-04  8:27 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: linux-can, wg, varkabhadram, netdev, socketcan, linux-arm-kernel
In-Reply-To: <5457E9DA.6090702@pengutronix.de>

On Mon, Nov 03, 2014 at 09:47:22PM +0100, Marc Kleine-Budde wrote:
> On 10/29/2014 11:45 AM, Dong Aisheng wrote:
> > Currently priv->ctrlmode is not cleared when close_candev, so next time
> > the driver will still use this value to set controller even user
> > does not set any ctrl mode.
> > e.g.
> > Step 1. ip link set can0 up type can0 bitrate 1000000 loopback on
> > Controller will be in loopback mode
> > Step 2. ip link set can0 down
> > Step 3. ip link set can0 up type can0 bitrate 1000000
> > Controller will still be set to loopback mode in driver due to saved
> > priv->ctrlmode.
> > 
> > This patch clears priv->ctrlmode when the CAN interface is closed,
> > and set it to correct mode according to next user setting.
> > 
> > Signed-off-by: Dong Aisheng <b29396@freescale.com>
> 
> NACK, as discussed with Oliver.
> 

Okay, i'm fine with it.

Regards
Dong Aisheng

> Marc
> 
> -- 
> Pengutronix e.K.                  | Marc Kleine-Budde           |
> Industrial Linux Solutions        | Phone: +49-231-2826-924     |
> Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |
> 



^ permalink raw reply

* Re: [PATCH 7/7] can: m_can: workaround for transmit data less than 4 bytes
From: Dong Aisheng @ 2014-11-04  8:25 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: linux-can, wg, varkabhadram, netdev, socketcan, linux-arm-kernel
In-Reply-To: <5457B1D1.6080301@pengutronix.de>

On Mon, Nov 03, 2014 at 05:48:17PM +0100, Marc Kleine-Budde wrote:
> On 10/29/2014 11:45 AM, Dong Aisheng wrote:
> > We meet an IC issue that we have to write the full 8 bytes (whatever
> > value for the second word) in Message RAM to avoid bit error for transmit
> > data less than 4 bytes.
> 
> Is this a SoC or a m_can problem? Are all versions of the SoC/m_can
> affected? Is there a m_can version register somewhere?
> 

I'm still not sure it's SoC or m_can problem.
Our IC guys ran the simulation code and found this issue.
But due to some reasons, it may be very slow for they to investigate
and get the conclusion.

> > Without the workaround, we can easily see the following errors:
> > root@imx6qdlsolo:~# ip link set can0 up type can bitrate 1000000
> > [   66.882520] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
> > root@imx6qdlsolo:~# cansend can0 123#112233
> > [   66.935640] m_can 20e8000.can can0: Bit Error Uncorrected
> > 
> > Signed-off-by: Dong Aisheng <b29396@freescale.com>
> > ---
> >  drivers/net/can/m_can/m_can.c | 11 ++++++++++-
> >  1 file changed, 10 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
> > index 219e0e3..f2d9ebe 100644
> > --- a/drivers/net/can/m_can/m_can.c
> > +++ b/drivers/net/can/m_can/m_can.c
> > @@ -1058,10 +1058,19 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb,
> >  	m_can_fifo_write(priv, 0, M_CAN_FIFO_ID, id);
> >  	m_can_fifo_write(priv, 0, M_CAN_FIFO_DLC, can_len2dlc(cf->len) << 16);
> >  
> > -	for (i = 0; i < cf->len; i += 4)
> > +	for (i = 0; i < cf->len; i += 4) {
> >  		m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(i / 4),
> >  				 *(u32 *)(cf->data + i));
> >  
> > +		/* FIXME: we meet an IC issue that we have to write the full 8
> 
> FIXME usually indicates that the driver needs some work here. Just
> describe your hardware bug, you might add a reference to an errata if
> available, though.
> 

We don't have an errata for it now.
Because i'm not sure this is the final workaround and also not sure if other
SoC vendors having the same issue, so i used FIXME here firstly.
Since the code is harmless, so i wish we could put it here first
until we find evidence no need for other SoC or only belong to specific
IP version.

> > +		 * bytes (whatever value for the second word) in Message RAM to
> > +		 * avoid bit error for transmit data less than 4 bytes
> > +		 */
> > +		if (cf->len <= 4)
> > +			m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(i / 4 + 1),
> > +					 0x0);
> 
> This workaround doesn't handle the dlc == 0 case, your error description
> isn't completely if this is a problem, too.
> 

You're right.
I just checked the dlc == 0 case also had such issue and it also needs
the extra 8 bytes write to avoid such issue.

BTW the issue only happened on the first time when you send a frame with no
data(dlc == 0) at the first time.
e.g.
root@imx6sxsabresd:~# ip link set can0 up type can bitrate 1000000
[   62.326014] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
root@imx6sxsabresd:~# cansend can0 123#R
[   69.233645] m_can 20e8000.can can0: Bit Error Uncorrected
[   69.239167] m_can 20e8000.can can0: Bit Error Corrected

If we send a frame success first (e.g. 5 bytes data), it will not fail
again even you send no data frame (dlc == 0) later.

The former failure of sending data less than 4 bytes is similar.

Looks like the first 8 bytes of message ram has to be initialised
for the first using.

> It should be possible to change the for loop to go always to 8, or
> simply unroll the loop:
> 
> /* errata description goes here */
> m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(0), *(u32 *)(cf->data + 0));
> m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(1), *(u32 *)(cf->data + 4));
> 

Yes, i tried to fix it as follows.

/* FIXME: we meet an IC issue that we have to write the full 8
 * bytes (whatever value for the second word) in Message RAM to
 * avoid bit error for transmit data less than 4 bytes
 */
if (cf->len <= 4) {
        m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(0),
                         *(u32 *)(cf->data + 0));
        m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(1),
                         *(u32 *)(cf->data + 4));
} else {
        for (i = 0; i < cf->len; i += 4)
                m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(i / 4),
                                 *(u32 *)(cf->data + i));

Will update the patch.

Regards
Dong Aisheng

> > +	}
> > +
> >  	can_put_echo_skb(skb, dev, 0);
> >  
> >  	if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
> > 
> 
> Marc
> 
> -- 
> Pengutronix e.K.                  | Marc Kleine-Budde           |
> Industrial Linux Solutions        | Phone: +49-231-2826-924     |
> Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |
> 



^ permalink raw reply

* RE: "asix: Don't reset PHY on if_up for ASIX 88772" breaks net on arndale platform
From: Stam, Michel [FINT] @ 2014-11-04  8:19 UTC (permalink / raw)
  To: Riku Voipio, davem; +Cc: linux-usb, netdev, linux-kernel, linux-samsung-soc
In-Reply-To: <20141104072236.GA559@afflict.kos.to>

Hello Riku,

Interesting, as the commit itself is a revert from a kernel back to 2.6
somewhere. The problem I had is related to the PHY being reset on
interface-up, can you confirm that you require this? Reverting this
breaks ethtool support in turn.

Kind regards,

Michel Stam

-----Original Message-----
From: Riku Voipio [mailto:riku.voipio@iki.fi] 
Sent: Tuesday, November 04, 2014 8:23 AM
To: davem@davemloft.net; Stam, Michel [FINT]
Cc: linux-usb@vger.kernel.org; netdev@vger.kernel.org;
linux-kernel@vger.kernel.org; linux-samsung-soc@vger.kernel.org
Subject: "asix: Don't reset PHY on if_up for ASIX 88772" breaks net on
arndale platform

Hi,

With 3.18-rc3, asix on arndale (samsung exynos 5250 based board), fails
to work. Interface is initialized but network traffic seem not to pass
through. With kernel IP config the result looks like:

[    3.323275] usb 3-3.2.4: new high-speed USB device number 4 using
exynos-ehci
[    3.419151] usb 3-3.2.4: New USB device found, idVendor=0b95,
idProduct=772a
[    3.424735] usb 3-3.2.4: New USB device strings: Mfr=1, Product=2,
SerialNumber=3
[    3.432196] usb 3-3.2.4: Product: AX88772 
[    3.436279] usb 3-3.2.4: Manufacturer: ASIX Elec. Corp.
[    3.441486] usb 3-3.2.4: SerialNumber: 000001
[    3.447530] asix 3-3.2.4:1.0 (unnamed net_device) (uninitialized):
invalid hw address, using random
[    3.764352] asix 3-3.2.4:1.0 eth0: register 'asix' at
usb-12110000.usb-3.2.4, ASIX AX88772 USB 2.0 Ethernet, de:a2:66:bf:ca:4f
[    4.488773] asix 3-3.2.4:1.0 eth0: link down
[    5.690025] asix 3-3.2.4:1.0 eth0: link up, 100Mbps, full-duplex, lpa
0xC5E1
[    5.712947] Sending DHCP requests ...... timed out!
[   83.165303] IP-Config: Retrying forever (NFS root)...
[   83.170397] asix 3-3.2.4:1.0 eth0: link up, 100Mbps, full-duplex, lpa
0xC5E1
[   83.192944] Sending DHCP requests .....

Similar results also with dhclient. Git bisect identified the breaking
commit as:

commit 3cc81d85ee01e5a0b7ea2f4190e2ed1165f53c31
Author: Michel Stam <m.stam@fugro.nl>
Date:   Thu Oct 2 10:22:02 2014 +0200

    asix: Don't reset PHY on if_up for ASIX 88772

Taking 3.18-rc3 and that commit reverted, network works again:

[    3.303500] usb 3-3.2.4: new high-speed USB device number 4 using
exynos-ehci
[    3.399375] usb 3-3.2.4: New USB device found, idVendor=0b95,
idProduct=772a
[    3.404963] usb 3-3.2.4: New USB device strings: Mfr=1, Product=2,
SerialNumber=3
[    3.412424] usb 3-3.2.4: Product: AX88772 
[    3.416508] usb 3-3.2.4: Manufacturer: ASIX Elec. Corp.
[    3.421715] usb 3-3.2.4: SerialNumber: 000001
[    3.427755] asix 3-3.2.4:1.0 (unnamed net_device) (uninitialized):
invalid hw address, using random
[    3.744837] asix 3-3.2.4:1.0 eth0: register 'asix' at
usb-12110000.usb-3.2.4, ASIX AX88772 USB 2.0 Ethernet, 12:59:f1:a8:43:90
[    7.098998] asix 3-3.2.4:1.0 eth0: link up, 100Mbps, full-duplex, lpa
0xC5E1
[    7.118258] Sending DHCP requests ., OK
[    9.753259] IP-Config: Got DHCP answer from 192.168.1.1, my address
is 192.168.1.111

There might something wrong on the samsung platform code (I understand
the USB on arndale is "funny"), but this is still an regression from
3.17.

Riku

^ permalink raw reply

* Re: TCP NewReno and single retransmit
From: Yuchung Cheng @ 2014-11-04  7:59 UTC (permalink / raw)
  To: Neal Cardwell; +Cc: Marcelo Ricardo Leitner, netdev, Eric Dumazet
In-Reply-To: <CADVnQykePToQ-MatwFV=o7iYw_1T7L_jg_3NtaXRueyMA=GAuw@mail.gmail.com>

On Tue, Nov 4, 2014 at 7:17 AM, Neal Cardwell <ncardwell@google.com> wrote:
> On Mon, Nov 3, 2014 at 4:35 PM, Marcelo Ricardo Leitner
> <mleitner@redhat.com> wrote:
>> So by sticking with the recovery for a bit longer will help disambiguate the
>> 3 dupacks on high_seq, if they ever happen, and with that avoid re-entering
>> Fast Retransmit if initial (2) happen. It's at the cost of leaving the fast
>> retransmit an ack later but if (2) happens the impact would be much worse,
>> AFAICS.
>
> Yes, that's my sense.
>
>> Cool, thanks Neal. If Yuchung is okay with it, I'll proceed with just
>> zeroing that tstamp as initially proposed.
>
> Yes, that sounds good to me for a short-term fix for the "net" branch,
> as long as it's:
>
> +  if (!tcp_any_retrans_done(sk))
> +    tp->retrans_stamp = 0;
>
> Longer-term ("net-next"?) perhaps it makes sense to remove the hold
> state and protect against this spurious FR situation at the time we
> decide to enter Fast Recovery, which seems to be the model the RFC is
> suggesting.
Thanks for checking. So my suggested fix of removing the hold state is
the "less careful variant" that RFC does not recommend. I would rather
have the proposed 2-liner fix than implementing the section 6
heuristics to detect spurious retransmit. It's not worth the effort.
Everyone should use SACK.

>
> neal

^ permalink raw reply

* "asix: Don't reset PHY on if_up for ASIX 88772" breaks net on arndale platform
From: Riku Voipio @ 2014-11-04  7:22 UTC (permalink / raw)
  To: davem, Michel Stam; +Cc: linux-usb, netdev, linux-kernel, linux-samsung-soc

Hi,

With 3.18-rc3, asix on arndale (samsung exynos 5250 based board), fails
to work. Interface is initialized but network traffic seem not to pass
through. With kernel IP config the result looks like:

[    3.323275] usb 3-3.2.4: new high-speed USB device number 4 using exynos-ehci
[    3.419151] usb 3-3.2.4: New USB device found, idVendor=0b95, idProduct=772a
[    3.424735] usb 3-3.2.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[    3.432196] usb 3-3.2.4: Product: AX88772 
[    3.436279] usb 3-3.2.4: Manufacturer: ASIX Elec. Corp.
[    3.441486] usb 3-3.2.4: SerialNumber: 000001
[    3.447530] asix 3-3.2.4:1.0 (unnamed net_device) (uninitialized): invalid hw address, using random
[    3.764352] asix 3-3.2.4:1.0 eth0: register 'asix' at usb-12110000.usb-3.2.4, ASIX AX88772 USB 2.0 Ethernet, de:a2:66:bf:ca:4f
[    4.488773] asix 3-3.2.4:1.0 eth0: link down
[    5.690025] asix 3-3.2.4:1.0 eth0: link up, 100Mbps, full-duplex, lpa 0xC5E1
[    5.712947] Sending DHCP requests ...... timed out!
[   83.165303] IP-Config: Retrying forever (NFS root)...
[   83.170397] asix 3-3.2.4:1.0 eth0: link up, 100Mbps, full-duplex, lpa 0xC5E1
[   83.192944] Sending DHCP requests .....

Similar results also with dhclient. Git bisect identified the breaking commit as:

commit 3cc81d85ee01e5a0b7ea2f4190e2ed1165f53c31
Author: Michel Stam <m.stam@fugro.nl>
Date:   Thu Oct 2 10:22:02 2014 +0200

    asix: Don't reset PHY on if_up for ASIX 88772

Taking 3.18-rc3 and that commit reverted, network works again:

[    3.303500] usb 3-3.2.4: new high-speed USB device number 4 using exynos-ehci
[    3.399375] usb 3-3.2.4: New USB device found, idVendor=0b95, idProduct=772a
[    3.404963] usb 3-3.2.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[    3.412424] usb 3-3.2.4: Product: AX88772 
[    3.416508] usb 3-3.2.4: Manufacturer: ASIX Elec. Corp.
[    3.421715] usb 3-3.2.4: SerialNumber: 000001
[    3.427755] asix 3-3.2.4:1.0 (unnamed net_device) (uninitialized): invalid hw address, using random
[    3.744837] asix 3-3.2.4:1.0 eth0: register 'asix' at usb-12110000.usb-3.2.4, ASIX AX88772 USB 2.0 Ethernet, 12:59:f1:a8:43:90
[    7.098998] asix 3-3.2.4:1.0 eth0: link up, 100Mbps, full-duplex, lpa 0xC5E1
[    7.118258] Sending DHCP requests ., OK
[    9.753259] IP-Config: Got DHCP answer from 192.168.1.1, my address is 192.168.1.111

There might something wrong on the samsung platform code (I understand the
USB on arndale is "funny"), but this is still an regression from 3.17.

Riku

^ permalink raw reply

* Re: [PATCH 6/7] can: m_can: update to support CAN FD features
From: Dong Aisheng @ 2014-11-04  7:12 UTC (permalink / raw)
  To: Oliver Hartkopp
  Cc: netdev, varkabhadram, linux-can, mkl, wg, linux-arm-kernel
In-Reply-To: <5452A071.2000307@hartkopp.net>

On Thu, Oct 30, 2014 at 09:32:49PM +0100, Oliver Hartkopp wrote:
> 
> On 10/30/2014 03:42 AM, Dong Aisheng wrote:
> > On Wed, Oct 29, 2014 at 08:21:28PM +0100, Oliver Hartkopp wrote:
> 
> >> So first I would suggest to check the core release register (CREL) to be
> >> version 3.0.x and quit the driver initialization if it doesn't fit this
> >> version. I would suggest to provide a separate patch for that check. What
> >> about printing the core release version into the kernel log at driver
> >> initialization time?
> >>
> > 
> > One question is that if v3.1.0 and v3.2.0 will be backward compatible with
> > v3.0.1, if yes, how about let the driver still work for them instead of
> > simply quit?
> 
> There are several important differences between 3.0.x and 3.1.x.
> E.g. the CCCR, BTP, PSR and others are changed and a register for the
> transmitter delay compensation is added.
> 
> I assume from 3.1.x to 3.2.x the controller registers will only change in
> small details as the main update will be on the wire and not in the functionality.
> 
> > And then we can add new features according new released IP version.
> 
> Yes. We probably can wait for 3.[12].x to become available before adding the
> special code that behaves according the core release register content.
> 

Okay

> >>> @@ -375,7 +414,7 @@ static int m_can_do_rx_poll(struct net_device *dev, int quota)
> >>>  		if (rxfs & RXFS_RFL)
> >>>  			netdev_warn(dev, "Rx FIFO 0 Message Lost\n");
> >>>  
> >>> -		skb = alloc_can_skb(dev, &frame);
> >>> +		skb = alloc_canfd_skb(dev, &frame);
> >>
> >> You are *always* allocating CAN FD frames now?
> >>
> > 
> > Yes, currently it is.
> > The test seemed ok using CAN FD frames even receive normal frame.
> 
> When you put CAN frame content into a CAN FD skb it becomes a CAN FD frame -
> which is wrong.
> 
> CAN 2.0 frame (EDL is clear) -> alloc_can_skb()
> CAN FD frame (EDL is set) -> alloc_canfd_skb()
> 
> You can have a CAN FD frame with a DLC of 8, which does *not* mean that you
> have a CAN 2.0 frame.
> 
> > The issue i know is that candump seemed can not recognize remote frame reported
> > by the driver.
> 
> Do you use the latest candump from
> 

Yes, i'm using latest candump.

> 	https://gitorious.org/linux-can/can-utils/
> ??
> 
> The latest candump switches the CAN_RAW socket into the mode to accept both
> CAN *and* CAN FD frames and displays the frames correctly.
> 
> > Not sure if it's caused by canfd_frame used.
> 
> Yes. CAN FD frames do not have a RTR bit.
> 

You're right.
It's indeed caused by using the CAN FD frames to receive RTR frame.
After switch to normal frame, candump showed it well.

> > Will test and check.
> > 
> >> Depending on RX_BUF_EDL in the RX FIFO message you should create a CAN or CAN
> >> FD frame.
> >>
> >> Of course you can use the struct canfd_frame in m_can_read_fifo() as the
> >> layout of the struct can_frame is identical when filled with 'normal' CAN
> >> frame content.
> >>
> >> But you need to distinguish whether it is a CAN or CAN FD frame when
> >> allocating the skb based on the RX_BUF_EDL value.
> >>
> > 
> > Yes, i think it's good to do that.
> > One obvious benefit is it saves memory at least.
> 
> The main point is that CAN frames and CAN FD frames are separated by this
> (MTU) length information. It's not about saving memory.
> A CAN FD frame with DLC 8 still has 64 data bytes inside it's data structure.
> 

For normal can frame, the CAN_MAX_DLEN is 8 while CANFD_MAX_DLEN is 64.
So i meant using struct canfd_frame to receive normal frame is a bit waste memory.
And besides, actually it's wrong as you already indicated.
I will send out the updated patch with this changed in v2 soon.
Thanks for pointing out this.

Regards
Dong Aisheng

> Regards,
> Oliver

^ permalink raw reply

* Re: [0/3] net: Kill skb_copy_datagram_const_iovec
From: Al Viro @ 2014-11-04  5:45 UTC (permalink / raw)
  To: David Miller; +Cc: herbert, netdev, linux-kernel, bcrl
In-Reply-To: <20141103.150553.633529234958324183.davem@davemloft.net>

On Mon, Nov 03, 2014 at 03:05:53PM -0500, David Miller wrote:

> I'll see if I can make some progress converting the networking over
> to iov_iter.  It can't be that difficult... albeit perhaps a little
> time consuming.

FWIW, I have a queue that got started back in April; basically, the plan
of attack was
	* separate kernel-side and userland msghdr.
	* localize ->msg_iov uses - most of that gets taken care of by
several new helpers, as in
    new helper: skb_copy_datagram_msg()
    
    Absolute majority of skb_copy_datagram_iovec() callers (49 out of 56)
    are passing it msg->msg_iov as iovec.  Provide a trivial wrapper that
    takes msg as argument instead of iovec.
and several like that (the numbers in the above are probably incorrect these
days - it was done more than half a year ago).
	* switch kernel-side msghdr to iov_iter.  That means diverging
layouts; it's really not hard, since we have copying of msghdr from
userland already localized.  Initially - just a mechanical conversion
(i.e. direct uses of iov_iter fields instead of ->msg_iov/->msg_iovlen;
note that after the introduction of wrappers the number of such places
is very much reduced).
	* start converting those relatively few places to iov_iter primitives.

And that's where it got stalled, since we have to deal with expectations
of callers.  Syscall ones are trivial; that's not a problem.  Unfortunately,
there are kernel_{send,recv}msg() users, and those do care about the state the
iovec is left in.  Strictly speaking, the state of iovec after e.g.
->sendmsg() is undefined.  And it's not just protocol-dependent - unless
I'm seriously misreading it, tcp_sendmsg() ends up modifying iovec in case
when it hits tcp_send_rcvq(), while in the normal case it leaves iovec
unmodified.  So in general you need to feed ->{send,recv}msg() a throwaway copy
of iovec.  Leads to wonders like
        /* NB we can't trust socket ops to either consume our iovs
         * or leave them alone. */
        LASSERT (niov > 0);

        for (nob = i = 0; i < niov; i++) {
                scratchiov[i] = iov[i];
                nob += scratchiov[i].iov_len;
        }
        LASSERT (nob <= conn->ksnc_rx_nob_wanted);

        rc = kernel_recvmsg(conn->ksnc_sock, &msg,
                (struct kvec *)scratchiov, niov, nob, MSG_DONTWAIT);
etc.  However, there are places that don't bother and do this:
        while (total_rx < data) {
                rx_loop = kernel_recvmsg(conn->sock, &msg, iov_p, iov_len,
                                        (data - total_rx), MSG_WAITALL);
                if (rx_loop <= 0) {
                        pr_debug("rx_loop: %d total_rx: %d\n",
                                rx_loop, total_rx); 
                        return rx_loop;
                }
                total_rx += rx_loop;
                pr_debug("rx_loop: %d, total_rx: %d, data: %d\n",
                                rx_loop, total_rx, data);
        }
(that's iscsit_do_rx_data()).  Maybe it's a bug; maybe it's relying on
specific behaviour of the protocol known to be used - this code clearly
expects recvmsg to advance iovec, which seems to depend only on the
protocol.  At the moment.  In any case, it's very brittle...

Hell knows; I hadn't finished digging through that zoo - got sidetracked back
then.  *IF* all such places either use a throwaway copy or assume that iovec
gets modified, we can do the following: switch the access to iovecs to
iov_iter primitives, with the first kind of callers creating a throwaway
iov_iter and the second just feeding the same iov_iter to e.g.
kernel_recvmsg().  iovec will remain constant, iov_iter will be advanced.
Moreover, in a lot of cases of first kind will be able to get rid of
throwaway iov_iter (and of manually advancing it), effectively converting
to the second one.

If we have places that currently rely on iovec remaining unchanged (i.e.
manually advancing it after kernel_{send,recv}msg()), the series will be
more painful ;-/  I very much hope that no such places exist...

FWIW, there is also a tactical question that needs to be dealt with.  We
can, of course, start with renaming the "kernel-side" (i.e. post
copy_msghdr_from_user()/get_compat_msghdr()) to struct kmsghdr.  OTOH,
that's a _lot_ of churn for very little reason - most of the instances
in the tree are of that kind.  So I did it the other way round - introduced
struct user_msghdr (only in linux/socket.h; note that we do *not* have
struct msghdr in uabi/linux/socket.h, or anywhere else in uabi/*),
made the syscalls take pointers to it and (initially) rely upon the identical
layouts in copy_msghdr_from_user(); once we put iov_iter into kernel-side
msghdr, we'll just do it like get_compat_msghdr() does.

Is that acceptable?  It would greatly reduce the amount of churn in net/* -
we don't need to pass iov_iter separately and most of the functions in
the middle of call chains are completely unchanged.  Only the originators
of ->sendmsg()/->recvmsg() and the places doing actual data copying
need to be touched.  OTOH, it makes for kernel struct msghdr looking
odd - instead of normal ->msg_iov and ->msg_iovlen it would have
->msg_iov_iter, with ->sendmsg()/->recvmsg() callers needing to set it
up...  OTTH, the things *are* odd from userland programmer POV - sendmsg(2)
and recvmsg(2) leave the iovec unchanged, and having it changed unpredicatably
in the kernel-side counterparts seems to make for a nasty trap.  Certainly
makes for a bunch of nasty comments in the code using those...

Comments?

^ permalink raw reply

* [PATCH net 2/2] geneve: Unregister pernet subsys on module unload.
From: Jesse Gross @ 2014-11-04  3:38 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Andy Zhou
In-Reply-To: <1415072318-64442-1-git-send-email-jesse@nicira.com>

The pernet ops aren't ever unregistered, which causes a memory
leak and an OOPs if the module is ever reinserted.

CC: Andy Zhou <azhou@nicira.com>
Signed-off-by: Jesse Gross <jesse@nicira.com>
---
 net/ipv4/geneve.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/ipv4/geneve.c b/net/ipv4/geneve.c
index 6e5266c..dedb21e 100644
--- a/net/ipv4/geneve.c
+++ b/net/ipv4/geneve.c
@@ -366,6 +366,7 @@ late_initcall(geneve_init_module);
 static void __exit geneve_cleanup_module(void)
 {
 	destroy_workqueue(geneve_wq);
+	unregister_pernet_subsys(&geneve_net_ops);
 }
 module_exit(geneve_cleanup_module);
 
-- 
1.9.1

^ permalink raw reply related

* [PATCH net 1/2] geneve: Set GSO type on transmit.
From: Jesse Gross @ 2014-11-04  3:38 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Andy Zhou

Geneve does not currently set the inner protocol type when
transmitting packets. This causes GSO segmentation to fail on NICs
that do not support Geneve offloading.

CC: Andy Zhou <azhou@nicira.com>
Signed-off-by: Jesse Gross <jesse@nicira.com>
---
 net/ipv4/geneve.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/ipv4/geneve.c b/net/ipv4/geneve.c
index 065cd94..6e5266c 100644
--- a/net/ipv4/geneve.c
+++ b/net/ipv4/geneve.c
@@ -144,6 +144,8 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt,
 	gnvh = (struct genevehdr *)__skb_push(skb, sizeof(*gnvh) + opt_len);
 	geneve_build_header(gnvh, tun_flags, vni, opt_len, opt);
 
+	skb_set_inner_protocol(skb, htons(ETH_P_TEB));
+
 	return udp_tunnel_xmit_skb(gs->sock, rt, skb, src, dst,
 				   tos, ttl, df, src_port, dst_port, xnet);
 }
-- 
1.9.1

^ 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