Re: Issue with load across multiple connections

2017-04-09 Thread Ulrich Speidel

Dear Eric,

My apologies for taking so long to get back to you - I had to wait for 
some experiments to finish until I could grab hold of two machines that 
weren't busy and had a more or less direct connection.


On the server (a Super Micro):

root@serverQ:/home/lei/Desktop/servers-20160311# cat 
/proc/sys/net/ipv4/tcp_rmem

409687380   6291456
root@serverQ:/home/lei/Desktop/servers-20160311# cat 
/proc/sys/net/ipv4/tcp_wmem

409616384   4194304
root@serverQ:/home/lei/Desktop/servers-20160311# cat 
/proc/sys/net/ipv4/tcp_mem

47337   63117   94674

On the client (a Raspberry Pi):

root@server-controller:/home/lei/20160226/servers-20160226# cat 
/proc/sys/net/ipv4/tcp_rmem

409687380   6291456
root@server-controller:/home/lei/20160226/servers-20160226# cat 
/proc/sys/net/ipv4/tcp_wmem

409616384   4194304
root@server-controller:/home/lei/20160226/servers-20160226# cat 
/proc/sys/net/ipv4/tcp_mem

22206   29611   44412

nstat output:

On server:

root@serverQ:/home/lei/Desktop/servers-20160311# nstat
#kernel
IpInReceives223487 0.0
IpInDelivers223487 0.0
IpOutRequests   242888 0.0
TcpPassiveOpens 2625   0.0
TcpEstabResets  1  0.0
TcpInSegs   217980 0.0
TcpOutSegs  227965 0.0
TcpRetransSegs  14888  0.0
TcpOutRsts  6350.0
UdpInDatagrams  8090.0
UdpOutDatagrams 32 0.0
Ip6InReceives   21 0.0
Ip6InDelivers   17 0.0
Ip6OutRequests  4  0.0
Ip6InMcastPkts  17 0.0
Ip6OutMcastPkts 8  0.0
Ip6InOctets 1480   0.0
Ip6OutOctets2880.0
Ip6InMcastOctets1192   0.0
Ip6OutMcastOctets   5760.0
Ip6InNoECTPkts  21 0.0
Icmp6InMsgs 13 0.0
Icmp6OutMsgs4  0.0
Icmp6InGroupMembQueries 4  0.0
Icmp6InGroupMembResponses   4  0.0
Icmp6InNeighborAdvertisements   5  0.0
Icmp6OutGroupMembResponses  4  0.0
Icmp6InType130  4  0.0
Icmp6InType131  4  0.0
Icmp6InType136  5  0.0
Icmp6OutType131 4  0.0
TcpExtSyncookiesSent1820.0
TcpExtSyncookiesRecv1820.0
TcpExtSyncookiesFailed  6220.0
TcpExtTW3370.0
TcpExtPAWSEstab 34317  0.0
TcpExtDelayedACKs   3  0.0
TcpExtDelayedACKLost7  0.0
TcpExtListenOverflows   8  0.0
TcpExtListenDrops   1900.0
TcpExtTCPHPHits 2  0.0
TcpExtTCPPureAcks   95602  0.0
TcpExtTCPHPAcks 14 0.0
TcpExtTCPSackRecovery   2784   0.0
TcpExtTCPSACKReorder1  0.0
TcpExtTCPFullUndo   1901   0.0
TcpExtTCPPartialUndo8830.0
TcpExtTCPFastRetrans1292   0.0
TcpExtTCPForwardRetrans 13592  0.0
TcpExtTCPTimeouts   4  0.0
TcpExtTCPLossProbes 18 0.0
TcpExtTCPDSACKOldSent   7  0.0
TcpExtTCPDSACKRecv  97 0.0
TcpExtTCPDSACKIgnoredNoUndo 97 0.0
TcpExtTCPSackShiftFallback  207045 0.0
TcpExtTCPReqQFullDoCookies  1820.0
IpExtInMcastPkts8170.0
IpExtOutMcastPkts   2  0.0
IpExtInBcastPkts4690   0.0
IpExtInOctets   15946943   0.0
IpExtOutOctets  295423944  0.0
IpExtInMcastOctets  200946 0.0
IpExtOutMcastOctets 64 0.0
IpExtInBcastOctets  629914 0.0
IpExtInNoECTPkts223487 0.0

On client:

root@server-controller:/home/lei/20160226/servers-20160226# nstat
#kernel
IpInReceives249082 0.0
IpInDelivers249030 0.0
IpOutRequests   218185 0.0
TcpActiveOpens  2641   0.0
TcpInSegs   242884 0.0
TcpOutSegs   

Re: [kernel-hardening] [PATCH net-next v6 07/11] landlock: Add ptrace restrictions

2017-04-09 Thread Djalal Harouni
On Wed, Mar 29, 2017 at 1:46 AM, Mickaël Salaün  wrote:
> A landlocked process has less privileges than a non-landlocked process
> and must then be subject to additional restrictions when manipulating
> processes. To be allowed to use ptrace(2) and related syscalls on a
> target process, a landlocked process must have a subset of the target
> process' rules.
>
> New in v6
>
> Signed-off-by: Mickaël Salaün 
> Cc: Alexei Starovoitov 
> Cc: Andy Lutomirski 
> Cc: Daniel Borkmann 
> Cc: David S. Miller 
> Cc: James Morris 
> Cc: Kees Cook 
> Cc: Serge E. Hallyn 
> ---
>  security/landlock/Makefile   |   2 +-
>  security/landlock/hooks_ptrace.c | 126 
> +++
>  security/landlock/hooks_ptrace.h |  11 
>  security/landlock/init.c |   2 +
>  4 files changed, 140 insertions(+), 1 deletion(-)
>  create mode 100644 security/landlock/hooks_ptrace.c
>  create mode 100644 security/landlock/hooks_ptrace.h
>
[...]

> +/**
> + * landlock_ptrace_access_check - determine whether the current process may
> + *   access another
> + *
> + * @child: the process to be accessed
> + * @mode: the mode of attachment
> + *
> + * If the current task has Landlock rules, then the child must have at least
> + * the same rules.  Else denied.
> + *
> + * Determine whether a process may access another, returning 0 if permission
> + * granted, -errno if denied.
> + */
> +static int landlock_ptrace_access_check(struct task_struct *child,
> +   unsigned int mode)
> +{
> +   if (!landlocked(current))
> +   return 0;
> +
> +   if (!landlocked(child))
> +   return -EPERM;
> +
> +   if (landlock_task_has_subset_events(current, child))
> +   return 0;
> +
> +   return -EPERM;
> +}
> +

Maybe you want to check the mode argument here if it is a
PTRACE_ATTACH which may translate to read/writes ? PTRACE_READ are
normally for reads only. Or also which creds were used if this was a
direct syscall or a filesystem call through procfs.

I'm bringing this, since you may want to make some room for landlock
ptrace events and what others may want to do with it. Also I'm
planning to send another v2 RFC for procfs separate instances [1], the
aim is to give LSMs a security_ptrace_access_check hook path when
dealing with /proc// [2]  . Right now LSMs don't really have a
security path there, and the implementation does not guarantee that.
With this Yama ptrace scope or other LSMs may take advantage of it and
check the 'PTRACE_MODE_READ_FSCRED' mode for filesystem accesses.
That's why I think it would be better if the default landlock ptrace
semantics are not that wide.

Thanks!

[1] https://lkml.org/lkml/2017/3/30/670
[2] http://lxr.free-electrons.com/source/fs/proc/base.c#L719


[PATCH] ipv6: Fix idev->addr_list corruption

2017-04-09 Thread Rabin Vincent
From: Rabin Vincent 

addrconf_ifdown() removes elements from the idev->addr_list without
holding the idev->lock.

If this happens while the loop in __ipv6_dev_get_saddr() is handling the
same element, that function ends up in an infinite loop:

  NMI watchdog: BUG: soft lockup - CPU#1 stuck for 23s! [test:1719]
  Call Trace:
   ipv6_get_saddr_eval+0x13c/0x3a0
   __ipv6_dev_get_saddr+0xe4/0x1f0
   ipv6_dev_get_saddr+0x1b4/0x204
   ip6_dst_lookup_tail+0xcc/0x27c
   ip6_dst_lookup_flow+0x38/0x80
   udpv6_sendmsg+0x708/0xba8
   sock_sendmsg+0x18/0x30
   SyS_sendto+0xb8/0xf8
   syscall_common+0x34/0x58

Fixes: 6a923934c33 (Revert "ipv6: Revert optional address flusing on ifdown.")
Signed-off-by: Rabin Vincent 
---
 net/ipv6/addrconf.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 3631725..80ce478 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3626,14 +3626,19 @@ static int addrconf_ifdown(struct net_device *dev, int 
how)
INIT_LIST_HEAD(&del_list);
list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) {
struct rt6_info *rt = NULL;
+   bool keep;
 
addrconf_del_dad_work(ifa);
 
+   keep = keep_addr && (ifa->flags & IFA_F_PERMANENT) &&
+   !addr_is_local(&ifa->addr);
+   if (!keep)
+   list_move(&ifa->if_list, &del_list);
+
write_unlock_bh(&idev->lock);
spin_lock_bh(&ifa->lock);
 
-   if (keep_addr && (ifa->flags & IFA_F_PERMANENT) &&
-   !addr_is_local(&ifa->addr)) {
+   if (keep) {
/* set state to skip the notifier below */
state = INET6_IFADDR_STATE_DEAD;
ifa->state = 0;
@@ -3645,8 +3650,6 @@ static int addrconf_ifdown(struct net_device *dev, int 
how)
} else {
state = ifa->state;
ifa->state = INET6_IFADDR_STATE_DEAD;
-
-   list_move(&ifa->if_list, &del_list);
}
 
spin_unlock_bh(&ifa->lock);
-- 
2.7.0



Re: [PATCH 1/5] netlink: extended ACK reporting

2017-04-09 Thread Johannes Berg

> perhaps I misunderstand something, but nla_parse suggests attribute
> type can not be 0:
[...]

Yes, some - very few - families still insist on using attribute 0,
perhaps parsing by hand or so. Like you say though, the entire
infrastructure makes that hard and undesirable, so I don't really see
why we need to invest the extra code/work into making it work *here*,
especially since it's such a corner case as I described in my other
email.

johannes


Re: [PATCH v2 1/2] bpf: remove struct bpf_prog_type_list

2017-04-09 Thread Johannes Berg

> > If you just don't want to list things multiple times how about:
> > 
> > linux/bpf_verifiers.h:
> > BPF_VERIFIER(BPF_PROG_TYPE_SOCKET_FILTER, sk_filter_prog_ops)
> > BPF_VERIFIER(BPF_PROG_TYPE_SCHED_CLS, tc_cls_prog_ops)
> >  ...
> > 
> > Then in bpf.h:
> > 
> > #define BPF_VERIFIER(TYPE_VAL, SYM) extern const struct
> > bpf_verifier_ops SYM;
> > #include  > 
> > and in kernel/bpf/syscall.c:
> > 
> > #define BPF_VERIFIER(TYPE_VAL, SYM) [TYPE_VAL] = &SYM,
> > #include  > 
> > or something like that.
> 
> That is great suggestion! I like it.

It'd doable, but then I need to play with the include guards, like
having "#define __BPF_REINCLUDE" or something like that before
reincluding it, I guess? Unless that file can simply not be included
anywhere?

Maybe I'll play with it - though perhaps it should be named bpf_types.h
or something like that so we don't have to have two files.

johannes


[PATCH] p54: add null pointer check before releasing socket buffer

2017-04-09 Thread Myungho Jung
Kernel panic is caused by trying to dereference null pointer. Check if
the pointer is null before freeing space.

Signed-off-by: Myungho Jung 
---
 drivers/net/wireless/intersil/p54/txrx.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intersil/p54/txrx.c 
b/drivers/net/wireless/intersil/p54/txrx.c
index 1af7da0..8956061 100644
--- a/drivers/net/wireless/intersil/p54/txrx.c
+++ b/drivers/net/wireless/intersil/p54/txrx.c
@@ -503,7 +503,9 @@ static void p54_rx_eeprom_readback(struct p54_common *priv,
 
priv->eeprom = NULL;
tmp = p54_find_and_unlink_skb(priv, hdr->req_id);
-   dev_kfree_skb_any(tmp);
+   if (unlikely(!tmp))
+   dev_kfree_skb_any(tmp);
+
complete(&priv->eeprom_comp);
 }
 
@@ -597,7 +599,9 @@ static void p54_rx_stats(struct p54_common *priv, struct 
sk_buff *skb)
}
 
tmp = p54_find_and_unlink_skb(priv, hdr->req_id);
-   dev_kfree_skb_any(tmp);
+   if (unlikely(!tmp))
+   dev_kfree_skb_any(tmp);
+
complete(&priv->stat_comp);
 }
 
