Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next 3/3] vhost: don't touch avail ring if in_order is negotiated
From: Jason Wang @ 2018-11-26  4:01 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: netdev, linux-kernel, kvm, virtualization
In-Reply-To: <20181123103750-mutt-send-email-mst@kernel.org>


On 2018/11/23 下午11:41, Michael S. Tsirkin wrote:
> On Fri, Nov 23, 2018 at 11:00:16AM +0800, Jason Wang wrote:
>> Device use descriptors table in order, so there's no need to read
>> index from available ring. This eliminate the cache contention on
>> avail ring completely.
> Well this isn't what the in order feature says in the spec.
>
> It forces the used ring to be in the same order as
> the available ring. So I don't think you can skip
> checking the available ring.


Maybe I miss something. The spec 
(https://github.com/oasis-tcs/virtio-spec master) said: "If 
VIRTIO_F_IN_ORDER has been negotiated, driver uses descriptors in ring 
order: starting from offset 0 in the table, and wrapping around at the 
end of the table."

Even if I was wrong, maybe it's time to force this consider the obvious 
improvement it brings? And maybe what you said is the reason that we 
only allow the following optimization only for packed ring?

"notify the use of a batch of buffers to the driver by only writing out 
a single used descriptor with the Buffer ID corresponding to the last 
descriptor in the batch. "

This seems another good optimization for packed ring as well.


> And in fact depending on
> ring size and workload, using all of descriptor buffer might
> cause a slowdown.


This is not the sin of in order but the size of the queue I believe?


> Rather you should be able to get
> about the same speedup, but from skipping checking
> the used ring in virtio.


Yes, I've made such changes in virtio-net pmd. But since we're testing 
it with vhost-kernel, the main contention was on available. So the 
improvement was not obvious.

Thanks


>
>
>> Virito-user + vhost_kernel + XDP_DROP gives about ~10% improvement on
>> TX from 4.8Mpps to 5.3Mpps on Intel(R) Core(TM) i7-5600U CPU @
>> 2.60GHz.
>>
>> Signed-off-by: Jason Wang <jasowang@redhat.com>
>> ---
>>   drivers/vhost/vhost.c | 19 ++++++++++++-------
>>   1 file changed, 12 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
>> index 3a5f81a66d34..c8be151bc897 100644
>> --- a/drivers/vhost/vhost.c
>> +++ b/drivers/vhost/vhost.c
>> @@ -2002,6 +2002,7 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq,
>>   	__virtio16 avail_idx;
>>   	__virtio16 ring_head;
>>   	int ret, access;
>> +	bool in_order = vhost_has_feature(vq, VIRTIO_F_IN_ORDER);
>>   
>>   	/* Check it isn't doing very strange things with descriptor numbers. */
>>   	last_avail_idx = vq->last_avail_idx;
>> @@ -2034,15 +2035,19 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq,
>>   
>>   	/* Grab the next descriptor number they're advertising, and increment
>>   	 * the index we've seen. */
>> -	if (unlikely(vhost_get_avail(vq, ring_head,
>> -		     &vq->avail->ring[last_avail_idx & (vq->num - 1)]))) {
>> -		vq_err(vq, "Failed to read head: idx %d address %p\n",
>> -		       last_avail_idx,
>> -		       &vq->avail->ring[last_avail_idx % vq->num]);
>> -		return -EFAULT;
>> +	if (!in_order) {
>> +		if (unlikely(vhost_get_avail(vq, ring_head,
>> +		    &vq->avail->ring[last_avail_idx & (vq->num - 1)]))) {
>> +			vq_err(vq, "Failed to read head: idx %d address %p\n",
>> +				last_avail_idx,
>> +				&vq->avail->ring[last_avail_idx % vq->num]);
>> +			return -EFAULT;
>> +		}
>> +		head = vhost16_to_cpu(vq, ring_head);
>> +	} else {
>> +		head = last_avail_idx & (vq->num - 1);
>>   	}
>>   
>> -	head = vhost16_to_cpu(vq, ring_head);
>>   
>>   	/* If their number is silly, that's an error. */
>>   	if (unlikely(head >= vq->num)) {
>> -- 
>> 2.17.1
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply

* Re: [PATCH net 1/2] virtio-net: disable guest csum during XDP set
From: Jason Wang @ 2018-11-26  4:03 UTC (permalink / raw)
  To: David Miller
  Cc: mst, virtualization, netdev, linux-kernel, brouer, pashinho1990,
	dsahern
In-Reply-To: <20181123.120119.2279234989819941118.davem@davemloft.net>


On 2018/11/24 上午4:01, David Miller wrote:
> From: Jason Wang <jasowang@redhat.com>
> Date: Thu, 22 Nov 2018 14:36:30 +0800
>
>> We don't disable VIRTIO_NET_F_GUEST_CSUM if XDP was set. This means we
>> can receive partial csumed packets with metadata kept in the
>> vnet_hdr. This may have several side effects:
>>
>> - It could be overridden by header adjustment, thus is might be not
>>    correct after XDP processing.
>> - There's no way to pass such metadata information through
>>    XDP_REDIRECT to another driver.
>> - XDP does not support checksum offload right now.
>>
>> So simply disable guest csum if possible in this the case of XDP.
>>
>> Fixes: 3f93522ffab2d ("virtio-net: switch off offloads on demand if possible on XDP set")
>> Reported-by: Jesper Dangaard Brouer <brouer@redhat.com>
>> Cc: Jesper Dangaard Brouer <brouer@redhat.com>
>> Cc: Pavel Popa <pashinho1990@gmail.com>
>> Cc: David Ahern <dsahern@gmail.com>
>> Signed-off-by: Jason Wang <jasowang@redhat.com>
> Applied and queued up for -stable.
>
> We really should have a way to use the checksum provided if the XDP
> program returns XDP_PASS and does not modify the packet contents
> or size.


Yes, I think this may require the assistance of BPF verifier to set a 
flag or other. Then we can assume the metadata is safe to use.

Thanks

^ permalink raw reply

* Re: [PATCH net-next] net: phy: fix two issues with linkmode bitmaps
From: Heiner Kallweit @ 2018-11-25 17:21 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: Florian Fainelli, David Miller, netdev@vger.kernel.org
In-Reply-To: <20181125164513.GD18663@lunn.ch>

On 25.11.2018 17:45, Andrew Lunn wrote:
> On Sun, Nov 25, 2018 at 03:23:42PM +0100, Heiner Kallweit wrote:
>> I wondered why ethtool suddenly reports that link partner doesn't
>> support aneg and GBit modes. It turned out that this is caused by two
>> bugs in conversion to linkmode bitmaps.
>>
>> 1. In genphy_read_status the value of phydev->lp_advertising is
>>    overwritten, thus GBit modes aren't reported any longer.
>> 2. In mii_lpa_to_linkmode_lpa_t the aneg bit was overwritten by the
>>    call to mii_adv_to_linkmode_adv_t.
> 
> Hi Heiner
> 
> Thanks for looking into this.
> 
> There are more bugs :-(
> 
> static inline void mii_lpa_to_linkmode_lpa_t(unsigned long *lp_advertising,
>                                              u32 lpa)
> {
>         if (lpa & LPA_LPACK)
>                 linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
>                                  lp_advertising);
> 
>         mii_adv_to_linkmode_adv_t(lp_advertising, lpa);
> }
> 
> But
> 
> static inline void mii_adv_to_linkmode_adv_t(unsigned long *advertising,
>                                              u32 adv)
> {
>         linkmode_zero(advertising);
> 
>         if (adv & ADVERTISE_10HALF)
>                 linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
>                                  advertising);
>  
> So the Autoneg_BIT gets cleared.
> 
> I think the better fix is to take the linkmode_zero() out from here.
> 
> Then:
> 
>         if (adv & ADVERTISE_10HALF)
>                linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
>                                 advertising);
> +	else
> +              linkmode_clear_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
> +                                 advertising);
> 
> for all the bits mii_adv_to_linkmode_adv_t() looks at.
> 
> So mii_adv_to_linkmode_adv_t() only modifies bits it is responsible
> for, and leaves the others alone.
> 
>     Andrew
> 

mii_adv_to_linkmode_adv_t() is used also in phy_mii_ioctl(), and I'm
not sure the proposed change is safe there.

Eventually we'd have three types of mii_xxx_to_linkmode_yyy functions:

1. Function first zeroes the destination linkmode bitmap
2. Function sets bits in the linkmode bitmap but doesn't clear bits
   if condition isn't met
3. Function clears / sets bits it's responsible for

example case 1: mmd_eee_adv_to_linkmode
example case 2: mii_stat1000_to_linkmode_lpa_t
example case 3: what you just proposed as fix for
                mii_adv_to_linkmode_adv_t

Because function naming is the same I'm afraid they easily can be used
incorrectly (the bugs we just discuss are good examples). Maybe it
could be an option to reflect the semantics in the name like this
(better suited proposals welcome):

case 1: mii_xxx_to_linkmode_yyy
case 2: mii_xxx_or_linkmode_yyy
case 3: mii_xxx_mod_linkmode_yyy

Heiner

^ permalink raw reply

* Re: [PATCH iproute2-next] man: tc: update man page for fq packet scheduler
From: David Ahern @ 2018-11-25 17:42 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev, Eric Dumazet
In-Reply-To: <20181125014436.161499-1-edumazet@google.com>

On 11/24/18 6:44 PM, Eric Dumazet wrote:
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> ---
>  man/man8/tc-fq.8 | 37 ++++++++++++++++++++++++++-----------
>  1 file changed, 26 insertions(+), 11 deletions(-)
> 

applied to iproute2-next. Thanks, Eric.

^ permalink raw reply

* [RFC -next v0 0/3] netfilter: expose flow offload tables as an ebpf map
From: Aaron Conole @ 2018-11-25 18:09 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, netfilter-devel, coreteam, Alexei Starovoitov,
	Daniel Borkmann, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Florian Westphal, John Fastabend, Jesper Brouer, David S . Miller,
	Andy Gospodarek, Rony Efraim, Simon Horman, Marcelo Leitner

This is an alternate approach to exposing connection tracking data
to the XDP + eBPF world.  Rather than having to rework a number of
helper functions to ignore or rebuild metadata from an skbuff data
segment, we reuse the existing flow offload hooks that expose conntrack
tuples directly based on a flow tuple.  As this is an early-version RFC,
the API behavior is definitely going to change.  I'll be working on this
unless the flames grow so high that there's no choice but to bail and
let it burn down.

The goal of this work is to integrate the flow offload infrastructure
from netfilter, in a similar way to the approach that flow hw offload
has taken (ie: the 'slowpath' of netfilter does the heavy lifting for
lots of the required functions, like port allocations, helper parsing,
etc).  The advatange of building a series like this is two-fold:

 1.  We can get the advantages of the netfilter infrastructure today,
     and pull in functionality via various map types or operations (TBD).
     I think the next thing to add to this would be NAT support (so that
     we could actually forward end-to-end and watch things go).

 2.  For the hw offload folks, this gives a way to test out some of the
     proposed conntrack API changes without need hardware available
     today.  In fact, this might let the hardware vendors prototype their
     conntrack offload, see where the proposed APIs are lacking (or where
     they need reworking), and turn around changes quickly.

It's not all sunshine and roses, though.  The first patch in the series is
definitely controversial.  It would allow kernel subsystems to register
their own map types at module load time, rather than being compiled in to
the kernel at run-time.  I think there is a worry about this kind of
functionality enabling the eBPF ecosystem to fracture.  I don't know if
I understand the concern enough.  If that's dead in the water, there might
be an alternate approach with out patch 1 (I have a rough sketch in my
head, but haven't coded it up).

I have only done some rudimentary testing with this.  Just enough to prove
that I wasn't breaking anything existing.  I'm sending this out just as
it matched the first packet (and I'm re-running the build and retesting so
that I didn't forget to save something).  So I don't have any benchmark
data, and I don't even have support yet to do anything useful (NAT would
be needed for my IPv4 testing to to proceed, so that's my next task).

I have a small (and hacky) test program at:
  https://github.com/orgcandman/conntrack_bpf

It is only used to exercise the lookup call - it doesn't actually prevent
connections from eventually succeeding.  I eventually hope to flesh that
out into a bpf implementation of hardware offload (with various features,
like window tracking, flag validation, etc).

Aaron Conole (3):
  bpf: modular maps
  netfilter: nf_flow_table: support a new 'snoop' mode
  netfilter: nf_flow_table_bpf_map: introduce new loadable bpf map

 include/linux/bpf.h                       |   6 +
 include/linux/bpf_types.h                 |   2 +
 include/net/netfilter/nf_flow_table.h     |   5 +
 include/uapi/linux/bpf.h                  |   7 +
 include/uapi/linux/netfilter/nf_tables.h  |   2 +
 init/Kconfig                              |   8 +
 kernel/bpf/syscall.c                      |  57 +++++-
 net/netfilter/Kconfig                     |   9 +
 net/netfilter/Makefile                    |   1 +
 net/netfilter/nf_flow_table_bpf_flowmap.c | 202 ++++++++++++++++++++++
 net/netfilter/nf_flow_table_core.c        |  44 ++++-
 net/netfilter/nf_tables_api.c             |  13 +-
 12 files changed, 351 insertions(+), 5 deletions(-)
 create mode 100644 net/netfilter/nf_flow_table_bpf_flowmap.c

-- 
2.19.1

^ permalink raw reply

* [RFC -next v0 3/3] netfilter: nf_flow_table_bpf_map: introduce new loadable bpf map
From: Aaron Conole @ 2018-11-25 18:09 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, netfilter-devel, coreteam, Alexei Starovoitov,
	Daniel Borkmann, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Florian Westphal, John Fastabend, Jesper Brouer, David S . Miller,
	Andy Gospodarek, Rony Efraim, Simon Horman, Marcelo Leitner
In-Reply-To: <20181125180919.13996-1-aconole@bytheb.org>

This commit introduces a new loadable map that allows an eBPF program to
query the flow offload tables for specific flow information.  For now,
that information is limited to input and output index information.  Future
enhancements would be to include connection tracking details, such as
state, metadata, and allow for window validation.

Signed-off-by: Aaron Conole <aconole@bytheb.org>
---
 include/linux/bpf_types.h                 |   2 +
 include/uapi/linux/bpf.h                  |   7 +
 net/netfilter/Kconfig                     |   9 +
 net/netfilter/Makefile                    |   1 +
 net/netfilter/nf_flow_table_bpf_flowmap.c | 202 ++++++++++++++++++++++
 5 files changed, 221 insertions(+)
 create mode 100644 net/netfilter/nf_flow_table_bpf_flowmap.c

diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h
index 44d9ab4809bd..82d3038cf6c3 100644
--- a/include/linux/bpf_types.h
+++ b/include/linux/bpf_types.h
@@ -71,3 +71,5 @@ BPF_MAP_TYPE(BPF_MAP_TYPE_REUSEPORT_SOCKARRAY, reuseport_array_ops)
 #endif
 BPF_MAP_TYPE(BPF_MAP_TYPE_QUEUE, queue_map_ops)
 BPF_MAP_TYPE(BPF_MAP_TYPE_STACK, stack_map_ops)
+
+BPF_MAP_TYPE(BPF_MAP_TYPE_FLOWMAP, loadable_map)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 852dc17ab47a..fb77c8c5c209 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -131,6 +131,7 @@ enum bpf_map_type {
 	BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE,
 	BPF_MAP_TYPE_QUEUE,
 	BPF_MAP_TYPE_STACK,
+	BPF_MAP_TYPE_FLOWMAP,
 };
 
 enum bpf_prog_type {
@@ -2942,4 +2943,10 @@ struct bpf_flow_keys {
 	};
 };
 
+struct bpf_flow_map {
+	struct bpf_flow_keys	flow;
+	__u32			iifindex;
+	__u32			oifindex;
+};
+
 #endif /* _UAPI__LINUX_BPF_H__ */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 2ab870ef233a..30f1bc9084be 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -709,6 +709,15 @@ config NF_FLOW_TABLE
 
 	  To compile it as a module, choose M here.
 
+config NF_FLOW_TABLE_BPF
+	tristate "Netfilter flowtable BPF map"
+	depends on NF_FLOW_TABLE
+	depends on BPF_LOADABLE_MAPS
+	help
+	  This option adds support for retrieving flow table entries
+	  via a loadable BPF map.
+	  To compile it as a module, choose M here.
+
 config NETFILTER_XTABLES
 	tristate "Netfilter Xtables support (required for ip_tables)"
 	default m if NETFILTER_ADVANCED=n
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 4ddf3ef51ece..8dba928a03fd 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -121,6 +121,7 @@ obj-$(CONFIG_NFT_FWD_NETDEV)	+= nft_fwd_netdev.o
 
 # flow table infrastructure
 obj-$(CONFIG_NF_FLOW_TABLE)	+= nf_flow_table.o
+obj-$(CONFIG_NF_FLOW_TABLE_BPF)	+= nf_flow_table_bpf_flowmap.o
 nf_flow_table-objs := nf_flow_table_core.o nf_flow_table_ip.o
 
 obj-$(CONFIG_NF_FLOW_TABLE_INET) += nf_flow_table_inet.o
diff --git a/net/netfilter/nf_flow_table_bpf_flowmap.c b/net/netfilter/nf_flow_table_bpf_flowmap.c
new file mode 100644
index 000000000000..577985560883
--- /dev/null
+++ b/net/netfilter/nf_flow_table_bpf_flowmap.c
@@ -0,0 +1,202 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2018, Aaron Conole <aconole@bytheb.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/bpf.h>
+#include <net/xdp.h>
+#include <linux/filter.h>
+#include <trace/events/xdp.h>
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_flow_table.h>
+
+struct flow_map_internal {
+	struct bpf_map map;
+	struct nf_flowtable net_flow_table;
+};
+
+static void flow_map_init_from_attr(struct bpf_map *map, union bpf_attr *attr)
+{
+	map->map_type = attr->map_type;
+	map->key_size = attr->key_size;
+	map->value_size = attr->value_size;
+	map->max_entries = attr->max_entries;
+	map->map_flags = attr->map_flags;
+	map->numa_node = bpf_map_attr_numa_node(attr);
+}
+
+static struct bpf_map *flow_map_alloc(union bpf_attr *attr)
+{
+	struct flow_map_internal *fmap_ret;
+	u64 cost;
+	int err;
+
+	if (!capable(CAP_NET_ADMIN))
+		return ERR_PTR(-EPERM);
+
+	if (attr->max_entries == 0 ||
+	    attr->key_size != sizeof(struct bpf_flow_map) ||
+	    attr->value_size != sizeof(struct bpf_flow_map))
+		return ERR_PTR(-EINVAL);
+
+	fmap_ret = kzalloc(sizeof(*fmap_ret), GFP_USER);
+	if (!fmap_ret)
+		return ERR_PTR(-ENOMEM);
+
+	flow_map_init_from_attr(&fmap_ret->map, attr);
+	cost = (u64)fmap_ret->map.max_entries * sizeof(struct flow_offload);
+	if (cost >= U32_MAX - PAGE_SIZE) {
+		kfree(&fmap_ret);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	fmap_ret->map.pages = round_up(cost, PAGE_SIZE) >> PAGE_SHIFT;
+
+	/* if map size is larger than memlock limit, reject it early */
+	if ((err = bpf_map_precharge_memlock(fmap_ret->map.pages))) {
+		kfree(&fmap_ret);
+		return ERR_PTR(err);
+	}
+
+	memset(&fmap_ret->net_flow_table, 0, sizeof(fmap_ret->net_flow_table));
+	fmap_ret->net_flow_table.flags |= NF_FLOWTABLE_F_SNOOP;
+	nf_flow_table_init(&fmap_ret->net_flow_table);
+
+	return &fmap_ret->map;
+}
+
+static void flow_map_free(struct bpf_map *map)
+{
+	struct flow_map_internal *fmap = container_of(map,
+						      struct flow_map_internal,
+						      map);
+
+	nf_flow_table_free(&fmap->net_flow_table);
+	synchronize_rcu();
+	kfree(fmap);
+}
+
+static void flow_walk(struct flow_offload *flow, void *data)
+{
+	printk("Flow offload dir0: %x:%d -> %x:%d, %u, %u, %d, %u\n",
+	       flow->tuplehash[0].tuple.src_v4.s_addr,
+	       flow->tuplehash[0].tuple.src_port,
+	       flow->tuplehash[0].tuple.dst_v4.s_addr,
+	       flow->tuplehash[0].tuple.dst_port,
+	       flow->tuplehash[0].tuple.l3proto,
+	       flow->tuplehash[0].tuple.l4proto,
+	       flow->tuplehash[0].tuple.iifidx,
+	       flow->tuplehash[0].tuple.dir
+	       );
+
+	printk("Flow offload dir1: %x:%d -> %x:%d, %u, %u, %d, %u\n",
+	       flow->tuplehash[1].tuple.src_v4.s_addr,
+	       flow->tuplehash[1].tuple.src_port,
+	       flow->tuplehash[1].tuple.dst_v4.s_addr,
+	       flow->tuplehash[1].tuple.dst_port,
+	       flow->tuplehash[1].tuple.l3proto,
+	       flow->tuplehash[1].tuple.l4proto,
+	       flow->tuplehash[1].tuple.iifidx,
+	       flow->tuplehash[1].tuple.dir
+	       );
+}
+
+static void *flow_map_lookup_elem(struct bpf_map *map, void *key)
+{
+	struct flow_map_internal *fmap = container_of(map,
+						      struct flow_map_internal, map);
+	struct bpf_flow_map *internal_key = (struct bpf_flow_map *)key;
+	struct flow_offload_tuple_rhash *hash_ret;
+	struct flow_offload_tuple lookup_key;
+
+	memset(&lookup_key, 0, sizeof(lookup_key));
+	lookup_key.src_port = ntohs(internal_key->flow.sport);
+	lookup_key.dst_port = ntohs(internal_key->flow.dport);
+	lookup_key.dir = 0;
+
+	if (internal_key->flow.addr_proto == htons(ETH_P_IP)) {
+		lookup_key.l3proto = AF_INET;
+		lookup_key.src_v4.s_addr = ntohl(internal_key->flow.ipv4_src);
+		lookup_key.dst_v4.s_addr = ntohl(internal_key->flow.ipv4_dst);
+	} else if (internal_key->flow.addr_proto == htons(ETH_P_IPV6)) {
+		lookup_key.l3proto = AF_INET6;
+		memcpy(&lookup_key.src_v6,
+		       internal_key->flow.ipv6_src,
+		       sizeof(lookup_key.src_v6));
+		memcpy(&lookup_key.dst_v6,
+		       internal_key->flow.ipv6_dst,
+		       sizeof(lookup_key.dst_v6));
+	} else
+		return NULL;
+
+	lookup_key.l4proto = (u8)internal_key->flow.ip_proto;
+	lookup_key.iifidx = internal_key->iifindex;
+
+	printk("Flow offload lookup: %x:%d -> %x:%d, %u, %u, %d, %u\n",
+	       lookup_key.src_v4.s_addr, lookup_key.src_port,
+	       lookup_key.dst_v4.s_addr, lookup_key.dst_port,
+	       lookup_key.l3proto, lookup_key.l4proto,
+	       lookup_key.iifidx, lookup_key.dir);
+	hash_ret = flow_offload_lookup(&fmap->net_flow_table, &lookup_key);
+	if (!hash_ret) {
+		memcpy(&lookup_key.src_v6, internal_key->flow.ipv6_src,
+		       sizeof(lookup_key.src_v6));
+		memcpy(&lookup_key.dst_v6, internal_key->flow.ipv6_dst,
+		       sizeof(lookup_key.dst_v6));
+		lookup_key.src_port = internal_key->flow.dport;
+		lookup_key.dst_port = internal_key->flow.sport;
+		lookup_key.dir = 1;
+		hash_ret = flow_offload_lookup(&fmap->net_flow_table,
+					       &lookup_key);
+	}
+
+	if (!hash_ret) {
+		printk("No flow found, but table is: %d\n",
+		       atomic_read(&fmap->net_flow_table.rhashtable.nelems));
+		nf_flow_table_iterate(&fmap->net_flow_table, flow_walk, NULL);
+		return NULL;
+	}
+
+	printk("Flow matched!\n");
+	return key;
+}
+
+static int flow_map_get_next_key(struct bpf_map *map, void *key, void *next_key)
+{
+	return 0;
+}
+
+static int flow_map_check_no_btf(const struct bpf_map *map,
+				 const struct btf_type *key_type,
+				 const struct btf_type *value_type)
+{
+	return -ENOTSUPP;
+}
+
+const struct bpf_map_ops flow_map_ops = {
+	.map_alloc = flow_map_alloc,
+	.map_free = flow_map_free,
+	.map_get_next_key = flow_map_get_next_key,
+	.map_lookup_elem = flow_map_lookup_elem,
+	.map_check_btf = flow_map_check_no_btf,
+};
+
+static int __init flow_map_init(void)
+{
+	bpf_map_insert_ops(BPF_MAP_TYPE_FLOWMAP, &flow_map_ops);
+	return 0;
+}
+
+module_init(flow_map_init);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Aaron Conole <aconole@bytheb.org>");
-- 
2.19.1

^ permalink raw reply related

* Re: [PATCH net-next v2 0/2] r8169: make use of xmit_more and __netdev_sent_queue
From: David Miller @ 2018-11-25 18:19 UTC (permalink / raw)
  To: hkallweit1; +Cc: nic_swsd, netdev
In-Reply-To: <33ded8c6-b369-84d8-cca1-dca4c989515a@gmail.com>

From: Heiner Kallweit <hkallweit1@gmail.com>
Date: Sun, 25 Nov 2018 14:29:22 +0100

> This series adds helper __netdev_sent_queue to the core and makes use
> of it in the r8169 driver.
> 
> Heiner Kallweit (2):
>   net: core: add __netdev_sent_queue as variant of __netdev_tx_sent_queue
>   r8169: make use of xmit_more and __netdev_sent_queue
> 
> v2:
> - fix minor style issue

Series applied.

^ permalink raw reply

* Re: [PATCH 3/8] socket: Disentangle SOCK_RCVTSTAMPNS from SOCK_RCVTSTAMP
From: David Miller @ 2018-11-25 18:19 UTC (permalink / raw)
  To: willemdebruijn.kernel
  Cc: deepa.kernel, linux-kernel, netdev, viro, arnd, y2038
In-Reply-To: <CAF=yD-LjfVKSr=KhknZHhN-M2-ZdLE9g0XR8Ta4rokx24arkBg@mail.gmail.com>

From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
Date: Sun, 25 Nov 2018 09:18:55 -0500

> The existing logic is as is for a reason. There is no need to change
> it to satisfy the main purpose of your patchset?
> 
> It is structured as one bit to test whether a timestamp is requested
> and another to select among two variants usec/nsec. Just add another
> layer of branching between new/old in cases where this distinction is
> needed.
> 
> Please avoid code churn unless needed.

+1

^ permalink raw reply

* Re: [PATCH net-next] net: remove unsafe skb_insert()
From: David Miller @ 2018-11-25 18:29 UTC (permalink / raw)
  To: edumazet; +Cc: netdev, eric.dumazet, faisal.latif, dledford, jgg, linux-rdma
In-Reply-To: <20181125162623.127762-1-edumazet@google.com>

From: Eric Dumazet <edumazet@google.com>
Date: Sun, 25 Nov 2018 08:26:23 -0800

> I do not see how one can effectively use skb_insert() without holding
> some kind of lock. Otherwise other cpus could have changed the list
> right before we have a chance of acquiring list->lock.
> 
> Only existing user is in drivers/infiniband/hw/nes/nes_mgt.c and this
> one probably meant to use __skb_insert() since it appears nesqp->pau_list
> is protected by nesqp->pau_lock. This looks like nesqp->pau_lock
> could be removed, since nesqp->pau_list.lock could be used instead.
> 
> Signed-off-by: Eric Dumazet <edumazet@google.com>

Good find.

Indeed, any of the queue SKB manipulation functions that take two SKBs
as an argument are suspect in this manner.

Applied, thanks Eric.

^ permalink raw reply

* Re: Can decnet be deprecated?
From: David Miller @ 2018-11-25 18:31 UTC (permalink / raw)
  To: bjorn; +Cc: dsahern, netdev
In-Reply-To: <877eh12y3x.fsf@miraculix.mork.no>

From: Bjørn Mork <bjorn@mork.no>
Date: Sun, 25 Nov 2018 12:30:26 +0100

> David Miller <davem@davemloft.net> writes:
>> From: David Ahern <dsahern@gmail.com>
>> Date: Sat, 24 Nov 2018 17:12:48 -0700
>>
>>> IPX was moved to staging at the end of last year. Can decnet follow
>>> suit? git log seems to indicate no active development in a very long time.
>>
>> Last time I tried to do that someone immediately said on the list
>> "Don't, we're using that!"
> 
> Not sure about that.  What I can see is a claim that it has no bugs:
> http://patchwork.ozlabs.org/patch/837484/
> 
> The V1 received only support for removal:
> http://patchwork.ozlabs.org/patch/837261/
> 
> But no one claimed they were using decnet.

Ok, if people want to try and deprecate it again we can try.

^ permalink raw reply

* Re: [PATCH] mm: Replace all open encodings for NUMA_NO_NODE
From: Anshuman Khandual @ 2018-11-26  6:45 UTC (permalink / raw)
  To: Vinod Koul
  Cc: hverkuil-qWit8jRvyhVmR6Xm/wNWPw,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	linux-ia64-u79uwXL29TY76Z2rM5mHXA,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-block-u79uwXL29TY76Z2rM5mHXA,
	linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	intel-wired-lan-qjLDD68F18P21nG7glBr7A,
	linux-alpha-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	sparclinux-u79uwXL29TY76Z2rM5mHXA,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	jiangqi903-Re5JQEeQqe8AvxtiuMwx3w,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
	ocfs2-devel-N0ozoZBvEnrZJqsBc5GL+g,
	linux-media-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20181124140554.GG3175-bQVUxfxUtC3xKnQ2JfU4AA@public.gmane.org>



On 11/24/2018 07:35 PM, Vinod Koul wrote:
> On 23-11-18, 15:24, Anshuman Khandual wrote:
> 
>> --- a/drivers/dma/dmaengine.c
>> +++ b/drivers/dma/dmaengine.c
>> @@ -386,7 +386,8 @@ EXPORT_SYMBOL(dma_issue_pending_all);
>>  static bool dma_chan_is_local(struct dma_chan *chan, int cpu)
>>  {
>>  	int node = dev_to_node(chan->device->dev);
>> -	return node == -1 || cpumask_test_cpu(cpu, cpumask_of_node(node));
>> +	return node == NUMA_NO_NODE ||
>> +		cpumask_test_cpu(cpu, cpumask_of_node(node));
>>  }
> 
> I do not see dev_to_node being updated first, that returns -1 so I would
> prefer to check for -1 unless it return NUMA_NO_NODE

Sure will update dev_to_node() to return NUMA_NO_NODE as well.

^ permalink raw reply

* Re: hard-coded limit on unresolved multicast route cache in ipv4/ipmr.c causes slow, unreliable creation of multicast routes on busy networks
From: Hangbin Liu @ 2018-11-26  6:58 UTC (permalink / raw)
  To: Sukumar Gopalakrishnan
  Cc: davem, karn, kuznet, yoshfuji, netdev, linux-kernel
In-Reply-To: <CADiZnkSy=rFq5xLs6RcgJDihQ1Vwo2WBBY9Fi_5jOHr8XupukQ@mail.gmail.com>

On Mon, Nov 26, 2018 at 10:44:49AM +0530, Sukumar Gopalakrishnan wrote:
> Hi,
> 
>  There is a patch to make this queue len configurable. Is below mentioned going
> to be applied ?
> 
> http://lkml.iu.edu/hypermail/linux/kernel/1810.3/02344.html

Thanks for this reminder, I saw Stephen has gave some comments. But I'm not sure
which patch David would apply.

Thanks
Hangbin

^ permalink raw reply

* [PATCH v2 0/4] Macb power management support for ZynqMP
From: Harini Katakam @ 2018-11-26  7:07 UTC (permalink / raw)
  To: nicolas.ferre, davem, claudiu.beznea
  Cc: netdev, linux-kernel, michal.simek, harinikatakamlinux,
	harini.katakam

This series adds support for macb suspend/resume with system power down.
In relation to the above, this series also updates mdio_read/write
function for PM and adds tsu clock management.

Harini Katakam (4):
  net: macb: Check MDIO state before read/write and use timeouts
  net: macb: Support clock management for tsu_clk
  net: macb: Add pm runtime support
  net: macb: Add support for suspend/resume with full power down

 drivers/net/ethernet/cadence/macb.h      |   6 +-
 drivers/net/ethernet/cadence/macb_main.c | 210 +++++++++++++++++++++++++++----
 2 files changed, 188 insertions(+), 28 deletions(-)

-- 
2.7.4

^ permalink raw reply

* [PATCH v2 1/4] net: macb: Check MDIO state before read/write and use timeouts
From: Harini Katakam @ 2018-11-26  7:07 UTC (permalink / raw)
  To: nicolas.ferre, davem, claudiu.beznea
  Cc: netdev, linux-kernel, michal.simek, harinikatakamlinux,
	harini.katakam, Harini Katakam, Shubhrajyoti Datta,
	Sai Pavan Boddu
In-Reply-To: <1543216072-9623-1-git-send-email-harini.katakam@xilinx.com>

From: Harini Katakam <harinik@xilinx.com>

Replace the while loop in MDIO read/write functions with a timeout.
In addition, add a check for MDIO bus busy before initiating a new
operation as well to make sure there is no ongoing MDIO operation.

Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
Signed-off-by: Harini Katakam <harinik@xilinx.com>
---
v2 changes:
Use readx_poll_timeout

Changes form RFC:
Cleaned up timeout implementation and moved it to a helper.

 drivers/net/ethernet/cadence/macb.h      |  3 +++
 drivers/net/ethernet/cadence/macb_main.c | 33 ++++++++++++++++++++++++++------
 2 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index 3d45f4c..df7bee1 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -714,6 +714,9 @@
 		__v; \
 	})
 
+#define MACB_IDLE_MASK		(1 << MACB_IDLE_OFFSET)
+#define MACB_READ_NSR(bp)	macb_readl(bp, NSR)
+
 /* struct macb_dma_desc - Hardware DMA descriptor
  * @addr: DMA address of data buffer
  * @ctrl: Control and status bits
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 1d86b4d..fd86ece 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -36,6 +36,7 @@
 #include <linux/ip.h>
 #include <linux/udp.h>
 #include <linux/tcp.h>
+#include <linux/iopoll.h>
 #include "macb.h"
 
 #define MACB_RX_BUFFER_SIZE	128
@@ -79,6 +80,8 @@
  */
 #define MACB_HALT_TIMEOUT	1230
 
+#define MACB_MDIO_TIMEOUT	1000000 /* in usecs */
+
 /* DMA buffer descriptor might be different size
  * depends on hardware configuration:
  *
@@ -318,10 +321,23 @@ static void macb_get_hwaddr(struct macb *bp)
 	eth_hw_addr_random(bp->dev);
 }
 
+static int macb_mdio_wait_for_idle(struct macb *bp)
+{
+	u32 val;
+
+	return readx_poll_timeout(MACB_READ_NSR, bp, val, val & MACB_IDLE_MASK,
+				  1, MACB_MDIO_TIMEOUT);
+}
+
 static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
 {
 	struct macb *bp = bus->priv;
 	int value;
+	int err;
+
+	err = macb_mdio_wait_for_idle(bp);
+	if (err < 0)
+		return err;
 
 	macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF)
 			      | MACB_BF(RW, MACB_MAN_READ)
@@ -329,9 +345,9 @@ static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
 			      | MACB_BF(REGA, regnum)
 			      | MACB_BF(CODE, MACB_MAN_CODE)));
 
-	/* wait for end of transfer */
-	while (!MACB_BFEXT(IDLE, macb_readl(bp, NSR)))
-		cpu_relax();
+	err = macb_mdio_wait_for_idle(bp);
+	if (err < 0)
+		return err;
 
 	value = MACB_BFEXT(DATA, macb_readl(bp, MAN));
 
@@ -342,6 +358,11 @@ static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
 			   u16 value)
 {
 	struct macb *bp = bus->priv;
+	int err;
+
+	err = macb_mdio_wait_for_idle(bp);
+	if (err < 0)
+		return err;
 
 	macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF)
 			      | MACB_BF(RW, MACB_MAN_WRITE)
@@ -350,9 +371,9 @@ static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
 			      | MACB_BF(CODE, MACB_MAN_CODE)
 			      | MACB_BF(DATA, value)));
 