-- 
2.7.4



Re: [PATCH v2 1/2] bpf: remove struct bpf_prog_type_list

2017-04-09 Thread Alexei Starovoitov
On Sun, Apr 09, 2017 at 06:22:36PM -0700, David Miller wrote:
> From: Johannes Berg 
> Date: Fri,  7 Apr 2017 21:00:07 +0200
> 
> > From: Johannes Berg 
> > 
> > There's no need to have struct bpf_prog_type_list since
> > it just contains a list_head, the type, and the ops
> > pointer. Since the types are densely packed and not
> > actually dynamically registered, it's much easier and
> > smaller to have an array of type->ops pointer. Also
> > initialize this array statically to remove code needed
> > to initialize it.
> > 
> > Signed-off-by: Johannes Berg 
> 
> If you just don't want to list things multiple times how about:
> 
> linux/bpf_verifiers.h:
> BPF_VERIFIER(BPF_PROG_TYPE_SOCKET_FILTER, sk_filter_prog_ops)
> BPF_VERIFIER(BPF_PROG_TYPE_SCHED_CLS, tc_cls_prog_ops)
>  ...
> 
> Then in bpf.h:
> 
> #define BPF_VERIFIER(TYPE_VAL, SYM) extern const struct bpf_verifier_ops SYM;
> #include  
> and in kernel/bpf/syscall.c:
> 
> #define BPF_VERIFIER(TYPE_VAL, SYM) [TYPE_VAL] = &SYM,
> #include  
> or something like that.

That is great suggestion! I like it.



Re: [PATCH v2 net-next RFC] Generic XDP

2017-04-09 Thread Alexei Starovoitov
On Sun, Apr 09, 2017 at 01:35:28PM -0700, David Miller wrote:
> 
> This provides a generic non-optimized XDP implementation when the
> device driver does not provide an optimized one.
> 
> It is arguable that perhaps I should have required something like
> this as part of the initial XDP feature merge.
> 
> I believe this is critical for two reasons:
> 
> 1) Accessibility.  More people can play with XDP with less
>dependencies.  Yes I know we have XDP support in virtio_net, but
>that just creates another depedency for learning how to use this
>facility.
> 
>I wrote this to make life easier for the XDP newbies.
> 
> 2) As a model for what the expected semantics are.  If there is a pure
>generic core implementation, it serves as a semantic example for
>driver folks adding XDP support.
> 
> This is just a rough draft and is untested.
> 
> Signed-off-by: David S. Miller 
...
> +static u32 netif_receive_generic_xdp(struct sk_buff *skb,
> +  struct bpf_prog *xdp_prog)
> +{
> + struct xdp_buff xdp;
> + u32 act = XDP_DROP;
> + void *orig_data;
> + int hlen, off;
> +
> + if (skb_linearize(skb))
> + goto do_drop;

do we need to force disable gro ?
Otherwise if we linearize skb_is_gso packet it will be huge
and not similar to normal xdp packets?
gso probably needs to disabled too to avoid veth surprises?

> +
> + hlen = skb_headlen(skb);
> + xdp.data = skb->data;

it probably should be
hlen = skb_headlen(skb) + skb->mac_len;
xdp.data = skb->data - skb->mac_len;
to make sure xdp program is looking at l2 header.

> + xdp.data_end = xdp.data + hlen;
> + xdp.data_hard_start = xdp.data - skb_headroom(skb);
> + orig_data = xdp.data;
> + act = bpf_prog_run_xdp(xdp_prog, &xdp);
> +
> + off = xdp.data - orig_data;
> + if (off)
> + __skb_push(skb, off);

and restore l2 back somehow and get new skb->protocol ?
if we simply do __skb_pull(skb, skb->mac_len); like
we do with cls_bpf, it will not work correctly,
since if the program did ip->ipip encap (like our balancer
does and the test tools/testing/selftests/bpf/test_xdp.c)
the skb metadata fields will be wrong.
So we need to repeat eth_type_trans() here if (xdp.data != orig_data)

In case of cls_bpf when we mess with skb sizes we always
adjust skb metafields in helpers, so there it's fine
and __skb_pull(skb, skb->mac_len); is enough.
Here we need to be a bit more careful.

>  static int netif_receive_skb_internal(struct sk_buff *skb)
>  {
>   int ret;
> @@ -4258,6 +4336,21 @@ static int netif_receive_skb_internal(struct sk_buff 
> *skb)
>  
>   rcu_read_lock();
>  
> + if (static_key_false(&generic_xdp_needed)) {
> + struct bpf_prog *xdp_prog = rcu_dereference(skb->dev->xdp_prog);
> +
> + if (xdp_prog) {
> + u32 act = netif_receive_generic_xdp(skb, xdp_prog);

That's indeed the best attachment point in the stack.
I was trying to see whether it can be lowered into something like
dev_gro_receive(), but not everyone calls it.
Another option to put it into eth_type_trans() itself, then
there are no problems with gro, l2 headers, and adjust_head,
but changing all drivers is too much.

> +
> + if (act != XDP_PASS) {
> + rcu_read_unlock();
> + if (act == XDP_TX)
> + dev_queue_xmit(skb);

It should be fine. For cls_bpf we do recursion check __bpf_tx_skb()
but I forgot specific details. May be here it's fine as-is.
Daniel, do we need recursion check here?

> @@ -6725,14 +6819,16 @@ int dev_change_xdp_fd(struct net_device *dev, int fd, 
> u32 flags)
>  
>   ASSERT_RTNL();
>  
> - if (!ops->ndo_xdp)
> - return -EOPNOTSUPP;
> + xdp_op = ops->ndo_xdp;
> + if (!xdp_op)
> + xdp_op = generic_xdp_install;

I suspect there always be drivers that don't support xdp (like e100),
so this generic_xdp_install() will stay with us forever.
Since it will stay, can we enable it for xdp enabled drivers too?
This will allow us to test both raw xdp and skb-based paths neck to neck.
Today bpf-newbies typically start developing with cls_bpf, since
it can run on tap/veth and then refactor the program to xdp.
Unfortunately cls_bpf and xdp programs are substantially different,
so it pretty much means that cls_bpf prog is a throw away.
If we can add a flag to this xdp netlink attach command
that says 'enable skb-based xdp', we'll have exactly the same
program running on raw dma buffer and on skb, which will help
developing on veth/tap and moving the same prog into physical
eth0 later. And users will be able to switch between skb-based
mode on eth0 and raw-buffer mode back and forth to see perf difference
(and hopefully nothing else).

Another advantage that it will help to flush out the differences
between skb- and raw- modes in the drivers that support xdp already.

Yet another b

[PATCH v2 02/12] ftgmac100: Move ftgmac100_hard_start_xmit() around

2017-04-09 Thread Benjamin Herrenschmidt
Move it below ftgmac100_xmit() and the rest of the tx path

No code change.

Signed-off-by: Benjamin Herrenschmidt 
---

v2. - Fix patch splitting mistake
---
 drivers/net/ethernet/faraday/ftgmac100.c | 58 
 1 file changed, 29 insertions(+), 29 deletions(-)

diff --git a/drivers/net/ethernet/faraday/ftgmac100.c 
b/drivers/net/ethernet/faraday/ftgmac100.c
index f4b719214..21df322 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -673,6 +673,35 @@ static int ftgmac100_xmit(struct ftgmac100 *priv, struct 
sk_buff *skb,
return NETDEV_TX_OK;
 }
 
+static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
+struct net_device *netdev)
+{
+   struct ftgmac100 *priv = netdev_priv(netdev);
+   dma_addr_t map;
+
+   if (unlikely(skb->len > MAX_PKT_SIZE)) {
+   if (net_ratelimit())
+   netdev_dbg(netdev, "tx packet too big\n");
+
+   netdev->stats.tx_dropped++;
+   kfree_skb(skb);
+   return NETDEV_TX_OK;
+   }
+
+   map = dma_map_single(priv->dev, skb->data, skb_headlen(skb), 
DMA_TO_DEVICE);
+   if (unlikely(dma_mapping_error(priv->dev, map))) {
+   /* drop packet */
+   if (net_ratelimit())
+   netdev_err(netdev, "map socket buffer failed\n");
+
+   netdev->stats.tx_dropped++;
+   kfree_skb(skb);
+   return NETDEV_TX_OK;
+   }
+
+   return ftgmac100_xmit(priv, skb, map);
+}
+
 static void ftgmac100_free_buffers(struct ftgmac100 *priv)
 {
int i;
@@ -1210,35 +1239,6 @@ static int ftgmac100_stop(struct net_device *netdev)
return 0;
 }
 
-static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
-struct net_device *netdev)
-{
-   struct ftgmac100 *priv = netdev_priv(netdev);
-   dma_addr_t map;
-
-   if (unlikely(skb->len > MAX_PKT_SIZE)) {
-   if (net_ratelimit())
-   netdev_dbg(netdev, "tx packet too big\n");
-
-   netdev->stats.tx_dropped++;
-   kfree_skb(skb);
-   return NETDEV_TX_OK;
-   }
-
-   map = dma_map_single(priv->dev, skb->data, skb_headlen(skb), 
DMA_TO_DEVICE);
-   if (unlikely(dma_mapping_error(priv->dev, map))) {
-   /* drop packet */
-   if (net_ratelimit())
-   netdev_err(netdev, "map socket buffer failed\n");
-
-   netdev->stats.tx_dropped++;
-   kfree_skb(skb);
-   return NETDEV_TX_OK;
-   }
-
-   return ftgmac100_xmit(priv, skb, map);
-}
-
 /* optional */
 static int ftgmac100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, 
int cmd)
 {
-- 
2.9.3



[PATCH v2 10/12] ftgmac100: Don't clear tx desc fields unnecessarily

2017-04-09 Thread Benjamin Herrenschmidt
Those are non-cachable stores, let's avoid those we don't need. Remove
the helper, it's not particularly helpful and since it uses "priv"
I can't move it to the header file.

Signed-off-by: Benjamin Herrenschmidt 
---
 drivers/net/ethernet/faraday/ftgmac100.c | 17 ++---
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/faraday/ftgmac100.c 
b/drivers/net/ethernet/faraday/ftgmac100.c
index b33de5c..8a44c22 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -466,16 +466,6 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, 
int *processed)
return true;
 }
 
-static void ftgmac100_txdes_reset(const struct ftgmac100 *priv,
- struct ftgmac100_txdes *txdes)
-{
-   /* clear all except end of ring bit */
-   txdes->txdes0 &= cpu_to_le32(priv->txdes0_edotr_mask);
-   txdes->txdes1 = 0;
-   txdes->txdes2 = 0;
-   txdes->txdes3 = 0;
-}
-
 static bool ftgmac100_txdes_owned_by_dma(struct ftgmac100_txdes *txdes)
 {
return txdes->txdes0 & cpu_to_le32(FTGMAC100_TXDES0_TXDMA_OWN);
@@ -575,7 +565,12 @@ static void ftgmac100_free_tx_packet(struct ftgmac100 
*priv,
dev_kfree_skb(skb);
priv->tx_skbs[pointer] = NULL;
 
-   ftgmac100_txdes_reset(priv, txdes);
+   /* Clear txdes0 except end of ring bit, clear txdes1 as we
+* only "OR" into it, leave 2 and 3 alone as 2 is unused
+* and 3 will be overwritten entirely
+*/
+   txdes->txdes0 &= cpu_to_le32(priv->txdes0_edotr_mask);
+   txdes->txdes1 = 0;
 }
 
 static bool ftgmac100_tx_complete_packet(struct ftgmac100 *priv)
-- 
2.9.3



[PATCH v2 03/12] ftgmac100: Merge ftgmac100_xmit() into ftgmac100_hard_start_xmit()

2017-04-09 Thread Benjamin Herrenschmidt
This will make subsequent rework of the tx path simpler

Signed-off-by: Benjamin Herrenschmidt 
---
 drivers/net/ethernet/faraday/ftgmac100.c | 58 ++--
 1 file changed, 25 insertions(+), 33 deletions(-)

diff --git a/drivers/net/ethernet/faraday/ftgmac100.c 
b/drivers/net/ethernet/faraday/ftgmac100.c
index 21df322..a5bab0d 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -627,12 +627,33 @@ static void ftgmac100_tx_complete(struct ftgmac100 *priv)
;
 }
 
-static int ftgmac100_xmit(struct ftgmac100 *priv, struct sk_buff *skb,
- dma_addr_t map)
+static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
+struct net_device *netdev)
 {
-   struct net_device *netdev = priv->netdev;
-   struct ftgmac100_txdes *txdes;
unsigned int len = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;
+   struct ftgmac100 *priv = netdev_priv(netdev);
+   struct ftgmac100_txdes *txdes;
+   dma_addr_t map;
+
+   if (unlikely(skb->len > MAX_PKT_SIZE)) {
+   if (net_ratelimit())
+   netdev_dbg(netdev, "tx packet too big\n");
+
+   netdev->stats.tx_dropped++;
+   kfree_skb(skb);
+   return NETDEV_TX_OK;
+   }
+
+   map = dma_map_single(priv->dev, skb->data, skb_headlen(skb), 
DMA_TO_DEVICE);
+   if (unlikely(dma_mapping_error(priv->dev, map))) {
+   /* drop packet */
+   if (net_ratelimit())
+   netdev_err(netdev, "map socket buffer failed\n");
+
+   netdev->stats.tx_dropped++;
+   kfree_skb(skb);
+   return NETDEV_TX_OK;
+   }
 
txdes = ftgmac100_current_txdes(priv);
ftgmac100_tx_pointer_advance(priv);
@@ -673,35 +694,6 @@ static int ftgmac100_xmit(struct ftgmac100 *priv, struct 
sk_buff *skb,
return NETDEV_TX_OK;
 }
 
-static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
-struct net_device *netdev)
-{
-   struct ftgmac100 *priv = netdev_priv(netdev);
-   dma_addr_t map;
-
-   if (unlikely(skb->len > MAX_PKT_SIZE)) {
-   if (net_ratelimit())
-   netdev_dbg(netdev, "tx packet too big\n");
-
-   netdev->stats.tx_dropped++;
-   kfree_skb(skb);
-   return NETDEV_TX_OK;
-   }
-
-   map = dma_map_single(priv->dev, skb->data, skb_headlen(skb), 
DMA_TO_DEVICE);
-   if (unlikely(dma_mapping_error(priv->dev, map))) {
-   /* drop packet */
-   if (net_ratelimit())
-   netdev_err(netdev, "map socket buffer failed\n");
-
-   netdev->stats.tx_dropped++;
-   kfree_skb(skb);
-   return NETDEV_TX_OK;
-   }
-
-   return ftgmac100_xmit(priv, skb, map);
-}
-
 static void ftgmac100_free_buffers(struct ftgmac100 *priv)
 {
int i;
-- 
2.9.3



[PATCH v2 04/12] ftgmac100: Factor tx packet dropping path

2017-04-09 Thread Benjamin Herrenschmidt
Use a simple goto to a drop path at the tail of the function,
it will be used in a few more cases soon

Signed-off-by: Benjamin Herrenschmidt 
---
 drivers/net/ethernet/faraday/ftgmac100.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/faraday/ftgmac100.c 
b/drivers/net/ethernet/faraday/ftgmac100.c
index a5bab0d..84ae800 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -638,10 +638,7 @@ static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
if (unlikely(skb->len > MAX_PKT_SIZE)) {
if (net_ratelimit())
netdev_dbg(netdev, "tx packet too big\n");
-
-   netdev->stats.tx_dropped++;
-   kfree_skb(skb);
-   return NETDEV_TX_OK;
+   goto drop;
}
 
map = dma_map_single(priv->dev, skb->data, skb_headlen(skb), 
DMA_TO_DEVICE);
@@ -649,10 +646,7 @@ static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
/* drop packet */
if (net_ratelimit())
netdev_err(netdev, "map socket buffer failed\n");
-
-   netdev->stats.tx_dropped++;
-   kfree_skb(skb);
-   return NETDEV_TX_OK;
+   goto drop;
}
 