-	/* wait for end of transfer */
-	while (!MACB_BFEXT(IDLE, macb_readl(bp, NSR)))
-		cpu_relax();
+	err = macb_mdio_wait_for_idle(bp);
+	if (err < 0)
+		return err;
 
 	return 0;
 }
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 2/4] net: macb: Support clock management for tsu_clk
From: Harini Katakam @ 2018-11-26  7:07 UTC (permalink / raw)
  To: nicolas.ferre, davem, claudiu.beznea
  Cc: netdev, linux-kernel, michal.simek, harinikatakamlinux,
	harini.katakam, Harini Katakam
In-Reply-To: <1543216072-9623-1-git-send-email-harini.katakam@xilinx.com>

From: Harini Katakam <harinik@xilinx.com>

TSU clock needs to be enabled/disabled as per support in devicetree
and it should also be controlled during suspend/resume (WOL has no
dependency on this clock).

Signed-off-by: Harini Katakam <harinik@xilinx.com>
---
v2:
No changes

 drivers/net/ethernet/cadence/macb.h      |  3 ++-
 drivers/net/ethernet/cadence/macb_main.c | 30 +++++++++++++++++++++++++-----
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index df7bee1..e0fddff 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -1085,7 +1085,7 @@ struct macb_config {
 	unsigned int		dma_burst_length;
 	int	(*clk_init)(struct platform_device *pdev, struct clk **pclk,
 			    struct clk **hclk, struct clk **tx_clk,
-			    struct clk **rx_clk);
+			    struct clk **rx_clk, struct clk **tsu_clk);
 	int	(*init)(struct platform_device *pdev);
 	int	jumbo_max_len;
 };
@@ -1165,6 +1165,7 @@ struct macb {
 	struct clk		*hclk;
 	struct clk		*tx_clk;
 	struct clk		*rx_clk;
+	struct clk		*tsu_clk;
 	struct net_device	*dev;
 	union {
 		struct macb_stats	macb;
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index fd86ece..32453d4 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -3293,7 +3293,7 @@ static void macb_probe_queues(void __iomem *mem,
 
 static int macb_clk_init(struct platform_device *pdev, struct clk **pclk,
 			 struct clk **hclk, struct clk **tx_clk,
-			 struct clk **rx_clk)
+			 struct clk **rx_clk, struct clk **tsu_clk)
 {
 	struct macb_platform_data *pdata;
 	int err;
@@ -3327,6 +3327,10 @@ static int macb_clk_init(struct platform_device *pdev, struct clk **pclk,
 	if (IS_ERR(*rx_clk))
 		*rx_clk = NULL;
 
+	*tsu_clk = devm_clk_get(&pdev->dev, "tsu_clk");
+	if (IS_ERR(*tsu_clk))
+		*tsu_clk = NULL;
+
 	err = clk_prepare_enable(*pclk);
 	if (err) {
 		dev_err(&pdev->dev, "failed to enable pclk (%u)\n", err);
@@ -3351,8 +3355,17 @@ static int macb_clk_init(struct platform_device *pdev, struct clk **pclk,
 		goto err_disable_txclk;
 	}
 
+	err = clk_prepare_enable(*tsu_clk);
+	if (err) {
+		dev_err(&pdev->dev, "failed to enable tsu_clk (%u)\n", err);
+		goto err_disable_rxclk;
+	}
+
 	return 0;
 
+err_disable_rxclk:
+	clk_disable_unprepare(*rx_clk);
+
 err_disable_txclk:
 	clk_disable_unprepare(*tx_clk);
 
@@ -3803,13 +3816,14 @@ static const struct net_device_ops at91ether_netdev_ops = {
 
 static int at91ether_clk_init(struct platform_device *pdev, struct clk **pclk,
 			      struct clk **hclk, struct clk **tx_clk,
-			      struct clk **rx_clk)
+			      struct clk **rx_clk, struct clk **tsu_clk)
 {
 	int err;
 
 	*hclk = NULL;
 	*tx_clk = NULL;
 	*rx_clk = NULL;
+	*tsu_clk = NULL;
 
 	*pclk = devm_clk_get(&pdev->dev, "ether_clk");
 	if (IS_ERR(*pclk))
@@ -3957,11 +3971,12 @@ static int macb_probe(struct platform_device *pdev)
 {
 	const struct macb_config *macb_config = &default_gem_config;
 	int (*clk_init)(struct platform_device *, struct clk **,
-			struct clk **, struct clk **,  struct clk **)
-					      = macb_config->clk_init;
+			struct clk **, struct clk **,  struct clk **,
+			struct clk **) = macb_config->clk_init;
 	int (*init)(struct platform_device *) = macb_config->init;
 	struct device_node *np = pdev->dev.of_node;
 	struct clk *pclk, *hclk = NULL, *tx_clk = NULL, *rx_clk = NULL;
+	struct clk *tsu_clk = NULL;
 	unsigned int queue_mask, num_queues;
 	struct macb_platform_data *pdata;
 	bool native_io;
@@ -3989,7 +4004,7 @@ static int macb_probe(struct platform_device *pdev)
 		}
 	}
 
-	err = clk_init(pdev, &pclk, &hclk, &tx_clk, &rx_clk);
+	err = clk_init(pdev, &pclk, &hclk, &tx_clk, &rx_clk, &tsu_clk);
 	if (err)
 		return err;
 
@@ -4026,6 +4041,7 @@ static int macb_probe(struct platform_device *pdev)
 	bp->hclk = hclk;
 	bp->tx_clk = tx_clk;
 	bp->rx_clk = rx_clk;
+	bp->tsu_clk = tsu_clk;
 	if (macb_config)
 		bp->jumbo_max_len = macb_config->jumbo_max_len;
 
@@ -4141,6 +4157,7 @@ static int macb_probe(struct platform_device *pdev)
 	clk_disable_unprepare(hclk);
 	clk_disable_unprepare(pclk);
 	clk_disable_unprepare(rx_clk);
+	clk_disable_unprepare(tsu_clk);
 
 	return err;
 }
@@ -4168,6 +4185,7 @@ static int macb_remove(struct platform_device *pdev)
 		clk_disable_unprepare(bp->hclk);
 		clk_disable_unprepare(bp->pclk);
 		clk_disable_unprepare(bp->rx_clk);
+		clk_disable_unprepare(bp->tsu_clk);
 		of_node_put(bp->phy_node);
 		free_netdev(dev);
 	}
@@ -4193,6 +4211,7 @@ static int __maybe_unused macb_suspend(struct device *dev)
 		clk_disable_unprepare(bp->pclk);
 		clk_disable_unprepare(bp->rx_clk);
 	}
+	clk_disable_unprepare(bp->tsu_clk);
 
 	return 0;
 }