txdes = ftgmac100_current_txdes(priv);
@@ -692,6 +686,13 @@ static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
ftgmac100_txdma_normal_prio_start_polling(priv);
 
return NETDEV_TX_OK;
+
+ drop:
+   /* Drop the packet */
+   dev_kfree_skb_any(skb);
+   netdev->stats.tx_dropped++;
+
+   return NETDEV_TX_OK;
 }
 
 static void ftgmac100_free_buffers(struct ftgmac100 *priv)
-- 
2.9.3



RE: IMX6 FEC connection drops occasionally with 'MDIO read timeout'

2017-04-09 Thread Andy Duan
From: Tim Harvey  Sent: Friday, April 07, 2017 10:47 PM
>To: netdev 
>Cc: Fabio Estevam ; Lucas Stach
>; Andy Duan ; Koen
>Vandeputte 
>Subject: IMX6 FEC connection drops occasionally with 'MDIO read timeout'
>
>Greetings,
>
>I've had a couple of users report that they are getting occasional link drops
>when using IMX6 FEC on our boards which are using a Marvell
>88E1510 PHY:
>
>[ 9348.474418] fec 2188000.ethernet eth0: MDIO read timeout [ 9350.478804]
>fec 2188000.ethernet eth0: Link is Down
>
>If they bring the interface back up it works fine.
>
>The most recent version of Linux they have tested and seen this on is
>v4.9 with CONFIG_MARVELL_PHY=y
>
>Has anyone else run into this or know what the issue could be? Should there
>be any retries at the MDIO level or above?
>
>Regards,
>
>Tim

Pls keep ipg clock always on and try it.
In general, MDIO timeout maybe caused by ipg clock off and mii interrupt lost. 


Regards,
Andy


Re: [PATCH net-next] net: dsa: mt7530: Include gpio/consumer.h for GPIO functions

2017-04-09 Thread David Miller
From: Florian Fainelli 
Date: Sat,  8 Apr 2017 08:52:02 -0700

> Fixes build errors seen with CONFIG_GPIOLIB disabled and warnings enabled:
 ...
> Fixes: b8f126a8d543 ("net-next: dsa: add dsa support for Mediatek MT7530 
> switch")
> Signed-off-by: Florian Fainelli 

Applied, thanks Florian.


Re: [PATCH net] tcp: clear saved_syn in tcp_disconnect()

2017-04-09 Thread David Miller
From: Eric Dumazet 
Date: Sat, 08 Apr 2017 08:07:33 -0700

> From: Eric Dumazet 
> 
> In the (very unlikely) case a passive socket becomes a listener,
> we do not want to duplicate its saved SYN headers.
> 
> This would lead to double frees, use after free, and please hackers and
> various fuzzers 
> 
> Tested:
 ...
> Fixes: cd8ae85299d5 ("tcp: provide SYN headers for passive connections")
> Signed-off-by: Eric Dumazet 

Applied, thanks Eric.


Re: [PATCH net-next] bpf: fix comment typo

2017-04-09 Thread David Miller
From: Alexander Alemayhu 
Date: Sat,  8 Apr 2017 22:08:10 +0200

> o s/bpf_bpf_get_socket_cookie/bpf_get_socket_cookie
> 
> Signed-off-by: Alexander Alemayhu 

Applied.


Re: [PATCH v2 1/2] bpf: remove struct bpf_prog_type_list

2017-04-09 Thread David Miller
From: Johannes Berg 
Date: Fri,  7 Apr 2017 21:00:07 +0200

> From: Johannes Berg 
> 
> There's no need to have struct bpf_prog_type_list since
> it just contains a list_head, the type, and the ops
> pointer. Since the types are densely packed and not
> actually dynamically registered, it's much easier and
> smaller to have an array of type->ops pointer. Also
> initialize this array statically to remove code needed
> to initialize it.
> 
> Signed-off-by: Johannes Berg 

If you just don't want to list things multiple times how about:

linux/bpf_verifiers.h:
BPF_VERIFIER(BPF_PROG_TYPE_SOCKET_FILTER, sk_filter_prog_ops)
BPF_VERIFIER(BPF_PROG_TYPE_SCHED_CLS, tc_cls_prog_ops)
 ...

Then in bpf.h:

#define BPF_VERIFIER(TYPE_VAL, SYM) extern const struct bpf_verifier_ops SYM;
#include 

[PATCH v2 11/12] ftgmac100: Add support for fragmented tx

2017-04-09 Thread Benjamin Herrenschmidt
Add NETIF_F_SG and create multiple TX ring entries for skb fragments.

On reclaim, the skb is only freed on the segment marked as "last".

Signed-off-by: Benjamin Herrenschmidt 
--

v2. - Remove skb headlen size adjustments now that we use
  eth_skb_pad().
---
 drivers/net/ethernet/faraday/ftgmac100.c | 119 ---
 1 file changed, 94 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/faraday/ftgmac100.c 
b/drivers/net/ethernet/faraday/ftgmac100.c
index 8a44c22..2a4d903 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -45,7 +45,7 @@
 #define RX_BUF_SIZEMAX_PKT_SIZE/* must be smaller than 0x3fff 
*/
 
 /* Min number of tx ring entries before stopping queue */
-#define TX_THRESHOLD   (1)
+#define TX_THRESHOLD   (MAX_SKB_FRAGS + 1)
 
 struct ftgmac100_descs {
struct ftgmac100_rxdes rxdes[RX_QUEUE_ENTRIES];
@@ -487,20 +487,30 @@ static void ftgmac100_txdes_set_first_segment(struct 
ftgmac100_txdes *txdes)
txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_FTS);
 }
 
+static inline bool ftgmac100_txdes_get_first_segment(struct ftgmac100_txdes 
*txdes)
+{
+   return (txdes->txdes0 & cpu_to_le32(FTGMAC100_TXDES0_FTS)) != 0;
+}
+
 static void ftgmac100_txdes_set_last_segment(struct ftgmac100_txdes *txdes)
 {
txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_LTS);
 }
 