@@ -4212,6 +4231,7 @@ static int __maybe_unused macb_resume(struct device *dev)
 		clk_prepare_enable(bp->tx_clk);
 		clk_prepare_enable(bp->rx_clk);
 	}
+	clk_prepare_enable(bp->tsu_clk);
 
 	netif_device_attach(netdev);
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 3/4] net: macb: Add pm runtime support
From: Harini Katakam @ 2018-11-26  7:07 UTC (permalink / raw)
  To: nicolas.ferre, davem, claudiu.beznea
  Cc: netdev, linux-kernel, michal.simek, harinikatakamlinux,
	harini.katakam, Harini Katakam, Shubhrajyoti Datta
In-Reply-To: <1543216072-9623-1-git-send-email-harini.katakam@xilinx.com>

From: Harini Katakam <harinik@xilinx.com>

Add runtime pm functions and move clock handling there.
Add runtime PM calls to mdio functions to allow for active mdio bus.

Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>
Signed-off-by: Harini Katakam <harinik@xilinx.com>
---
v2 changes:
Allow for mdio bus to be active

Changes from RFC:
Updated pm get sync/put sync calls.
Removed unecessary clk up in mdio helpers.

 drivers/net/ethernet/cadence/macb_main.c | 121 ++++++++++++++++++++++++++-----
 1 file changed, 101 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 32453d4..4b85ad7 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -37,6 +37,7 @@
 #include <linux/udp.h>
 #include <linux/tcp.h>
 #include <linux/iopoll.h>
+#include <linux/pm_runtime.h>
 #include "macb.h"
 
 #define MACB_RX_BUFFER_SIZE	128
@@ -80,6 +81,8 @@
  */
 #define MACB_HALT_TIMEOUT	1230
 
+#define MACB_PM_TIMEOUT  100 /* ms */
+
 #define MACB_MDIO_TIMEOUT	1000000 /* in usecs */
 
 /* DMA buffer descriptor might be different size
@@ -335,6 +338,10 @@ static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
 	int value;
 	int err;
 
+	err = pm_runtime_get_sync(&bp->pdev->dev);
+	if (err < 0)
+		return err;
+
 	err = macb_mdio_wait_for_idle(bp);
 	if (err < 0)
 		return err;
@@ -346,11 +353,17 @@ static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
 			      | MACB_BF(CODE, MACB_MAN_CODE)));
 
 	err = macb_mdio_wait_for_idle(bp);
-	if (err < 0)
+	if (err < 0) {
+		pm_runtime_mark_last_busy(&bp->pdev->dev);
+		pm_runtime_put_autosuspend(&bp->pdev->dev);
 		return err;
+	}
 
 	value = MACB_BFEXT(DATA, macb_readl(bp, MAN));
 
+	pm_runtime_mark_last_busy(&bp->pdev->dev);
+	pm_runtime_put_autosuspend(&bp->pdev->dev);
+
 	return value;
 }
 
@@ -360,10 +373,17 @@ static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
 	struct macb *bp = bus->priv;
 	int err;
 
-	err = macb_mdio_wait_for_idle(bp);
+	err = pm_runtime_get_sync(&bp->pdev->dev);
 	if (err < 0)
 		return err;
 
+	err = macb_mdio_wait_for_idle(bp);
+	if (err < 0) {
+		pm_runtime_mark_last_busy(&bp->pdev->dev);
+		pm_runtime_put_autosuspend(&bp->pdev->dev);
+		return err;
+	}
+
 	macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF)
 			      | MACB_BF(RW, MACB_MAN_WRITE)
 			      | MACB_BF(PHYA, mii_id)
@@ -375,6 +395,9 @@ static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
 	if (err < 0)
 		return err;
 
+	pm_runtime_mark_last_busy(&bp->pdev->dev);
+	pm_runtime_put_autosuspend(&bp->pdev->dev);
+
 	return 0;
 }
 
@@ -2386,12 +2409,18 @@ static int macb_open(struct net_device *dev)
 
 	netdev_dbg(bp->dev, "open\n");
 
+	err = pm_runtime_get_sync(&bp->pdev->dev);
+	if (err < 0)
+		goto pm_exit;
+
 	/* carrier starts down */
 	netif_carrier_off(dev);
 
 	/* if the phy is not yet register, retry later*/
-	if (!dev->phydev)
-		return -EAGAIN;
+	if (!dev->phydev) {
+		err = -EAGAIN;
+		goto pm_exit;
+	}
 
 	/* RX buffers initialization */
 	macb_init_rx_buffer_size(bp, bufsz);
@@ -2400,7 +2429,7 @@ static int macb_open(struct net_device *dev)
 	if (err) {
 		netdev_err(dev, "Unable to allocate DMA memory (error %d)\n",
 			   err);
-		return err;
+		goto pm_exit;
 	}
 
 	bp->macbgem_ops.mog_init_rings(bp);
@@ -2417,6 +2446,11 @@ static int macb_open(struct net_device *dev)
 	if (bp->ptp_info)
 		bp->ptp_info->ptp_init(dev);
 
+pm_exit:
+	if (err) {
+		pm_runtime_put_sync(&bp->pdev->dev);
+		return err;
+	}
 	return 0;
 }
 
@@ -2445,6 +2479,8 @@ static int macb_close(struct net_device *dev)
 	if (bp->ptp_info)
 		bp->ptp_info->ptp_remove(dev);
 
+	pm_runtime_put(&bp->pdev->dev);
+
 	return 0;
 }
 
@@ -4008,6 +4044,11 @@ static int macb_probe(struct platform_device *pdev)
 	if (err)
 		return err;
 