+static inline bool ftgmac100_txdes_get_last_segment(struct ftgmac100_txdes 
*txdes)
+{
+   return (txdes->txdes0 & cpu_to_le32(FTGMAC100_TXDES0_LTS)) != 0;
+}
+
 static void ftgmac100_txdes_set_buffer_size(struct ftgmac100_txdes *txdes,
unsigned int len)
 {
txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_TXBUF_SIZE(len));
 }
 
-static void ftgmac100_txdes_set_txint(struct ftgmac100_txdes *txdes)
+static inline unsigned int ftgmac100_txdes_get_buffer_size(struct 
ftgmac100_txdes *txdes)
 {
-   txdes->txdes1 |= cpu_to_le32(FTGMAC100_TXDES1_TXIC);
+   return FTGMAC100_TXDES0_TXBUF_SIZE(cpu_to_le32(txdes->txdes0));
 }
 
 static void ftgmac100_txdes_set_tcpcs(struct ftgmac100_txdes *txdes)
@@ -526,7 +536,7 @@ static void ftgmac100_txdes_set_dma_addr(struct 
ftgmac100_txdes *txdes,
 
 static dma_addr_t ftgmac100_txdes_get_dma_addr(struct ftgmac100_txdes *txdes)
 {
-   return le32_to_cpu(txdes->txdes3);
+   return (dma_addr_t)le32_to_cpu(txdes->txdes3);
 }
 
 static int ftgmac100_next_tx_pointer(int pointer)
@@ -556,13 +566,19 @@ static void ftgmac100_free_tx_packet(struct ftgmac100 
*priv,
 struct sk_buff *skb,
 struct ftgmac100_txdes *txdes)
 {
-   dma_addr_t map;
+   dma_addr_t map = ftgmac100_txdes_get_dma_addr(txdes);
 
-   map = ftgmac100_txdes_get_dma_addr(txdes);
-
-   dma_unmap_single(priv->dev, map, skb_headlen(skb), DMA_TO_DEVICE);
+   if (ftgmac100_txdes_get_first_segment(txdes)) {
+   dma_unmap_single(priv->dev, map, skb_headlen(skb),
+DMA_TO_DEVICE);
+   } else {
+   dma_unmap_page(priv->dev, map,
+  ftgmac100_txdes_get_buffer_size(txdes),
+  DMA_TO_DEVICE);
+   }
 
-   dev_kfree_skb(skb);
+   if (ftgmac100_txdes_get_last_segment(txdes))
+   dev_kfree_skb(skb);
priv->tx_skbs[pointer] = NULL;
 
/* Clear txdes0 except end of ring bit, clear txdes1 as we
@@ -624,8 +640,8 @@ static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
 struct net_device *netdev)
 {
struct ftgmac100 *priv = netdev_priv(netdev);
-   struct ftgmac100_txdes *txdes;
-   unsigned int pointer;
+   struct ftgmac100_txdes *txdes, *first;
+   unsigned int pointer, nfrags, len, i, j;
dma_addr_t map;
 
/* The HW doesn't pad small frames */
@@ -641,26 +657,33 @@ static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
goto drop;
}
 
-   map = dma_map_single(priv->dev, skb->data, skb_headlen(skb), 
DMA_TO_DEVICE);
-   if (unlikely(dma_mapping_error(priv->dev, map))) {
-   /* drop packet */
+   /* Do we have a limit on #fragments ? I yet have to get a reply
+* from Aspeed. If there's one I haven't hit it.
+*/
+   nfrags = skb_shinfo(skb)->nr_frags;
+
+   /* Get header len */
+   len = skb_headlen(skb);
+
+   /* Map the packet head */
+   map = dma_map_single(priv->dev, skb->data, len, DMA_TO_DEVICE);
+   if (dma_mapping_error(priv->dev, map)) {
if (net_ratelimit())
-   netdev_err(netdev, "map socket buffer failed\n");
+   netdev_err(netdev, "map tx packet head failed\n");
goto drop;
}
 
/* Grab the next free tx descriptor */
pointer = priv->tx_pointer;
-   txdes 

[PATCH v2 07/12] ftgmac100: Cleanup tx queue handling

2017-04-09 Thread Benjamin Herrenschmidt
We have a private lock which isn't terribly useful, and we maintain
a "tx_pending" counter for information that's already available
via a trivial arithmetic operation. Then we unconditionaly wake
the queue even when not stopped. Finally our code in tx isn't
really safe vs. a concurrent reclaim. The aspeed chips aren't SMP
today but I prefer the code being right and future proof.

So rip that out and replace it with more "standard" queue handling,
currently with a threshold of 1 queue element, which will be
increased when we implement fragmented sends.

Signed-off-by: Benjamin Herrenschmidt 
---
 drivers/net/ethernet/faraday/ftgmac100.c | 103 ---
 1 file changed, 68 insertions(+), 35 deletions(-)

diff --git a/drivers/net/ethernet/faraday/ftgmac100.c 
b/drivers/net/ethernet/faraday/ftgmac100.c
index 8d85f1d..8078d65 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -44,6 +44,9 @@
 #define MAX_PKT_SIZE   1536
 #define RX_BUF_SIZEMAX_PKT_SIZE/* must be smaller than 0x3fff 
*/
 
+/* Min number of tx ring entries before stopping queue */
+#define TX_THRESHOLD   (1)
+
 struct ftgmac100_descs {
struct ftgmac100_rxdes rxdes[RX_QUEUE_ENTRIES];
struct ftgmac100_txdes txdes[TX_QUEUE_ENTRIES];
@@ -66,9 +69,7 @@ struct ftgmac100 {
struct sk_buff *tx_skbs[TX_QUEUE_ENTRIES];
unsigned int tx_clean_pointer;
unsigned int tx_pointer;
-   unsigned int tx_pending;
u32 txdes0_edotr_mask;
-   spinlock_t tx_lock;
 
/* Scratch page to use when rx skb alloc fails */
void *rx_scratch;
@@ -163,7 +164,6 @@ static int ftgmac100_reset_and_config_mac(struct ftgmac100 
*priv)
priv->rx_pointer = 0;
priv->tx_clean_pointer = 0;
priv->tx_pointer = 0;
-   priv->tx_pending = 0;
 
/* The doc says reset twice with 10us interval */
if (ftgmac100_reset_mac(priv, maccr))
@@ -549,6 +549,23 @@ static int ftgmac100_next_tx_pointer(int pointer)
return (pointer + 1) & (TX_QUEUE_ENTRIES - 1);
 }
 
+static u32 ftgmac100_tx_buf_avail(struct ftgmac100 *priv)
+{
+   /* Returns the number of available slots in the TX queue
+*
+* This always leaves one free slot so we don't have to
+* worry about empty vs. full, and this simplifies the
+* test for ftgmac100_tx_buf_cleanable() below
+*/
+   return (priv->tx_clean_pointer - priv->tx_pointer - 1) &
+   (TX_QUEUE_ENTRIES - 1);
+}
+
+static bool ftgmac100_tx_buf_cleanable(struct ftgmac100 *priv)
+{
+   return priv->tx_pointer != priv->tx_clean_pointer;
+}
+
 static bool ftgmac100_tx_complete_packet(struct ftgmac100 *priv)
 {
struct net_device *netdev = priv->netdev;
@@ -557,9 +574,6 @@ static bool ftgmac100_tx_complete_packet(struct ftgmac100 
*priv)
struct sk_buff *skb;
dma_addr_t map;
 
-   if (priv->tx_pending == 0)
-   return false;
-
pointer = priv->tx_clean_pointer;
txdes = &priv->descs->txdes[pointer];
 
@@ -581,18 +595,31 @@ static bool ftgmac100_tx_complete_packet(struct ftgmac100 
*priv)
 
priv->tx_clean_pointer = ftgmac100_next_tx_pointer(pointer);
 
-   spin_lock(&priv->tx_lock);
-   priv->tx_pending--;
-   spin_unlock(&priv->tx_lock);
-   netif_wake_queue(netdev);
-
return true;
 }
 
 static void ftgmac100_tx_complete(struct ftgmac100 *priv)
 {
-   while (ftgmac100_tx_complete_packet(priv))
+   struct net_device *netdev = priv->netdev;
+
+   /* Process all completed packets */
+   while (ftgmac100_tx_buf_cleanable(priv) &&
+  ftgmac100_tx_complete_packet(priv))
;
+
+   /* Restart queue if needed */
+   smp_mb();
+   if (unlikely(netif_queue_stopped(netdev) &&
+ftgmac100_tx_buf_avail(priv) >= TX_THRESHOLD)) {
+   struct netdev_queue *txq;
+
+   txq = netdev_get_tx_queue(netdev, 0);
+   __netif_tx_lock(txq, smp_processor_id());
+   if (netif_queue_stopped(netdev) &&
+   ftgmac100_tx_buf_avail(priv) >= TX_THRESHOLD)
+   netif_wake_queue(netdev);
+   __netif_tx_unlock(txq);
+   }
 }
 
 static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
@@ -650,17 +677,22 @@ static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
}
}
 
+   ftgmac100_txdes_set_dma_own(txdes);
+
/* Update next TX pointer */
priv->tx_pointer = ftgmac100_next_tx_pointer(pointer);
 
-   spin_lock(&priv->tx_lock);
-   priv->tx_pending++;
-   if (priv->tx_pending == TX_QUEUE_ENTRIES)
+   /* If there isn't enough room for all the fragments of a new packet
+* in the TX ring, stop the queue. The sequence below is race free
+* vs. a concurrent restart in ftgmac100_poll()
+*/
+   if (unlikely(ftgmac100_

[PATCH v2 06/12] ftgmac100: Store tx skbs in a separate array

2017-04-09 Thread Benjamin Herrenschmidt
Rather than in the descriptor. The descriptor is mapped non-cachable
and rather slow to access.

Since to do that we need to keep track of the tx "pointer" we also
have no use of all the accesors to manipulate it, just open code
it, it's as clear and will help when adding fragmented sends.

Signed-off-by: Benjamin Herrenschmidt 
---

v2. - Fix patch splitting mistake
---
 drivers/net/ethernet/faraday/ftgmac100.c | 59 +---
 1 file changed, 16 insertions(+), 43 deletions(-)

diff --git a/drivers/net/ethernet/faraday/ftgmac100.c 
b/drivers/net/ethernet/faraday/ftgmac100.c
index 739916d..8d85f1d 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -63,6 +63,7 @@ struct ftgmac100 {
u32 rxdes0_edorr_mask;
 
/* Tx ring */
+   struct sk_buff *tx_skbs[TX_QUEUE_ENTRIES];
unsigned int tx_clean_pointer;
unsigned int tx_pointer;
unsigned int tx_pending;
@@ -543,63 +544,29 @@ static dma_addr_t ftgmac100_txdes_get_dma_addr(struct 
ftgmac100_txdes *txdes)
return le32_to_cpu(txdes->txdes3);
 }
 
-/*
- * txdes2 is not used by hardware. We use it to keep track of socket buffer.
- * Since hardware does not touch it, we can skip cpu_to_le32()/le32_to_cpu().
- */
-static void ftgmac100_txdes_set_skb(struct ftgmac100_txdes *txdes,
-   struct sk_buff *skb)
-{
-   txdes->txdes2 = (unsigned int)skb;
-}
-
-static struct sk_buff *ftgmac100_txdes_get_skb(struct ftgmac100_txdes *txdes)
-{
-   return (struct sk_buff *)txdes->txdes2;
-}
-
 static int ftgmac100_next_tx_pointer(int pointer)
 {
return (pointer + 1) & (TX_QUEUE_ENTRIES - 1);
 }
 
-static void ftgmac100_tx_pointer_advance(struct ftgmac100 *priv)
-{
-   priv->tx_pointer = ftgmac100_next_tx_pointer(priv->tx_pointer);
-}
-
-static void ftgmac100_tx_clean_pointer_advance(struct ftgmac100 *priv)
-{
-   priv->tx_clean_pointer = 
ftgmac100_next_tx_pointer(priv->tx_clean_pointer);
-}
-
-static struct ftgmac100_txdes *ftgmac100_current_txdes(struct ftgmac100 *priv)
-{
-   return &priv->descs->txdes[priv->tx_pointer];
-}
-
-static struct ftgmac100_txdes *
-ftgmac100_current_clean_txdes(struct ftgmac100 *priv)
-{
-   return &priv->descs->txdes[priv->tx_clean_pointer];
-}
-
 static bool ftgmac100_tx_complete_packet(struct ftgmac100 *priv)
 {
struct net_device *netdev = priv->netdev;
struct ftgmac100_txdes *txdes;
+   unsigned int pointer;
struct sk_buff *skb;
dma_addr_t map;
 
if (priv->tx_pending == 0)
return false;
 
-   txdes = ftgmac100_current_clean_txdes(priv);
+   pointer = priv->tx_clean_pointer;
+   txdes = &priv->descs->txdes[pointer];
 
if (ftgmac100_txdes_owned_by_dma(txdes))
return false;
 
-   skb = ftgmac100_txdes_get_skb(txdes);
+   skb = priv->tx_skbs[pointer];
map = ftgmac100_txdes_get_dma_addr(txdes);
 
netdev->stats.tx_packets++;
@@ -608,10 +575,11 @@ static bool ftgmac100_tx_complete_packet(struct ftgmac100 
*priv)
dma_unmap_single(priv->dev, map, skb_headlen(skb), DMA_TO_DEVICE);
 
dev_kfree_skb(skb);
+   priv->tx_skbs[pointer] = NULL;
 
ftgmac100_txdes_reset(priv, txdes);
 
-   ftgmac100_tx_clean_pointer_advance(priv);
+   priv->tx_clean_pointer = ftgmac100_next_tx_pointer(pointer);
 
spin_lock(&priv->tx_lock);
priv->tx_pending--;
@@ -632,6 +600,7 @@ static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
 {
struct ftgmac100 *priv = netdev_priv(netdev);
struct ftgmac100_txdes *txdes;
+   unsigned int pointer;
dma_addr_t map;
 
/* The HW doesn't pad small frames */
@@ -655,11 +624,12 @@ static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
goto drop;
}
 
-   txdes = ftgmac100_current_txdes(priv);
-   ftgmac100_tx_pointer_advance(priv);
+   /* Grab the next free tx descriptor */
+   pointer = priv->tx_pointer;
+   txdes = &priv->descs->txdes[pointer];
 
/* setup TX descriptor */
-   ftgmac100_txdes_set_skb(txdes, skb);
+   priv->tx_skbs[pointer] = skb;
ftgmac100_txdes_set_dma_addr(txdes, map);
ftgmac100_txdes_set_buffer_size(txdes, skb->len);
 
@@ -680,6 +650,9 @@ static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
}
}
 
+   /* Update next TX pointer */
+   priv->tx_pointer = ftgmac100_next_tx_pointer(pointer);
+
spin_lock(&priv->tx_lock);
priv->tx_pending++;
if (priv->tx_pending == TX_QUEUE_ENTRIES)
@@ -722,7 +695,7 @@ static void ftgmac100_free_buffers(struct ftgmac100 *priv)
/* Free all TX buffers */
for (i = 0; i < TX_QUEUE_ENTRIES; i++) {
struct ftgmac100_txdes *txdes = &priv->descs->txdes[i];
-   struct sk_buff *skb = ftgmac100_txdes_get_skb(txdes);
+   struct sk_buff *

[PATCH v2 08/12] ftgmac100: Move the barrier out of ftgmac100_txdes_set_dma_own()

2017-04-09 Thread Benjamin Herrenschmidt
We'll use variants of this accessor without barriers when
building series of descriptors for fragmented sends

Signed-off-by: Benjamin Herrenschmidt 
---
 drivers/net/ethernet/faraday/ftgmac100.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/faraday/ftgmac100.c 
b/drivers/net/ethernet/faraday/ftgmac100.c
index 8078d65..bdec14f 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -483,11 +483,6 @@ static bool ftgmac100_txdes_owned_by_dma(struct 
ftgmac100_txdes *txdes)
 
 static void ftgmac100_txdes_set_dma_own(struct ftgmac100_txdes *txdes)
 {
-   /*
-* Make sure dma own bit will not be set before any other
-* descriptor fields.
-*/
-   wmb();
txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_TXDMA_OWN);
 }
 
@@ -677,6 +672,10 @@ static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
}
}
 