+	pm_runtime_set_autosuspend_delay(&pdev->dev, MACB_PM_TIMEOUT);
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_get_noresume(&pdev->dev);
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
 	native_io = hw_is_native_io(mem);
 
 	macb_probe_queues(mem, native_io, &queue_mask, &num_queues);
@@ -4139,6 +4180,9 @@ static int macb_probe(struct platform_device *pdev)
 		    macb_is_gem(bp) ? "GEM" : "MACB", macb_readl(bp, MID),
 		    dev->base_addr, dev->irq, dev->dev_addr);
 
+	pm_runtime_mark_last_busy(&bp->pdev->dev);
+	pm_runtime_put_autosuspend(&bp->pdev->dev);
+
 	return 0;
 
 err_out_unregister_mdio:
@@ -4158,6 +4202,9 @@ static int macb_probe(struct platform_device *pdev)
 	clk_disable_unprepare(pclk);
 	clk_disable_unprepare(rx_clk);
 	clk_disable_unprepare(tsu_clk);
+	pm_runtime_disable(&pdev->dev);
+	pm_runtime_set_suspended(&pdev->dev);
+	pm_runtime_dont_use_autosuspend(&pdev->dev);
 
 	return err;
 }
@@ -4181,11 +4228,16 @@ static int macb_remove(struct platform_device *pdev)
 		mdiobus_free(bp->mii_bus);
 
 		unregister_netdev(dev);
-		clk_disable_unprepare(bp->tx_clk);
-		clk_disable_unprepare(bp->hclk);
-		clk_disable_unprepare(bp->pclk);
-		clk_disable_unprepare(bp->rx_clk);
-		clk_disable_unprepare(bp->tsu_clk);
+		pm_runtime_disable(&pdev->dev);
+		pm_runtime_dont_use_autosuspend(&pdev->dev);
+		if (!pm_runtime_suspended(&pdev->dev)) {
+			clk_disable_unprepare(bp->tx_clk);
+			clk_disable_unprepare(bp->hclk);
+			clk_disable_unprepare(bp->pclk);
+			clk_disable_unprepare(bp->rx_clk);
+			clk_disable_unprepare(bp->tsu_clk);
+			pm_runtime_set_suspended(&pdev->dev);
+		}
 		of_node_put(bp->phy_node);
 		free_netdev(dev);
 	}
@@ -4205,13 +4257,9 @@ static int __maybe_unused macb_suspend(struct device *dev)
 		macb_writel(bp, IER, MACB_BIT(WOL));
 		macb_writel(bp, WOL, MACB_BIT(MAG));
 		enable_irq_wake(bp->queues[0].irq);
-	} else {
-		clk_disable_unprepare(bp->tx_clk);
-		clk_disable_unprepare(bp->hclk);
-		clk_disable_unprepare(bp->pclk);
-		clk_disable_unprepare(bp->rx_clk);
 	}
-	clk_disable_unprepare(bp->tsu_clk);
+
+	pm_runtime_force_suspend(dev);
 
 	return 0;
 }
@@ -4221,11 +4269,43 @@ static int __maybe_unused macb_resume(struct device *dev)
 	struct net_device *netdev = dev_get_drvdata(dev);
 	struct macb *bp = netdev_priv(netdev);
 
+	pm_runtime_force_resume(dev);
+
 	if (bp->wol & MACB_WOL_ENABLED) {
 		macb_writel(bp, IDR, MACB_BIT(WOL));
 		macb_writel(bp, WOL, 0);
 		disable_irq_wake(bp->queues[0].irq);
-	} else {
+	}
+
+	netif_device_attach(netdev);
+
+	return 0;
+}
+
+static int __maybe_unused macb_runtime_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct net_device *netdev = platform_get_drvdata(pdev);
+	struct macb *bp = netdev_priv(netdev);
+
+	if (!(device_may_wakeup(&bp->dev->dev))) {
+		clk_disable_unprepare(bp->tx_clk);
+		clk_disable_unprepare(bp->hclk);
+		clk_disable_unprepare(bp->pclk);
+		clk_disable_unprepare(bp->rx_clk);
+	}
+	clk_disable_unprepare(bp->tsu_clk);
+
+	return 0;
+}
+
+static int __maybe_unused macb_runtime_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct net_device *netdev = platform_get_drvdata(pdev);
+	struct macb *bp = netdev_priv(netdev);
+
+	if (!(device_may_wakeup(&bp->dev->dev))) {
 		clk_prepare_enable(bp->pclk);
 		clk_prepare_enable(bp->hclk);
 		clk_prepare_enable(bp->tx_clk);
@@ -4233,12 +4313,13 @@ static int __maybe_unused macb_resume(struct device *dev)
 	}
 	clk_prepare_enable(bp->tsu_clk);
 
-	netif_device_attach(netdev);
-
 	return 0;
 }
 
-static SIMPLE_DEV_PM_OPS(macb_pm_ops, macb_suspend, macb_resume);
+static const struct dev_pm_ops macb_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(macb_suspend, macb_resume)
+	SET_RUNTIME_PM_OPS(macb_runtime_suspend, macb_runtime_resume, NULL)
+};
 
 static struct platform_driver macb_driver = {
 	.probe		= macb_probe,
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 4/4] net: macb: Add support for suspend/resume with full power down
From: Harini Katakam @ 2018-11-26  7:07 UTC (permalink / raw)
  To: nicolas.ferre, davem, claudiu.beznea
  Cc: netdev, linux-kernel, michal.simek, harinikatakamlinux,
	harini.katakam, Kedareswara rao Appana
In-Reply-To: <1543216072-9623-1-git-send-email-harini.katakam@xilinx.com>

When macb device is suspended and system is powered down, the clocks
are removed and hence macb should be closed gracefully and restored
upon resume. This patch does the same by switching off the net device,
suspending phy and performing necessary cleanup of interrupts and BDs.
Upon resume, all these are reinitialized again.

Reset of macb device is done only when GEM is not a wake device.
Even when gem is a wake device, tx queues can be stopped and ptp device
can be closed (tsu clock will be disabled in pm_runtime_suspend) as
wake event detection has no dependency on this.

Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
Signed-off-by: Harini Katakam <harini.katakam@xilinx.com>
---
v2 changes:
Fixed parameter passed to phy calls.

 drivers/net/ethernet/cadence/macb_main.c | 38 ++++++++++++++++++++++++++++++--
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 4b85ad7..dcb0194 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -4249,16 +4249,33 @@ static int __maybe_unused macb_suspend(struct device *dev)
 {
 	struct net_device *netdev = dev_get_drvdata(dev);
 	struct macb *bp = netdev_priv(netdev);
+	struct macb_queue *queue = bp->queues;
+	unsigned long flags;
+	unsigned int q;
+
+	if (!netif_running(netdev))
+		return 0;
 
-	netif_carrier_off(netdev);
-	netif_device_detach(netdev);
 
 	if (bp->wol & MACB_WOL_ENABLED) {
 		macb_writel(bp, IER, MACB_BIT(WOL));
 		macb_writel(bp, WOL, MACB_BIT(MAG));
 		enable_irq_wake(bp->queues[0].irq);
+		netif_device_detach(netdev);
+	} else {
+		netif_device_detach(netdev);
+		for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue)
+			napi_disable(&queue->napi);
+		phy_stop(netdev->phydev);
+		phy_suspend(netdev->phydev);
+		spin_lock_irqsave(&bp->lock, flags);
+		macb_reset_hw(bp);
+		spin_unlock_irqrestore(&bp->lock, flags);
 	}
 
+	netif_carrier_off(netdev);
+	if (bp->ptp_info)
+		bp->ptp_info->ptp_remove(netdev);
 	pm_runtime_force_suspend(dev);
 
 	return 0;
@@ -4268,6 +4285,11 @@ static int __maybe_unused macb_resume(struct device *dev)
 {
 	struct net_device *netdev = dev_get_drvdata(dev);
 	struct macb *bp = netdev_priv(netdev);
+	struct macb_queue *queue = bp->queues;
+	unsigned int q;
+
+	if (!netif_running(netdev))
+		return 0;
 
 	pm_runtime_force_resume(dev);
 
@@ -4275,9 +4297,21 @@ static int __maybe_unused macb_resume(struct device *dev)
 		macb_writel(bp, IDR, MACB_BIT(WOL));
 		macb_writel(bp, WOL, 0);
 		disable_irq_wake(bp->queues[0].irq);
+	} else {
+		macb_writel(bp, NCR, MACB_BIT(MPE));
+		for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue)
+			napi_enable(&queue->napi);
+		phy_resume(netdev->phydev);
+		phy_init_hw(netdev->phydev);
+		phy_start(netdev->phydev);
 	}
 
+	bp->macbgem_ops.mog_init_rings(bp);
+	macb_init_hw(bp);
+	macb_set_rx_mode(netdev);
 	netif_device_attach(netdev);
+	if (bp->ptp_info)
+		bp->ptp_info->ptp_init(netdev);
 
 	return 0;
 }
-- 
2.7.4

^ permalink raw reply related

* Re: [PATCH net-next] net: phy: fix two issues with linkmode bitmaps
From: Andrew Lunn @ 2018-11-25 20:47 UTC (permalink / raw)
  To: Heiner Kallweit; +Cc: Florian Fainelli, David Miller, netdev@vger.kernel.org
In-Reply-To: <3917cdd2-ae04-7392-4b08-cf2d15082dcd@gmail.com>

> Eventually we'd have three types of mii_xxx_to_linkmode_yyy functions:
> 
> 1. Function first zeroes the destination linkmode bitmap
> 2. Function sets bits in the linkmode bitmap but doesn't clear bits
>    if condition isn't met
> 3. Function clears / sets bits it's responsible for
> 
> example case 1: mmd_eee_adv_to_linkmode
> example case 2: mii_stat1000_to_linkmode_lpa_t
> example case 3: what you just proposed as fix for
>                 mii_adv_to_linkmode_adv_t
> 
> Because function naming is the same I'm afraid they easily can be used
> incorrectly (the bugs we just discuss are good examples). Maybe it
> could be an option to reflect the semantics in the name like this
> (better suited proposals welcome):
> 
> case 1: mii_xxx_to_linkmode_yyy
> case 2: mii_xxx_or_linkmode_yyy
> case 3: mii_xxx_mod_linkmode_yyy