+   /* Order the previous packet and descriptor udpates
+* before setting the OWN bit.
+*/
+   dma_wmb();
ftgmac100_txdes_set_dma_own(txdes);
 
/* Update next TX pointer */
-- 
2.9.3



[PATCH v2 12/12] ftgmac100: Remove tx descriptor accessors

2017-04-09 Thread Benjamin Herrenschmidt
Directly access the fields when needed. The accessors add clutter
not clarity and in some cases cause unnecessary read-modify-write
type access on the slow (uncached) descriptor memory.

Signed-off-by: Benjamin Herrenschmidt 
---

v2. - Adjust for changes in previous patches
---
 drivers/net/ethernet/faraday/ftgmac100.c | 175 ---
 drivers/net/ethernet/faraday/ftgmac100.h |   8 +-
 2 files changed, 69 insertions(+), 114 deletions(-)

diff --git a/drivers/net/ethernet/faraday/ftgmac100.c 
b/drivers/net/ethernet/faraday/ftgmac100.c
index 2a4d903..98b8956 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -466,77 +466,13 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, 
int *processed)
return true;
 }
 
-static bool ftgmac100_txdes_owned_by_dma(struct ftgmac100_txdes *txdes)
+static u32 ftgmac100_base_tx_ctlstat(struct ftgmac100 *priv,
+unsigned int index)
 {
-   return txdes->txdes0 & cpu_to_le32(FTGMAC100_TXDES0_TXDMA_OWN);
-}
-
-static void ftgmac100_txdes_set_dma_own(struct ftgmac100_txdes *txdes)
-{
-   txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_TXDMA_OWN);
-}
-
-static void ftgmac100_txdes_set_end_of_ring(const struct ftgmac100 *priv,
-   struct ftgmac100_txdes *txdes)
-{
-   txdes->txdes0 |= cpu_to_le32(priv->txdes0_edotr_mask);
-}
-
-static void ftgmac100_txdes_set_first_segment(struct ftgmac100_txdes *txdes)
-{
-   txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_FTS);
-}
-
-static inline bool ftgmac100_txdes_get_first_segment(struct ftgmac100_txdes 
*txdes)
-{
-   return (txdes->txdes0 & cpu_to_le32(FTGMAC100_TXDES0_FTS)) != 0;
-}
-
-static void ftgmac100_txdes_set_last_segment(struct ftgmac100_txdes *txdes)
-{
-   txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_LTS);
-}
-
-static inline bool ftgmac100_txdes_get_last_segment(struct ftgmac100_txdes 
*txdes)
-{
-   return (txdes->txdes0 & cpu_to_le32(FTGMAC100_TXDES0_LTS)) != 0;
-}
-
-static void ftgmac100_txdes_set_buffer_size(struct ftgmac100_txdes *txdes,
-   unsigned int len)
-{
-   txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_TXBUF_SIZE(len));
-}
-
-static inline unsigned int ftgmac100_txdes_get_buffer_size(struct 
ftgmac100_txdes *txdes)
-{
-   return FTGMAC100_TXDES0_TXBUF_SIZE(cpu_to_le32(txdes->txdes0));
-}
-
-static void ftgmac100_txdes_set_tcpcs(struct ftgmac100_txdes *txdes)
-{
-   txdes->txdes1 |= cpu_to_le32(FTGMAC100_TXDES1_TCP_CHKSUM);
-}
-
-static void ftgmac100_txdes_set_udpcs(struct ftgmac100_txdes *txdes)
-{
-   txdes->txdes1 |= cpu_to_le32(FTGMAC100_TXDES1_UDP_CHKSUM);
-}
-
-static void ftgmac100_txdes_set_ipcs(struct ftgmac100_txdes *txdes)
-{
-   txdes->txdes1 |= cpu_to_le32(FTGMAC100_TXDES1_IP_CHKSUM);
-}
-
-static void ftgmac100_txdes_set_dma_addr(struct ftgmac100_txdes *txdes,
-dma_addr_t addr)
-{
-   txdes->txdes3 = cpu_to_le32(addr);
-}
-
-static dma_addr_t ftgmac100_txdes_get_dma_addr(struct ftgmac100_txdes *txdes)
-{
-   return (dma_addr_t)le32_to_cpu(txdes->txdes3);
+   if (index == (TX_QUEUE_ENTRIES - 1))
+   return priv->txdes0_edotr_mask;
+   else
+   return 0;
 }
 
 static int ftgmac100_next_tx_pointer(int pointer)