Hi Heiner

That is a good idea. We should probably do this first, it will help
find the bugs.

     Andrew

^ permalink raw reply

* [PATCH 04/13] net: stmmac: dwmac-rk: Do not print redundant error message
From: Otavio Salvador @ 2018-11-25 21:18 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, linux-rockchip
  Cc: Otavio Salvador, Fabio Berton, Jose Abreu, Giuseppe Cavallaro,
	netdev, Alexandre Torgue, Maxime Coquelin, linux-stm32,
	David S. Miller
In-Reply-To: <20181125211907.9895-1-otavio@ossystems.com.br>

rk_gmac_setup() already prints a message saying that the PHY regulator
is not found, so we should not print it again.

Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
Signed-off-by: Fabio Berton <fabio.berton@ossystems.com.br>
---

 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 73855622445b..c895a9a6939a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -1203,10 +1203,8 @@ static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable)
 	int ret;
 	struct device *dev = &bsp_priv->pdev->dev;
 
-	if (!ldo) {
-		dev_err(dev, "no regulator found\n");
+	if (!ldo)
 		return 0;
-	}
 
 	if (enable) {
 		ret = regulator_enable(ldo);
-- 
2.19.1

^ permalink raw reply related

* [PATCH 05/13] net: stmmac: dwmac-rk: Do not print error when PHY regulator is not found
From: Otavio Salvador @ 2018-11-25 21:18 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, linux-rockchip
  Cc: Otavio Salvador, Fabio Berton, Jose Abreu, Giuseppe Cavallaro,
	netdev, Alexandre Torgue, Maxime Coquelin, linux-stm32,
	David S. Miller
In-Reply-To: <20181125211907.9895-1-otavio@ossystems.com.br>

The PHY regulator is optional, so when it is not present move the message
level from error to debug, which is more appropriate.

Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
Signed-off-by: Fabio Berton <fabio.berton@ossystems.com.br>
---

 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index c895a9a6939a..6b4ea95a30e0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -1242,7 +1242,7 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
 			dev_err(dev, "phy regulator is not available yet, deferred probing\n");
 			return ERR_PTR(-EPROBE_DEFER);
 		}
-		dev_err(dev, "no regulator found\n");
+		dev_dbg(dev, "no regulator found\n");
 		bsp_priv->regulator = NULL;
 	}
 
-- 
2.19.1

^ permalink raw reply related

* Re: [PATCH 7/8] socket: Add SO_TIMESTAMP[NS]_NEW
From: Arnd Bergmann @ 2018-11-25 22:35 UTC (permalink / raw)
  To: Willem de Bruijn
  Cc: Deepa Dinamani, David Miller, Linux Kernel Mailing List,
	Networking, Al Viro, y2038 Mailman List, James E.J. Bottomley,
	Ralf Baechle, Richard Henderson, linux-alpha,
	open list:RALINK MIPS ARCHITECTURE, Parisc List, linux-rdma,
	sparclinux
In-Reply-To: <CAF=yD-LngkYq23Q2TCJv_0PRiAryznYRWRbqYFaQkNO=U0w9gQ@mail.gmail.com>

On Sun, Nov 25, 2018 at 3:33 PM Willem de Bruijn
<willemdebruijn.kernel@gmail.com> wrote:
> On Sun, Nov 25, 2018 at 12:28 AM Deepa Dinamani <deepa.kernel@gmail.com> wrote:
> > So failing here means adding a bunch of ifdef's to verify it is not
> > executing on 64 bit arch or something like x32.
>
> The code as is adds branches on platforms that do not need it. Ifdefs
> are ugly, but if they can be contained to the few helper functions needed
> for the _2038 variants of cmsg_put, that is acceptable in my opinion.

In general, I think we should plan for the new code to be the fast path,
not the old one. Initially that obviously won't be the case, but I hope
that in a couple of years from now, 32-bit user space will normally use
64-bit time_t.

This also means that the compat handling for these timestamps
can be identical to the native 64-bit bit version, while the old
32-bit code can be hidden behind a flag that is only active
as the slowpath in native 32-bit mode or in compat mode.

I'd also want to see the same thing for the naming, with the
64-bit time_t based code having the obvious name.
SOCK_TSTAMP_NEW is fine, otherwise we can try to
just use SOCK_TSTAMP as the name in the kernel but
make it refer to the new version.

The two special cases we have consider are x86 with x32
user space, which wants 64-bit timestamps in compat mode
with SOCK_TSTAMP_OLD, and sparc64, which has an
incompatible layout of timeval, so we need to make sure
that sparc64 can handle all three layouts correctly.

> > The existing timestamp options: SO_TIMESTAMP* fail to provide proper
> > timestamps beyond year 2038 on 32 bit ABIs.
> > But, these work fine on 64 bit native ABIs.
> > So now we need a way of updating these timestamps so that we do not
> > break existing userspace: 64 bit ABIs should not have to change
> > userspace, 32 bit ABIs should work as is until 2038 after which they
> > have bad timestamps.
> > So we introduce new y2038 safe timestamp options for 32 bit ABIs. We
> > assume that 32 bit applications will switch to new ABIs at some point,
> > but leave the older timestamps as is.
> > I can update the commit text as per above.
>
> So on 32-bit platforms SO_TIMESTAMP_NEW introduces a new struct
> sock_timeval with both 64-bit fields.
>
> Does this not break existing applications that compile against SO_TIMESTAMP
> and expect struct timeval? For one example, the selftests under tools/testing.
>
> The kernel will now convert SO_TIMESTAMP (previously constant 29) to
> different SO_TIMESTAMP_NEW (62) and returns a different struct. Perhaps
> with a library like libc in the middle this can be fixed up
> transparently, but for
> applications that don't have a more recent libc or use a library at
> all, it breaks
> the ABI.
>
> I suspect that these finer ABI points may have been discussed outside the
> narrow confines of socket timestamping. But on its own, this does worry me.

The entire purpose of the complexities in the patch set is to not break
the user space ABI after an application gets recompiled with a 64-bit
time_t defined by a new libc version:

#define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? \
            SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW)

This delays the evaluation of SO_TIMESTAMP to the point where
it is first used, the assumption being that at this point we have included
the libc header file that defines both 'time_t' and 'struct timeval'.
[If we have not included that header, we get a compile-time error,
which is also necessary because the compiler has no way of deciding
whether to use SO_TIMESTAMP_OLD or SO_TIMESTAMP_NEW
in that case].

If the application is built with a 32-bit time_t, or with on a 64-bit
architecture (all of which have 64-bit time_t and __kernel_long_t),
or on x32 (which also has 64-bit time_t and __kernel_long_t),
the result is SO_TIMESTAMP_OLD, so we tell the kernel
to send back a timestamp in the old format, and everything works
as it did before.

The only thing that changes is 32-bit user space (other than x32) with
a 64-bit time_t. In this case, the application expects a structure
that corresponds to the new sock_timeval (which is compatible
with the user space timeval based on 64-bit time_t), so we must
use the new constant in order to tell the kernel which one we want.

      Arnd

^ permalink raw reply

* Re: [PATCH net-next] net: remove unsafe skb_insert()
From: kbuild test robot @ 2018-11-25 22:52 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: kbuild-all, David S . Miller, netdev, Eric Dumazet, Eric Dumazet,
	Faisal Latif, Doug Ledford, Jason Gunthorpe, linux-rdma
In-Reply-To: <20181125162623.127762-1-edumazet@google.com>

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

Hi Eric,

I love your patch! Yet something to improve:

[auto build test ERROR on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Eric-Dumazet/net-remove-unsafe-skb_insert/20181126-061342
config: x86_64-randconfig-x009-201847 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/infiniband//hw/nes/nes_mgt.c: In function 'queue_fpdus':
>> drivers/infiniband//hw/nes/nes_mgt.c:561:29: error: passing argument 3 of '__skb_insert' from incompatible pointer type [-Werror=incompatible-pointer-types]
      __skb_insert(tmpskb, skb, &nesqp->pau_list);
                                ^
   In file included from drivers/infiniband//hw/nes/nes_mgt.c:34:0:
   include/linux/skbuff.h:1752:20: note: expected 'struct sk_buff *' but argument is of type 'struct sk_buff_head *'
    static inline void __skb_insert(struct sk_buff *newsk,
                       ^~~~~~~~~~~~
>> drivers/infiniband//hw/nes/nes_mgt.c:561:3: error: too few arguments to function '__skb_insert'
      __skb_insert(tmpskb, skb, &nesqp->pau_list);
      ^~~~~~~~~~~~
   In file included from drivers/infiniband//hw/nes/nes_mgt.c:34:0:
   include/linux/skbuff.h:1752:20: note: declared here
    static inline void __skb_insert(struct sk_buff *newsk,
                       ^~~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/__skb_insert +561 drivers/infiniband//hw/nes/nes_mgt.c

   503	
   504	/**
   505	 * queue_fpdus - Handle fpdu's that hw passed up to sw
   506	 */
   507	static void queue_fpdus(struct sk_buff *skb, struct nes_vnic *nesvnic, struct nes_qp *nesqp)
   508	{
   509		struct sk_buff *tmpskb;
   510		struct nes_rskb_cb *cb;
   511		struct iphdr *iph;
   512		struct tcphdr *tcph;
   513		unsigned char *tcph_end;
   514		u32 rcv_nxt;
   515		u32 rcv_wnd;
   516		u32 seqnum;
   517		u32 len;
   518		bool process_it = false;
   519		unsigned long flags;
   520	
   521		/* Move data ptr to after tcp header */
   522		iph = (struct iphdr *)skb->data;
   523		tcph = (struct tcphdr *)(((char *)iph) + (4 * iph->ihl));
   524		seqnum = be32_to_cpu(tcph->seq);
   525		tcph_end = (((char *)tcph) + (4 * tcph->doff));
   526	
   527		len = be16_to_cpu(iph->tot_len);
   528		if (skb->len > len)
   529			skb_trim(skb, len);
   530		skb_pull(skb, tcph_end - skb->data);
   531	
   532		/* Initialize tracking values */
   533		cb = (struct nes_rskb_cb *)&skb->cb[0];
   534		cb->seqnum = seqnum;
   535	
   536		/* Make sure data is in the receive window */
   537		rcv_nxt = nesqp->pau_rcv_nxt;
   538		rcv_wnd = le32_to_cpu(nesqp->nesqp_context->rcv_wnd);
   539		if (!between(seqnum, rcv_nxt, (rcv_nxt + rcv_wnd))) {
   540			nes_mgt_free_skb(nesvnic->nesdev, skb, PCI_DMA_TODEVICE);
   541			nes_rem_ref_cm_node(nesqp->cm_node);
   542			return;
   543		}
   544	
   545		spin_lock_irqsave(&nesqp->pau_lock, flags);
   546	
   547		if (nesqp->pau_busy)
   548			nesqp->pau_pending = 1;
   549		else
   550			nesqp->pau_busy = 1;
   551	
   552		/* Queue skb by sequence number */
   553		if (skb_queue_len(&nesqp->pau_list) == 0) {
   554			__skb_queue_head(&nesqp->pau_list, skb);
   555		} else {
   556			skb_queue_walk(&nesqp->pau_list, tmpskb) {
   557				cb = (struct nes_rskb_cb *)&tmpskb->cb[0];
   558				if (before(seqnum, cb->seqnum))
   559					break;
   560			}
 > 561			__skb_insert(tmpskb, skb, &nesqp->pau_list);
   562		}
   563		if (nesqp->pau_state == PAU_READY)
   564			process_it = true;
   565		spin_unlock_irqrestore(&nesqp->pau_lock, flags);
   566	
   567		if (process_it)
   568			process_fpdus(nesvnic, nesqp);
   569	
   570		return;
   571	}
   572	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 30370 bytes --]

^ permalink raw reply

* Re: [PATCH v2 net-next] ptp: Fix pass zero to ERR_PTR() in ptp_clock_register
From: YueHaibing @ 2018-11-26 10:20 UTC (permalink / raw)
  To: Richard Cochran; +Cc: davem, dmitry.torokhov, linux-kernel, netdev
In-Reply-To: <20181123163714.rxp766mx63bnx4tb@localhost>



On 2018/11/24 0:37, Richard Cochran wrote:
> On Fri, Nov 23, 2018 at 09:54:55AM +0800, YueHaibing wrote:
>> @@ -264,6 +266,7 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
>>  		pps.owner = info->owner;
>>  		ptp->pps_source = pps_register_source(&pps, PTP_PPS_DEFAULTS);
>>  		if (!ptp->pps_source) {
>> +			err = -EINVAL;
> 
> Bonus points:  The function, pps_register_source(), keeps error codes
> in a local variable, but it does not make use of the code.  There are
> only five callers of that function, and so it would be nice to let
> pps_register_source() return the error code.

Ok, I will post a new patch to do it.

> 
> For the present patch:
> 
> Acked-by: Richard Cochran <richardcochran@gmail.com>
> 
> 

^ permalink raw reply

* [PATCH -next] pps: using ERR_PTR instead of NULL while pps_register_source fails
From: YueHaibing @ 2018-11-26 10:24 UTC (permalink / raw)
  To: davem, giometti, richardcochran, sudipm.mukherjee, gregkh
  Cc: linux-kernel, netdev, YueHaibing

pps_register_source() has keeps error codes in a local variable,
but it does not make use of the code. This patch let it return
the errcode in case of failure.

Suggested-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 drivers/pps/clients/pps-gpio.c    | 4 ++--
 drivers/pps/clients/pps-ktimer.c  | 4 ++--
 drivers/pps/clients/pps-ldisc.c   | 4 ++--
 drivers/pps/clients/pps_parport.c | 2 +-
 drivers/pps/kapi.c                | 5 +++--
 drivers/ptp/ptp_clock.c           | 4 ++--
 6 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/pps/clients/pps-gpio.c b/drivers/pps/clients/pps-gpio.c
index 333ad7d..dd5d110 100644
--- a/drivers/pps/clients/pps-gpio.c
+++ b/drivers/pps/clients/pps-gpio.c
@@ -158,10 +158,10 @@ static int pps_gpio_probe(struct platform_device *pdev)
 	if (data->capture_clear)
 		pps_default_params |= PPS_CAPTURECLEAR | PPS_OFFSETCLEAR;
 	data->pps = pps_register_source(&data->info, pps_default_params);
-	if (data->pps == NULL) {
+	if (IS_ERR(data->pps)) {
 		dev_err(&pdev->dev, "failed to register IRQ %d as PPS source\n",
 			data->irq);
-		return -EINVAL;
+		return PTR_ERR(data->pps);
 	}
 
 	/* register IRQ interrupt handler */
diff --git a/drivers/pps/clients/pps-ktimer.c b/drivers/pps/clients/pps-ktimer.c
index 0473564..728818b 100644
--- a/drivers/pps/clients/pps-ktimer.c
+++ b/drivers/pps/clients/pps-ktimer.c
@@ -80,9 +80,9 @@ static int __init pps_ktimer_init(void)
 {
 	pps = pps_register_source(&pps_ktimer_info,
 				PPS_CAPTUREASSERT | PPS_OFFSETASSERT);
-	if (pps == NULL) {
+	if (IS_ERR(pps)) {
 		pr_err("cannot register PPS source\n");
-		return -ENOMEM;
+		return PTR_ERR(pps);
 	}
 
 	timer_setup(&ktimer, pps_ktimer_event, 0);
diff --git a/drivers/pps/clients/pps-ldisc.c b/drivers/pps/clients/pps-ldisc.c
index 73bd3bb..00f6c46 100644
--- a/drivers/pps/clients/pps-ldisc.c
+++ b/drivers/pps/clients/pps-ldisc.c
@@ -72,9 +72,9 @@ static int pps_tty_open(struct tty_struct *tty)
 
 	pps = pps_register_source(&info, PPS_CAPTUREBOTH | \
 				PPS_OFFSETASSERT | PPS_OFFSETCLEAR);
-	if (pps == NULL) {
+	if (IS_ERR(pps)) {
 		pr_err("cannot register PPS source \"%s\"\n", info.path);
-		return -ENOMEM;
+		return PTR_ERR(pps);
 	}
 	pps->lookup_cookie = tty;
 
diff --git a/drivers/pps/clients/pps_parport.c b/drivers/pps/clients/pps_parport.c
index 4db824f..7226e39 100644
--- a/drivers/pps/clients/pps_parport.c
+++ b/drivers/pps/clients/pps_parport.c
@@ -179,7 +179,7 @@ static void parport_attach(struct parport *port)
 
 	device->pps = pps_register_source(&info,
 			PPS_CAPTUREBOTH | PPS_OFFSETASSERT | PPS_OFFSETCLEAR);
-	if (device->pps == NULL) {
+	if (IS_ERR(device->pps)) {
 		pr_err("couldn't register PPS source\n");
 		goto err_release_dev;
 	}
diff --git a/drivers/pps/kapi.c b/drivers/pps/kapi.c
index 805c749..a1c3cd3 100644
--- a/drivers/pps/kapi.c
+++ b/drivers/pps/kapi.c
@@ -72,7 +72,8 @@ static void pps_echo_client_default(struct pps_device *pps, int event,
  * source is described by info's fields and it will have, as default PPS
  * parameters, the ones specified into default_params.
  *
- * The function returns, in case of success, the PPS device. Otherwise NULL.
+ * The function returns, in case of success, the PPS device. Otherwise
+ * ERR_PTR(errno).
  */
 
 struct pps_device *pps_register_source(struct pps_source_info *info,
@@ -135,7 +136,7 @@ struct pps_device *pps_register_source(struct pps_source_info *info,
 pps_register_source_exit:
 	pr_err("%s: unable to register source\n", info->name);
 
-	return NULL;
+	return ERR_PTR(err);
 }
 EXPORT_SYMBOL(pps_register_source);
 
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
index 8a81eec..48f3594 100644
--- a/drivers/ptp/ptp_clock.c
+++ b/drivers/ptp/ptp_clock.c
@@ -265,8 +265,8 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
 		pps.mode = PTP_PPS_MODE;
 		pps.owner = info->owner;
 		ptp->pps_source = pps_register_source(&pps, PTP_PPS_DEFAULTS);
-		if (!ptp->pps_source) {
-			err = -EINVAL;
+		if (IS_ERR(ptp->pps_source)) {
+			err = PTR_ERR(ptp->pps_source);
 			pr_err("failed to register pps source\n");
 			goto no_pps;
 		}
-- 
2.7.0

^ permalink raw reply related

* [PATCH] bpf: btf: fix spelling mistake "Memmber" -> "Member"
From: Colin King @ 2018-11-25 23:32 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, netdev; +Cc: kernel-janitors, linux-kernel

From: Colin Ian King <colin.king@canonical.com>

There is a spelling mistake in a btf_verifier_log_member message,
fix it.

Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
 kernel/bpf/btf.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 69da9169819a..a09b2f94ab25 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -1621,7 +1621,7 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env,
 
 		if (BITS_ROUNDUP_BYTES(member->offset) > struct_size) {
 			btf_verifier_log_member(env, t, member,
-						"Memmber bits_offset exceeds its struct size");
+						"Member bits_offset exceeds its struct size");
 			return -EINVAL;
 		}
 
-- 
2.19.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