@@ -564,29 +500,24 @@ static bool ftgmac100_tx_buf_cleanable(struct ftgmac100 
*priv)
 static void ftgmac100_free_tx_packet(struct ftgmac100 *priv,
 unsigned int pointer,
 struct sk_buff *skb,
-struct ftgmac100_txdes *txdes)
+struct ftgmac100_txdes *txdes,
+u32 ctl_stat)
 {
-   dma_addr_t map = ftgmac100_txdes_get_dma_addr(txdes);
+   dma_addr_t map = le32_to_cpu(txdes->txdes3);
+   size_t len;
 
-   if (ftgmac100_txdes_get_first_segment(txdes)) {
-   dma_unmap_single(priv->dev, map, skb_headlen(skb),
-DMA_TO_DEVICE);
+   if (ctl_stat & FTGMAC100_TXDES0_FTS) {
+   len = skb_headlen(skb);
+   dma_unmap_single(priv->dev, map, len, DMA_TO_DEVICE);
} else {
-   dma_unmap_page(priv->dev, map,
-  ftgmac100_txdes_get_buffer_size(txdes),
-  DMA_TO_DEVICE);
+   len = FTGMAC100_TXDES0_TXBUF_SIZE(ctl_stat);
+   dma_unmap_page(priv->dev, map, len, DMA_TO_DEVICE);
}
 
-   if (ftgmac100_txdes_get_last_segment(txdes))
+   /* Free SKB on last segment */
+   if (ctl_stat & FTGMAC100_TXDES0_LTS)
dev_kfree_skb(skb);
priv->tx_skbs[pointer] = NULL;
-
-   /* Clear txdes0 except end of ring bit, clear txdes1 as we
-* only "OR" into it, leave 2 and 3 alone as 2 is unused
-   

[PATCH v2 09/12] ftgmac100: Split tx packet freeing from ftgmac100_tx_complete_packet()

2017-04-09 Thread Benjamin Herrenschmidt
This moves the packet freeing to a separate function
which is also used by ftgmac100_free_buffers() and will
be used more in the error path of fragmented sends.

Signed-off-by: Benjamin Herrenschmidt 
---
 drivers/net/ethernet/faraday/ftgmac100.c | 38 ++--
 1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/faraday/ftgmac100.c 
b/drivers/net/ethernet/faraday/ftgmac100.c
index bdec14f..b33de5c 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -561,13 +561,29 @@ static bool ftgmac100_tx_buf_cleanable(struct ftgmac100 
*priv)
return priv->tx_pointer != priv->tx_clean_pointer;
 }
 
+static void ftgmac100_free_tx_packet(struct ftgmac100 *priv,
+unsigned int pointer,
+struct sk_buff *skb,
+struct ftgmac100_txdes *txdes)
+{
+   dma_addr_t map;
+
+   map = ftgmac100_txdes_get_dma_addr(txdes);
+
+   dma_unmap_single(priv->dev, map, skb_headlen(skb), DMA_TO_DEVICE);
+
+   dev_kfree_skb(skb);
+   priv->tx_skbs[pointer] = NULL;
+
+   ftgmac100_txdes_reset(priv, txdes);
+}
+
 static bool ftgmac100_tx_complete_packet(struct ftgmac100 *priv)
 {
struct net_device *netdev = priv->netdev;
struct ftgmac100_txdes *txdes;
-   unsigned int pointer;
struct sk_buff *skb;
-   dma_addr_t map;
+   unsigned int pointer;
 
pointer = priv->tx_clean_pointer;
txdes = &priv->descs->txdes[pointer];
@@ -576,17 +592,9 @@ static bool ftgmac100_tx_complete_packet(struct ftgmac100 
*priv)
return false;
 
skb = priv->tx_skbs[pointer];
-   map = ftgmac100_txdes_get_dma_addr(txdes);
-
netdev->stats.tx_packets++;
netdev->stats.tx_bytes += skb->len;
-
-   dma_unmap_single(priv->dev, map, skb_headlen(skb), DMA_TO_DEVICE);
-
-   dev_kfree_skb(skb);
-   priv->tx_skbs[pointer] = NULL;
-
-   ftgmac100_txdes_reset(priv, txdes);
+   ftgmac100_free_tx_packet(priv, pointer, skb, txdes);
 
priv->tx_clean_pointer = ftgmac100_next_tx_pointer(pointer);
 
@@ -727,13 +735,9 @@ static void ftgmac100_free_buffers(struct ftgmac100 *priv)
for (i = 0; i < TX_QUEUE_ENTRIES; i++) {
struct ftgmac100_txdes *txdes = &priv->descs->txdes[i];
struct sk_buff *skb = priv->tx_skbs[i];
-   dma_addr_t map = ftgmac100_txdes_get_dma_addr(txdes);
-
-   if (!skb)
-   continue;
 
-   dma_unmap_single(priv->dev, map, skb_headlen(skb), 
DMA_TO_DEVICE);
-   kfree_skb(skb);
+   if (skb)
+   ftgmac100_free_tx_packet(priv, i, skb, txdes);
}
 }
 
-- 
2.9.3



[PATCH v2 05/12] ftgmac100: Pad small frames properly

2017-04-09 Thread Benjamin Herrenschmidt
Rather than just transmitting garbage past the end of the small
packet.

Signed-off-by: Benjamin Herrenschmidt 
--

v2. Use eth_skb_pad (wrapper around skb_put_padto)
---
 drivers/net/ethernet/faraday/ftgmac100.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/faraday/ftgmac100.c 
b/drivers/net/ethernet/faraday/ftgmac100.c
index 84ae800..739916d 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -630,11 +630,17 @@ static void ftgmac100_tx_complete(struct ftgmac100 *priv)
 static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
 struct net_device *netdev)
 {
-   unsigned int len = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;
struct ftgmac100 *priv = netdev_priv(netdev);
struct ftgmac100_txdes *txdes;
dma_addr_t map;
 
+   /* The HW doesn't pad small frames */
+   if (eth_skb_pad(skb)) {
+   netdev->stats.tx_dropped++;
+   return NETDEV_TX_OK;
+   }
+
+   /* Reject oversize packets */
if (unlikely(skb->len > MAX_PKT_SIZE)) {
if (net_ratelimit())
netdev_dbg(netdev, "tx packet too big\n");
@@ -655,7 +661,7 @@ static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
/* setup TX descriptor */
ftgmac100_txdes_set_skb(txdes, skb);
ftgmac100_txdes_set_dma_addr(txdes, map);
-   ftgmac100_txdes_set_buffer_size(txdes, len);
+   ftgmac100_txdes_set_buffer_size(txdes, skb->len);
 
ftgmac100_txdes_set_first_segment(txdes);
ftgmac100_txdes_set_last_segment(txdes);
-- 
2.9.3



[PATCH v2 01/12] ftgmac100: Add a tx timeout handler

2017-04-09 Thread Benjamin Herrenschmidt
We have a reset task to reset our chip, use it.

Signed-off-by: Benjamin Herrenschmidt 
---
 drivers/net/ethernet/faraday/ftgmac100.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/net/ethernet/faraday/ftgmac100.c 
b/drivers/net/ethernet/faraday/ftgmac100.c
index 9f18e5e..f4b719214 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -1248,6 +1248,17 @@ static int ftgmac100_do_ioctl(struct net_device *netdev, 
struct ifreq *ifr, int
return phy_mii_ioctl(netdev->phydev, ifr, cmd);
 }
 
+static void ftgmac100_tx_timeout(struct net_device *netdev)
+{
+   struct ftgmac100 *priv = netdev_priv(netdev);
+
+   /* Disable all interrupts */
+   iowrite32(0, priv->base + FTGMAC100_OFFSET_IER);
+
+   /* Do the reset outside of interrupt context */
+   schedule_work(&priv->reset_task);
+}
+
 static const struct net_device_ops ftgmac100_netdev_ops = {
.ndo_open   = ftgmac100_open,
.ndo_stop   = ftgmac100_stop,
@@ -1255,6 +1266,7 @@ static const struct net_device_ops ftgmac100_netdev_ops = 
{
.ndo_set_mac_address= ftgmac100_set_mac_addr,
.ndo_validate_addr  = eth_validate_addr,
.ndo_do_ioctl   = ftgmac100_do_ioctl,
+   .ndo_tx_timeout = ftgmac100_tx_timeout,
 };
 
 static int ftgmac100_setup_mdio(struct net_device *netdev)
@@ -1359,6 +1371,7 @@ static int ftgmac100_probe(struct platform_device *pdev)
 
netdev->ethtool_ops = &ftgmac100_ethtool_ops;
netdev->netdev_ops = &ftgmac100_netdev_ops;
+   netdev->watchdog_timeo = 5 * HZ;
 
platform_set_drvdata(pdev, netdev);
 
-- 
2.9.3



[PATCH v2 00/12] ftgmac100: Rework batch 3 - TX path

2017-04-09 Thread Benjamin Herrenschmidt
This is version 2 of the third batch of updates to
the ftgmac100 driver.

This one tackles the TX path of the driver. This provides the
bulk of the performance improvements by adding support for
fragmented sends along with a bunch of cleanups.

Version 2 fixes a patch splitting mistake and uses
eth_skb_pad() (which uses skb_put_padto) to pad ethernet
frames rather than skb_padto(), thus removing the need to
also pad the packet headlen in a couple of places. 

Subsequent batches will add various features (ethtool functions,
vlan offlan, ...) and cleanups.



Re: pull-request: wireless-drivers-next 2017-04-07

2017-04-09 Thread David Miller
From: Kalle Valo 
Date: Fri, 07 Apr 2017 17:36:39 +0300

> here's a pull request for net-next, more info in the signed tag below.
> Please let me know if there are any problems.

Pulled, thanks Kalle.


Re: [PATCH v3 iproute] ip: Add support for netdev events to monitor

2017-04-09 Thread David Miller
From: David Ahern 
Date: Sat, 8 Apr 2017 22:54:07 -0400

> On 4/8/17 10:33 PM, David Miller wrote:
>> From: David Ahern 
>> Date: Sat, 8 Apr 2017 18:24:06 -0400
>> 
>>> per comments on the email thread about reducing notifications, the
>>> kernel patch for this should be reverted (and hence this iproute2 patch
>>> is not needed) in favor of using a bitmask. Right now there are too many
>>> redundant notifications to userspace.
>> 
>> I must have missed something in all the discussion, which patch needs
>> to be reverted from my tree exactly?
>> 
> 
> Here's the thread:
> https://www.spinics.net/lists/netdev/msg429154.html
> 
> The comment is that def12888c161 is adding a uapi that leads to way too
> many notifications (e.g., on a setlink).
> 
> It would be more efficient (read less notifications) to have do_setlink
> emit a single message with the IFLA_EVENT (or something else
> appropriately named) that indicates what attributes changed. Right now,
> a change MTU leads to 3 notifications causing unnecessary churn in
> userspace to track what the state of the link is.

Ok, I'll queue up the revert.  I guess this means your rtnetlink
patch set is going to need changes or a respin, therefore.


Re: [PATCH net-next 1/7] ibmvnic: Add is_up flag to avoid transmits when driver is down

2017-04-09 Thread David Miller
From: Nathan Fontenot 
Date: Sun, 09 Apr 2017 00:11:32 -0400

> From: Thomas Falcon 
> 
> There are brief windows when handling events such as failover where we
> could attempt to transmit packets between receiving the transport event
> notification and handling the reset in the workqueue.
> 
> This patch introduces an is_up flag so we can avoid transmit attempts at
> these times.
> 
> Signed-off-by: Thomas Falcon 
> Signed-off-by: Nathan Fontenot 

Simply stop the netdev queue when the device is in this state.
The kernel will stop queueing packets to the device if you do
that.

Please do not add unnecessary extra state and logic for this,
it doesn't appear to be necessary.

Thank you.


Re: [net-next 00/12][pull request] 40GbE Intel Wired LAN Driver Updates 2017-04-08

2017-04-09 Thread David Miller
From: Jeff Kirsher 
Date: Sat,  8 Apr 2017 02:55:41 -0700

> This series contains updates to i40e and i40evf only.

Pulled, thanks Jeff.


[PATCH v2 net-next RFC] Generic XDP

2017-04-09 Thread David Miller

This provides a generic non-optimized XDP implementation when the
device driver does not provide an optimized one.

It is arguable that perhaps I should have required something like
this as part of the initial XDP feature merge.

I believe this is critical for two reasons:

1) Accessibility.  More people can play with XDP with less
   dependencies.  Yes I know we have XDP support in virtio_net, but
   that just creates another depedency for learning how to use this
   facility.

   I wrote this to make life easier for the XDP newbies.

2) As a model for what the expected semantics are.  If there is a pure
   generic core implementation, it serves as a semantic example for
   driver folks adding XDP support.

This is just a rough draft and is untested.

Signed-off-by: David S. Miller 
---

v2:
 - Add some "fall through" comments in switch statements based
   upon feedback from Andrew Lunn
 - Use RCU for generic xdp_prog, thanks to Johannes Berg.

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index cc07c3b..f8ff49c 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1892,6 +1892,7 @@ struct net_device {
struct lock_class_key   *qdisc_tx_busylock;
struct lock_class_key   *qdisc_running_key;
boolproto_down;
+   struct bpf_prog __rcu   *xdp_prog;
 };
 #define to_net_dev(d) container_of(d, struct net_device, dev)
 
diff --git a/net/core/dev.c b/net/core/dev.c
index 7efb417..ad6de2d 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -95,6 +95,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -4247,6 +4248,83 @@ static int __netif_receive_skb(struct sk_buff *skb)
return ret;
 }
 
+static struct static_key generic_xdp_needed __read_mostly;
+
+static int generic_xdp_install(struct net_device *dev, struct netdev_xdp *xdp)
+{
+   struct bpf_prog *new = xdp->prog;
+   int ret = 0;
+
+   switch (xdp->command) {
+   case XDP_SETUP_PROG: {
+   struct bpf_prog *old = rtnl_dereference(dev->xdp_prog);
+
+   rcu_assign_pointer(dev->xdp_prog, new);
+   if (old)
+   bpf_prog_put(old);
+
+   if (old && !new)
+   static_key_slow_dec(&generic_xdp_needed);
+   else if (new && !old)
+   static_key_slow_inc(&generic_xdp_needed);
+   break;
+   }
+
+   case XDP_QUERY_PROG:
+   xdp->prog_attached = !!rcu_access_pointer(dev->xdp_prog);
+   break;
+
+   default:
+   ret = -EINVAL;
+   break;
+   }
+
+   return ret;
+}
+
+static u32 netif_receive_generic_xdp(struct sk_buff *skb,
+struct bpf_prog *xdp_prog)
+{
+   struct xdp_buff xdp;
+   u32 act = XDP_DROP;
+   void *orig_data;
+   int hlen, off;
+
+   if (skb_linearize(skb))
+   goto do_drop;
+
+   hlen = skb_headlen(skb);
+   xdp.data = skb->data;
+   xdp.data_end = xdp.data + hlen;
+   xdp.data_hard_start = xdp.data - skb_headroom(skb);
+   orig_data = xdp.data;
+
+   act = bpf_prog_run_xdp(xdp_prog, &xdp);
+
+   off = xdp.data - orig_data;
+   if (off)
+   __skb_push(skb, off);
+
+   switch (act) {
+   case XDP_PASS:
+   case XDP_TX:
+   break;
+
+   default:
+   bpf_warn_invalid_xdp_action(act);
+   /* fall through */
+   case XDP_ABORTED:
+   trace_xdp_exception(skb->dev, xdp_prog, act);
+   /* fall through */
+   case XDP_DROP:
+   do_drop:
+   kfree_skb(skb);
+   break;
+   }
+
+   return act;
+}
+
 static int netif_receive_skb_internal(struct sk_buff *skb)
 {
int ret;
@@ -4258,6 +4336,21 @@ static int netif_receive_skb_internal(struct sk_buff 
*skb)
 
rcu_read_lock();
 
+   if (static_key_false(&generic_xdp_needed)) {
+   struct bpf_prog *xdp_prog = rcu_dereference(skb->dev->xdp_prog);
+
+   if (xdp_prog) {
+   u32 act = netif_receive_generic_xdp(skb, xdp_prog);
+
+   if (act != XDP_PASS) {
+   rcu_read_unlock();
+   if (act == XDP_TX)
+   dev_queue_xmit(skb);
+   return NET_RX_DROP;
+   }
+   }
+   }
+
 #ifdef CONFIG_RPS
if (static_key_false(&rps_needed)) {
struct rps_dev_flow voidflow, *rflow = &voidflow;
@@ -6718,6 +6811,7 @@ EXPORT_SYMBOL(dev_change_proto_down);
  */
 int dev_change_xdp_fd(struct net_device *dev, int fd, u32 flags)
 {
+   int (*xdp_op)(struct net_device *dev, struct netdev_xdp *xdp);
const struct net_device_ops *ops = dev->netdev_ops;
struct bpf_prog *prog = NULL;
struct netdev_xdp xdp;
@@ -6725,14 

Re: [PATCH net-next RFC] Generic XDP

2017-04-09 Thread David Miller
From: Johannes Berg 
Date: Sun, 09 Apr 2017 09:04:07 +0200

> On Sun, 2017-04-09 at 08:25 +0200, Johannes Berg wrote:
>> That would also let you use rcu_assign_pointer() which seems like the
>> right thing to do here, along with marking the xdp_prog pointer as
>> __rcu? That'd also let you use rcu_dereference() instead of
>> READ_ONCE() which seems like the better annotation?
> 
> Looks like drivers do it exactly this way too though.

Every driver does things differently.  For example bnxt_en (which I
largely based my patch upon) uses xchg(), whilst mlx4 uses RCU
operations.

It just goes to show why it's good to have a common implementation of
XDP like this.

> What I forgot: I guess we could make drivers use dev->xdp_prog after
> this, instead of having their own?

Yes, but we have to resolve xchg() vs. RCU in order for that to work.

When evaluating this, we have to keep in mind that drivers tend to
have an extra pointer to the XDP program in their per-queue
datastructures.  They do this for the purposes of locality of
refernece during packet processing.

Instinctively I agree with you that RCU should be the way to go so
for now I'll adjust my patch to do things that way.

Thanks.



Re: [PATCH net-next RFC] Generic XDP

2017-04-09 Thread David Miller
From: Andy Gospodarek 
Date: Sun, 9 Apr 2017 01:17:26 -0400

> I should be able to run this on Monday and see how the performance
> compares to the driver/native XDP case on some bnxt_en-based hardware.

Thanks in advance for testing Andy.


Re: [PATCH net-next RFC] Generic XDP

2017-04-09 Thread David Miller
From: Andrew Lunn 
Date: Sun, 9 Apr 2017 15:46:55 +0200

>> +switch (act) {
>> +case XDP_PASS:
>> +case XDP_TX:
>> +break;
>> +
>> +default:
>> +bpf_warn_invalid_xdp_action(act);
> 
> Hi David
> 
> You might want to put a /* fall through */ comment here, just to
> prevent newbies from submitting patches moving the default clause to
> the end.

Probably need two, ala:

default:
bpf_warn_invalid_xdp_action(act);
/* fall through */
case XDP_ABORTED:
trace_xdp_exception(skb->dev, xdp_prog, act);
/* fall through */
case XDP_DROP:
do_drop:
kfree_skb(skb);
break;

So that's what I've done.

Thanks!


Re: [PATCH 1/5] netlink: extended ACK reporting

2017-04-09 Thread David Ahern
On 4/8/17 2:40 PM, Jiri Pirko wrote:
> Sat, Apr 08, 2017 at 08:37:01PM CEST, johan...@sipsolutions.net wrote:
>> On Sat, 2017-04-08 at 20:34 +0200, Jiri Pirko wrote:
>>> nla_total_size(sizeof(u32));
 +  if (extack &&
 +  (extack->missing_attr || extack-
> bad_attr))
>>>
>>> Attr could be 0, right? I know that on the most of the places 0 is
>>> UNSPEC, but I'm pretty sure not everywhere.

perhaps I misunderstand something, but nla_parse suggests attribute type
can not be 0:

int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
  int len, const struct nla_policy *policy,
  struct netlink_ext_ack *extack)
{
...

nla_for_each_attr(nla, head, len, rem) {
u16 type = nla_type(nla);

if (type > 0 && type <= maxtype) {
...
tb[type] = (struct nlattr *)nla;
}
}


> Also, could you please attach a patch to iproute2 for example which
> would make use of this. I just want to make sure it clicks.

I have follow on patches to Johannes' set that plumbs extack for
rtnetlink doit function and iproute2. will send later.


Re: [PATCH net-next 0/1 v2] skbuff: Extend gso_type to unsigned int.

2017-04-09 Thread Alexey Dobriyan
>  struct skb_shared_info {
> + unsigned short  _unused;
>   unsigned char   nr_frags;

This makes _all_ fields to be accessed with offset, but if you move
padding down, at least ->nr_frags will enjoy clean and simple [R64]
addressing.

On allyesconfig-ish kernel:

before: +542 = 720-178
 after: -158 =  53-211 (negative, because 16-bit field became 32-bit)

You may want to add configurable redzone there instead of padding
if that what you want. 2 bytes is nothing.


Re: [PATCH] net: rfkill: gpio: Add OBDA8723 ACPI HID

2017-04-09 Thread Larry Finger

On 04/09/2017 07:11 AM, Marcel Holtmann wrote:

Hi Hans,


The OBDA8723 ACPI HID is used on quite a few Bay Trail based tablets
for bluetooth rfkill functionality.

Tested-by: russianneuroman...@ya.ru 
Signed-off-by: Hans de Goede 
---
net/rfkill/rfkill-gpio.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c
index 76c01cb..50ca65e 100644
--- a/net/rfkill/rfkill-gpio.c
+++ b/net/rfkill/rfkill-gpio.c
@@ -163,6 +163,7 @@ static int rfkill_gpio_remove(struct platform_device *pdev)
static const struct acpi_device_id rfkill_acpi_match[] = {
{ "BCM4752", RFKILL_TYPE_GPS },
{ "LNV4752", RFKILL_TYPE_GPS },
+   { "OBDA8723", RFKILL_TYPE_BLUETOOTH },
{ },
};


NAK. We are integrating these with hci_bcm.c or hci_intel.c drivers.


This is for the bluetooth side of the rtl8723bs driver which recently
(yesterday) got merged in into drivers/staging. Which still needs
hciattach from userspace. I completely agree that eventually we should
fix that. In the mean time it would be nice if we could carry this
one line patch to give people using the staging driver working bluetooth.


why are Bluetooth drivers in staging? I objected to them before. The only 
reason to have them in staging would be people being to lazy to clean things up.


The Bluetooth driver is not in staging. It is only the wifi part; however, 
having a driver for that hardware in the kernel makes it easier for users to 
handle the BT part of the device. As Hans stated, the current BT driver runs in 
userspace. Until we actually produce hci_rtk, having this one line patch will be 
helpful.


Larry



--
If I was stranded on an island and the only way to get off
the island was to make a pretty UI, I’d die there.

Linus Torvalds


Re: [PATCH 06/22] staging: rtl8723bs: Fix various errors in os_dep/ioctl_cfg80211.c

2017-04-09 Thread Larry Finger

On 04/09/2017 10:28 AM, Bastien Nocera wrote:

On Sat, 2017-04-08 at 11:07 -0500, Larry Finger wrote:

Smatch lists the following:

  CHECK   drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:470
rtw_cfg80211_ibss_indicate_connect() error: we previously assumed
'scanned' could be null (see line 466)
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:942
rtw_cfg80211_set_encryption() warn: inconsistent indenting
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:955
rtw_cfg80211_set_encryption() error: buffer overflow 'psecuritypriv-

dot11DefKey' 4 <= 4

drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:1017
rtw_cfg80211_set_encryption() error: buffer overflow 'padapter-

securitypriv.dot118021XGrpKey' 5 <= 5

drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:1216
cfg80211_rtw_set_default_key() warn: inconsistent indenting
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:2498
rtw_cfg80211_monitor_if_xmit_entry() error: we previously assumed
'skb' could be null (see line 2495)
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:2850
cfg80211_rtw_start_ap() warn: if statement not indented
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:2860
cfg80211_rtw_start_ap() warn: if statement not indented
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:3417
rtw_cfg80211_preinit_wiphy() warn: inconsistent indenting
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:3547
rtw_wdev_alloc() info: ignoring unreachable code.

The indenting warnings were fixed by simple white space changes.

The section where 'scanned' could be null required an immediate exit
from
the routine at that point. A similar fix was required where 'skb'
could be null.

The two buffer overflow errors were caused by off-by-one errors.
While
locating these problems, another one was found in
os_dep/ioctl_linux.c.


Could you please split those up into patches that fix one kind of
problem? Makes it easier to review.


These patches were merged earlier today. Thanks for the reviews.

Larry




Re: [PATCH 00/22] staging: rtl87232bs: Fix errors and warnings detected by Smatch

2017-04-09 Thread Bastien Nocera
On Sat, 2017-04-08 at 11:07 -0500, Larry Finger wrote:
> A number of routines have indenting, off by one, and possible usage
> while null warnings or errors listed by Smatch. This set of patches
> fix all but one of these, and it is in code that will be removed in a
> subsequent patch.
> 
> Signed-off-by: Larry Finger 

Feel free to add:
Reviewed-by: Bastien Nocera 
for all the patches I didn't directly comment on.

Cheers


Re: [PATCH 20/22] staging rtl8723bs: Fix indenting errors and an off-by-one mistake in core/rtw_mlme_ext.c

2017-04-09 Thread Bastien Nocera
On Sat, 2017-04-08 at 11:07 -0500, Larry Finger wrote:
> } else {
> -   for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
> +   for (pstat->aid = 1; pstat->aid < NUM_STA; pstat->aid++)
> if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
> break;

why not start at 0 and increment pstat->aid afterwards? Meh.


Re: [PATCH 16/22] staging: rtl8723bs: Fix some indenting problems and a potential data overrun

2017-04-09 Thread Bastien Nocera
On Sat, 2017-04-08 at 11:07 -0500, Larry Finger wrote:
> +   if (cam_id >= 0 && cam_id < 32)

Isn't there a constant we could use instead of hard-coding this?


Re: [PATCH 13/22] staging: rtl8723bs: Fix indenting mistake in core/rtw_ap.c

2017-04-09 Thread Bastien Nocera
On Sat, 2017-04-08 at 11:07 -0500, Larry Finger wrote:
> Fixing this requires changing the indentatikon of a long for loop.

Typo here.


Re: [PATCH 06/22] staging: rtl8723bs: Fix various errors in os_dep/ioctl_cfg80211.c

2017-04-09 Thread Bastien Nocera
On Sat, 2017-04-08 at 11:07 -0500, Larry Finger wrote:
> Smatch lists the following:
> 
>   CHECK   drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
> drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:470
> rtw_cfg80211_ibss_indicate_connect() error: we previously assumed
> 'scanned' could be null (see line 466)
> drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:942
> rtw_cfg80211_set_encryption() warn: inconsistent indenting
> drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:955
> rtw_cfg80211_set_encryption() error: buffer overflow 'psecuritypriv-
> >dot11DefKey' 4 <= 4
> drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:1017
> rtw_cfg80211_set_encryption() error: buffer overflow 'padapter-
> >securitypriv.dot118021XGrpKey' 5 <= 5
> drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:1216
> cfg80211_rtw_set_default_key() warn: inconsistent indenting
> drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:2498
> rtw_cfg80211_monitor_if_xmit_entry() error: we previously assumed
> 'skb' could be null (see line 2495)
> drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:2850
> cfg80211_rtw_start_ap() warn: if statement not indented
> drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:2860
> cfg80211_rtw_start_ap() warn: if statement not indented
> drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:3417
> rtw_cfg80211_preinit_wiphy() warn: inconsistent indenting
> drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:3547
> rtw_wdev_alloc() info: ignoring unreachable code.
> 
> The indenting warnings were fixed by simple white space changes.
> 
> The section where 'scanned' could be null required an immediate exit
> from
> the routine at that point. A similar fix was required where 'skb'
> could be null.
> 
> The two buffer overflow errors were caused by off-by-one errors.
> While
> locating these problems, another one was found in
> os_dep/ioctl_linux.c.

Could you please split those up into patches that fix one kind of
problem? Makes it easier to review.


Re: [PATCH net-next RFC] Generic XDP

2017-04-09 Thread Andrew Lunn
> + switch (act) {
> + case XDP_PASS:
> + case XDP_TX:
> + break;
> +
> + default:
> + bpf_warn_invalid_xdp_action(act);

Hi David

You might want to put a /* fall through */ comment here, just to
prevent newbies from submitting patches moving the default clause to
the end.

Andrew

> + case XDP_ABORTED:
> + trace_xdp_exception(skb->dev, xdp_prog, act);
> + case XDP_DROP:
> + do_drop:
> + kfree_skb(skb);
> + break;
> + }
> +
> + return act;
> +}


[PATCH net 1/1] net: tcp: Increase TCPABORTONLINGER when send RST by linger2 in keepalive timer

2017-04-09 Thread gfree . wind
From: Gao Feng 

It should increase TCPABORTONLINGER counter when send RST caused by
linger2 in keepalive timer.

Signed-off-by: Gao Feng 
---
 net/ipv4/tcp_timer.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index b2ab411..5c01f21 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -650,6 +650,8 @@ static void tcp_keepalive_timer (unsigned long data)
tcp_time_wait(sk, TCP_FIN_WAIT2, tmo);
goto out;
}
+   } else {
+   NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONLINGER);
}
tcp_send_active_reset(sk, GFP_ATOMIC);
goto death;
-- 
1.9.1






Re: [PATCH] net: rfkill: gpio: Add OBDA8723 ACPI HID

2017-04-09 Thread Marcel Holtmann
Hi Hans,

>>> The OBDA8723 ACPI HID is used on quite a few Bay Trail based tablets
>>> for bluetooth rfkill functionality.
>>> 
>>> Tested-by: russianneuroman...@ya.ru 
>>> Signed-off-by: Hans de Goede 
>>> ---
>>> net/rfkill/rfkill-gpio.c | 1 +
>>> 1 file changed, 1 insertion(+)
>>> 
>>> diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c
>>> index 76c01cb..50ca65e 100644
>>> --- a/net/rfkill/rfkill-gpio.c
>>> +++ b/net/rfkill/rfkill-gpio.c
>>> @@ -163,6 +163,7 @@ static int rfkill_gpio_remove(struct platform_device 
>>> *pdev)
>>> static const struct acpi_device_id rfkill_acpi_match[] = {
>>> { "BCM4752", RFKILL_TYPE_GPS },
>>> { "LNV4752", RFKILL_TYPE_GPS },
>>> +   { "OBDA8723", RFKILL_TYPE_BLUETOOTH },
>>> { },
>>> };
>> 
>> NAK. We are integrating these with hci_bcm.c or hci_intel.c drivers.
> 
> This is for the bluetooth side of the rtl8723bs driver which recently
> (yesterday) got merged in into drivers/staging. Which still needs
> hciattach from userspace. I completely agree that eventually we should
> fix that. In the mean time it would be nice if we could carry this
> one line patch to give people using the staging driver working bluetooth.

why are Bluetooth drivers in staging? I objected to them before. The only 
reason to have them in staging would be people being to lazy to clean things up.

Regards

Marcel



Re: [PATCH] net: netfilter: Replace explicit NULL comparisons

2017-04-09 Thread Liping Zhang
2017-04-09 16:26 GMT+08:00 Jan Engelhardt :
>
> On Sunday 2017-04-09 05:42, Arushi Singhal wrote:
>>On Sun, Apr 9, 2017 at 1:44 AM, Pablo Neira Ayuso  wrote:
>>  On Sat, Apr 08, 2017 at 08:21:56PM +0200, Jan Engelhardt wrote:
>>  > On Saturday 2017-04-08 19:21, Arushi Singhal wrote:
>>  >
>>  > >Replace explicit NULL comparison with ! operator to simplify code.
>>  >
>>  > I still wouldn't do this, for the same reason as before. Comparing to
>>  > NULL explicitly more or less gave an extra guarantee that the other
>>  > operand was also a pointer.
>>
>>  Arushi, where does it say in the coding style that this is prefered?
>>
>>This is reported by checkpatch.pl script.
>
> checkpatch has been controversial at times, like when people took the 80
> character limit way too literally. Changing pointer comparisons looks like
> another thing that is better left ignored.

Yes, I agree too. Converting the "if (p != NULL)" to "if (p)" like this seems
unnecessary.


Re: [PATCH] net: rfkill: gpio: Add OBDA8723 ACPI HID

2017-04-09 Thread Hans de Goede

Hi,

On 09-04-17 10:01, Marcel Holtmann wrote:

Hi Hans,


The OBDA8723 ACPI HID is used on quite a few Bay Trail based tablets
for bluetooth rfkill functionality.

Tested-by: russianneuroman...@ya.ru 
Signed-off-by: Hans de Goede 
---
net/rfkill/rfkill-gpio.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c
index 76c01cb..50ca65e 100644
--- a/net/rfkill/rfkill-gpio.c
+++ b/net/rfkill/rfkill-gpio.c
@@ -163,6 +163,7 @@ static int rfkill_gpio_remove(struct platform_device *pdev)
static const struct acpi_device_id rfkill_acpi_match[] = {
{ "BCM4752", RFKILL_TYPE_GPS },
{ "LNV4752", RFKILL_TYPE_GPS },
+   { "OBDA8723", RFKILL_TYPE_BLUETOOTH },
{ },
};


NAK. We are integrating these with hci_bcm.c or hci_intel.c drivers.


This is for the bluetooth side of the rtl8723bs driver which recently
(yesterday) got merged in into drivers/staging. Which still needs
hciattach from userspace. I completely agree that eventually we should
fix that. In the mean time it would be nice if we could carry this
one line patch to give people using the staging driver working bluetooth.

Regards,

Hans


Re: [PATCH] net: netfilter: Replace explicit NULL comparisons

2017-04-09 Thread Jan Engelhardt

On Sunday 2017-04-09 05:42, Arushi Singhal wrote:
>On Sun, Apr 9, 2017 at 1:44 AM, Pablo Neira Ayuso  wrote:
>  On Sat, Apr 08, 2017 at 08:21:56PM +0200, Jan Engelhardt wrote:
>  > On Saturday 2017-04-08 19:21, Arushi Singhal wrote:
>  >
>  > >Replace explicit NULL comparison with ! operator to simplify code.
>  >
>  > I still wouldn't do this, for the same reason as before. Comparing to
>  > NULL explicitly more or less gave an extra guarantee that the other
>  > operand was also a pointer.
>
>  Arushi, where does it say in the coding style that this is prefered? 
>
>This is reported by checkpatch.pl script.

checkpatch has been controversial at times, like when people took the 80
character limit way too literally. Changing pointer comparisons looks like
another thing that is better left ignored.


Re: [PATCH] net: rfkill: gpio: Add OBDA8723 ACPI HID

2017-04-09 Thread Marcel Holtmann
Hi Hans,

> The OBDA8723 ACPI HID is used on quite a few Bay Trail based tablets
> for bluetooth rfkill functionality.
> 
> Tested-by: russianneuroman...@ya.ru 
> Signed-off-by: Hans de Goede 
> ---
> net/rfkill/rfkill-gpio.c | 1 +
> 1 file changed, 1 insertion(+)
> 
> diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c
> index 76c01cb..50ca65e 100644
> --- a/net/rfkill/rfkill-gpio.c
> +++ b/net/rfkill/rfkill-gpio.c
> @@ -163,6 +163,7 @@ static int rfkill_gpio_remove(struct platform_device 
> *pdev)
> static const struct acpi_device_id rfkill_acpi_match[] = {
>   { "BCM4752", RFKILL_TYPE_GPS },
>   { "LNV4752", RFKILL_TYPE_GPS },
> + { "OBDA8723", RFKILL_TYPE_BLUETOOTH },
>   { },
> };

NAK. We are integrating these with hci_bcm.c or hci_intel.c drivers.

Regards

Marcel



Re: [PATCH net-next RFC] Generic XDP

2017-04-09 Thread Johannes Berg
On Sun, 2017-04-09 at 08:25 +0200, Johannes Berg wrote:
> That would also let you use rcu_assign_pointer() which seems like the
> right thing to do here, along with marking the xdp_prog pointer as
> __rcu? That'd also let you use rcu_dereference() instead of
> READ_ONCE() which seems like the better annotation?

Looks like drivers do it exactly this way too though.

What I forgot: I guess we could make drivers use dev->xdp_prog after
this, instead of having their own?

johannes