* Re: Marvell Phy (1510) issue since v4.7 kernel
From: Russell King - ARM Linux @ 2017-01-12 22:31 UTC (permalink / raw)
To: Andrew Lunn
Cc: Kwok, WingMan, Karicheri, Muralidharan, netdev@vger.kernel.org
In-Reply-To: <20170112214941.GE10203@lunn.ch>
On Thu, Jan 12, 2017 at 10:49:41PM +0100, Andrew Lunn wrote:
> How are you using the PHY. What phy-mode do you have set? Do you
> happen to be using it as an RGMII to SERDES/SGMII bridge? This is what
> Russell King is doing, i think.
No - the 88E1512 here is connected to the ethernet host via SGMII.
Armada 8040 ----SGMII----> 88E1512 ----> RJ45
The problem that my commit fixes is that when the 88E1512 is used in
this mode, the copper page reflects the status of the RJ45-side link,
and the fiber page reflects the Armada 8040 side of the link.
Without my patch, the 88E1512 read_status function spots that the fiber
page reports its link is up (because the Armada 8040 side is indeed up)
and decides to report that as the link settings, rather than the
(correct) copper side.
> The point is, the phylib will continue polling the PHY registers,
> reading them. If the FIBRE is up, we want to read the FIBRE values,
> not the copper.
... but only if we aren't connected in SGMII mode to the ethernet host!
The 88E1512 has the RGMII pins, and it has the Serdes pins. The Serdes
pins are used for the optical transceiver, or they're used for a SGMII
connection to an ethernet host. So they can't do both.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* Re: [PATCH 2/2] ARM: dts: dra72-evm-revc: enable irqs for dp83867 eth phys
From: Tony Lindgren @ 2017-01-12 22:27 UTC (permalink / raw)
To: Grygorii Strashko; +Cc: Mugunthan V N, linux-omap, Sekhar Nori, netdev
In-Reply-To: <cd8cdb56-ca47-6e17-43b4-daedc7889612@ti.com>
* Grygorii Strashko <grygorii.strashko@ti.com> [170109 11:26]:
>
>
> On 01/06/2017 03:54 PM, Tony Lindgren wrote:
> > * Grygorii Strashko <grygorii.strashko@ti.com> [170106 12:56]:
> > > TI DRA72-EVM Rev C has two DP83867 ethernet phys which support IRQ
> > > generation in case of phy/link status changes. The INT/PWDN lines from both
> > > DP83867 phys are wired to DRA7 gpio6.16, so reflect the same in DT.
> >
> > Hmm not seeing the patch 1/2 here.. Can this one be queued separately?
> > Is it for v4.11 or a fix?
>
> This is for next (v4.11) and there is just a mistake in subj, Sry.
OK applying into omap-for-v4.11/dt thanks.
Tony
^ permalink raw reply
* [PATCH v2] tcp: fix tcp_fastopen unaligned access complaints on sparc
From: Shannon Nelson @ 2017-01-12 22:24 UTC (permalink / raw)
To: netdev, davem
Cc: sparclinux, linux-kernel, eric.dumazet, rob.gardner,
Shannon Nelson
Fix up a data alignment issue on sparc by swapping the order
of the cookie byte array field with the length field in
struct tcp_fastopen_cookie, and making it a proper union
to clean up the typecasting.
This addresses log complaints like these:
log_unaligned: 113 callbacks suppressed
Kernel unaligned access at TPC[976490] tcp_try_fastopen+0x2d0/0x360
Kernel unaligned access at TPC[9764ac] tcp_try_fastopen+0x2ec/0x360
Kernel unaligned access at TPC[9764c8] tcp_try_fastopen+0x308/0x360
Kernel unaligned access at TPC[9764e4] tcp_try_fastopen+0x324/0x360
Kernel unaligned access at TPC[976490] tcp_try_fastopen+0x2d0/0x360
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
v2: Use Eric's suggestion for a union in the struct
include/linux/tcp.h | 7 ++++++-
net/ipv4/tcp_fastopen.c | 2 +-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index fc5848d..c93f4b3 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -62,8 +62,13 @@ static inline unsigned int tcp_optlen(const struct sk_buff *skb)
/* TCP Fast Open Cookie as stored in memory */
struct tcp_fastopen_cookie {
+ union {
+ u8 val[TCP_FASTOPEN_COOKIE_MAX];
+#if IS_ENABLED(CONFIG_IPV6)
+ struct in6_addr addr;
+#endif
+ };
s8 len;
- u8 val[TCP_FASTOPEN_COOKIE_MAX];
bool exp; /* In RFC6994 experimental option format */
};
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
index 4e777a3..f519195 100644
--- a/net/ipv4/tcp_fastopen.c
+++ b/net/ipv4/tcp_fastopen.c
@@ -113,7 +113,7 @@ static bool tcp_fastopen_cookie_gen(struct request_sock *req,
struct tcp_fastopen_cookie tmp;
if (__tcp_fastopen_cookie_gen(&ip6h->saddr, &tmp)) {
- struct in6_addr *buf = (struct in6_addr *) tmp.val;
+ struct in6_addr *buf = &tmp.addr;
int i;
for (i = 0; i < 4; i++)
--
1.7.1
^ permalink raw reply related
* Re: [net PATCH 5/5] virtio_net: XDP support for adjust_head
From: Michael S. Tsirkin @ 2017-01-12 22:22 UTC (permalink / raw)
To: John Fastabend
Cc: jasowang, john.r.fastabend, netdev, alexei.starovoitov, daniel
In-Reply-To: <20170112214519.3039.27879.stgit@john-Precision-Tower-5810>
On Thu, Jan 12, 2017 at 01:45:19PM -0800, John Fastabend wrote:
> Add support for XDP adjust head by allocating a 256B header region
> that XDP programs can grow into. This is only enabled when a XDP
> program is loaded.
>
> In order to ensure that we do not have to unwind queue headroom push
> queue setup below bpf_prog_add. It reads better to do a prog ref
> unwind vs another queue setup call.
>
> At the moment this code must do a full reset to ensure old buffers
> without headroom on program add or with headroom on program removal
> are not used incorrectly in the datapath. Ideally we would only
> have to disable/enable the RX queues being updated but there is no
> API to do this at the moment in virtio so use the big hammer. In
> practice it is likely not that big of a problem as this will only
> happen when XDP is enabled/disabled changing programs does not
> require the reset. There is some risk that the driver may either
> have an allocation failure or for some reason fail to correctly
> negotiate with the underlying backend in this case the driver will
> be left uninitialized. I have not seen this ever happen on my test
> systems and for what its worth this same failure case can occur
> from probe and other contexts in virtio framework.
Could you explain about this a bit more?
Thanks!
> Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
> ---
> drivers/net/virtio_net.c | 155 ++++++++++++++++++++++++++++++++++++++++------
> drivers/virtio/virtio.c | 9 ++-
> include/linux/virtio.h | 3 +
> 3 files changed, 144 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 6041828..8b897e7 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -28,6 +28,7 @@
> #include <linux/slab.h>
> #include <linux/cpu.h>
> #include <linux/average.h>
> +#include <linux/pci.h>
> #include <net/busy_poll.h>
>
> static int napi_weight = NAPI_POLL_WEIGHT;
> @@ -159,6 +160,9 @@ struct virtnet_info {
> /* Ethtool settings */
> u8 duplex;
> u32 speed;
> +
> + /* Headroom allocated in RX Queue */
> + unsigned int headroom;
> };
>
> struct padded_vnet_hdr {
> @@ -359,6 +363,7 @@ static void virtnet_xdp_xmit(struct virtnet_info *vi,
> }
>
> if (vi->mergeable_rx_bufs) {
> + xdp->data -= sizeof(struct virtio_net_hdr_mrg_rxbuf);
> /* Zero header and leave csum up to XDP layers */
> hdr = xdp->data;
> memset(hdr, 0, vi->hdr_len);
> @@ -375,7 +380,9 @@ static void virtnet_xdp_xmit(struct virtnet_info *vi,
> num_sg = 2;
> sg_init_table(sq->sg, 2);
> sg_set_buf(sq->sg, hdr, vi->hdr_len);
> - skb_to_sgvec(skb, sq->sg + 1, 0, skb->len);
> + skb_to_sgvec(skb, sq->sg + 1,
> + xdp->data - xdp->data_hard_start,
> + xdp->data_end - xdp->data);
> }
> err = virtqueue_add_outbuf(sq->vq, sq->sg, num_sg,
> data, GFP_ATOMIC);
> @@ -401,7 +408,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
> struct bpf_prog *xdp_prog;
>
> len -= vi->hdr_len;
> - skb_trim(skb, len);
>
> rcu_read_lock();
> xdp_prog = rcu_dereference(rq->xdp_prog);
> @@ -413,11 +419,15 @@ static struct sk_buff *receive_small(struct net_device *dev,
> if (unlikely(hdr->hdr.gso_type || hdr->hdr.flags))
> goto err_xdp;
>
> - xdp.data = skb->data;
> + xdp.data_hard_start = skb->data;
> + xdp.data = skb->data + vi->headroom;
> xdp.data_end = xdp.data + len;
> act = bpf_prog_run_xdp(xdp_prog, &xdp);
> switch (act) {
> case XDP_PASS:
> + /* Recalculate length in case bpf program changed it */
> + len = xdp.data_end - xdp.data;
> + __skb_pull(skb, xdp.data - xdp.data_hard_start);
> break;
> case XDP_TX:
> virtnet_xdp_xmit(vi, rq, &xdp, skb);
> @@ -432,6 +442,7 @@ static struct sk_buff *receive_small(struct net_device *dev,
> }
> rcu_read_unlock();
>
> + skb_trim(skb, len);
> return skb;
>
> err_xdp:
> @@ -569,7 +580,11 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
> if (unlikely(hdr->hdr.gso_type))
> goto err_xdp;
>
> + /* Allow consuming headroom but reserve enough space to push
> + * the descriptor on if we get an XDP_TX return code.
> + */
> data = page_address(xdp_page) + offset;
> + xdp.data_hard_start = data - vi->headroom + desc_room;
> xdp.data = data + desc_room;
> xdp.data_end = xdp.data + (len - vi->hdr_len);
> act = bpf_prog_run_xdp(xdp_prog, &xdp);
> @@ -748,20 +763,21 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
> static int add_recvbuf_small(struct virtnet_info *vi, struct receive_queue *rq,
> gfp_t gfp)
> {
> + int headroom = GOOD_PACKET_LEN + vi->headroom;
> struct sk_buff *skb;
> struct virtio_net_hdr_mrg_rxbuf *hdr;
> int err;
>
> - skb = __netdev_alloc_skb_ip_align(vi->dev, GOOD_PACKET_LEN, gfp);
> + skb = __netdev_alloc_skb_ip_align(vi->dev, headroom, gfp);
> if (unlikely(!skb))
> return -ENOMEM;
>
> - skb_put(skb, GOOD_PACKET_LEN);
> + skb_put(skb, headroom);
>
> hdr = skb_vnet_hdr(skb);
> sg_init_table(rq->sg, 2);
> sg_set_buf(rq->sg, hdr, vi->hdr_len);
> - skb_to_sgvec(skb, rq->sg + 1, 0, skb->len);
> + skb_to_sgvec(skb, rq->sg + 1, vi->headroom, skb->len - vi->headroom);
>
> err = virtqueue_add_inbuf(rq->vq, rq->sg, 2, skb, gfp);
> if (err < 0)
> @@ -829,24 +845,27 @@ static unsigned int get_mergeable_buf_len(struct ewma_pkt_len *avg_pkt_len)
> return ALIGN(len, MERGEABLE_BUFFER_ALIGN);
> }
>
> -static int add_recvbuf_mergeable(struct receive_queue *rq, gfp_t gfp)
> +static int add_recvbuf_mergeable(struct virtnet_info *vi,
> + struct receive_queue *rq, gfp_t gfp)
> {
> struct page_frag *alloc_frag = &rq->alloc_frag;
> + unsigned int headroom = vi->headroom;
> char *buf;
> unsigned long ctx;
> int err;
> unsigned int len, hole;
>
> len = get_mergeable_buf_len(&rq->mrg_avg_pkt_len);
> - if (unlikely(!skb_page_frag_refill(len, alloc_frag, gfp)))
> + if (unlikely(!skb_page_frag_refill(len + headroom, alloc_frag, gfp)))
> return -ENOMEM;
>
> buf = (char *)page_address(alloc_frag->page) + alloc_frag->offset;
> + buf += headroom; /* advance address leaving hole at front of pkt */
> ctx = mergeable_buf_to_ctx(buf, len);
> get_page(alloc_frag->page);
> - alloc_frag->offset += len;
> + alloc_frag->offset += len + headroom;
> hole = alloc_frag->size - alloc_frag->offset;
> - if (hole < len) {
> + if (hole < len + headroom) {
> /* To avoid internal fragmentation, if there is very likely not
> * enough space for another buffer, add the remaining space to
> * the current buffer. This extra space is not included in
> @@ -880,7 +899,7 @@ static bool try_fill_recv(struct virtnet_info *vi, struct receive_queue *rq,
> gfp |= __GFP_COLD;
> do {
> if (vi->mergeable_rx_bufs)
> - err = add_recvbuf_mergeable(rq, gfp);
> + err = add_recvbuf_mergeable(vi, rq, gfp);
> else if (vi->big_packets)
> err = add_recvbuf_big(vi, rq, gfp);
> else
> @@ -1675,12 +1694,90 @@ static void virtnet_init_settings(struct net_device *dev)
> .set_settings = virtnet_set_settings,
> };
>
> +#define VIRTIO_XDP_HEADROOM 256
> +
> +static int init_vqs(struct virtnet_info *vi);
> +static void remove_vq_common(struct virtnet_info *vi, bool lock);
> +
> +/* Reset virtio device with RTNL held this is very similar to the
> + * freeze()/restore() logic except we need to ensure locking. It is
> + * possible that this routine may fail and leave the driver in a
> + * failed state. However assuming the driver negotiated correctly
> + * at probe time we _should_ be able to (re)negotiate driver again.
> + */
> +static int virtnet_xdp_reset(struct virtnet_info *vi)
> +{
> + struct virtio_device *vdev = vi->vdev;
> + unsigned int status;
> + int i, ret;
> +
> + /* Disable and unwind rings */
> + virtio_config_disable(vdev);
> + vdev->failed = vdev->config->get_status(vdev) & VIRTIO_CONFIG_S_FAILED;
> +
> + netif_device_detach(vi->dev);
> + cancel_delayed_work_sync(&vi->refill);
> + if (netif_running(vi->dev)) {
> + for (i = 0; i < vi->max_queue_pairs; i++)
> + napi_disable(&vi->rq[i].napi);
> + }
> +
> + remove_vq_common(vi, false);
> +
> + /* Do a reset per virtio spec recommendation */
> + vdev->config->reset(vdev);
> +
> + /* Acknowledge that we've seen the device. */
> + status = vdev->config->get_status(vdev);
> + vdev->config->set_status(vdev, status | VIRTIO_CONFIG_S_ACKNOWLEDGE);
> +
> + /* Notify driver is up and finalize features per specification. The
> + * error code from finalize features is checked here but should not
> + * fail because we assume features were previously synced successfully.
> + */
> + status = vdev->config->get_status(vdev);
> + vdev->config->set_status(vdev, status | VIRTIO_CONFIG_S_DRIVER);
> + ret = virtio_finalize_features(vdev);
> + if (ret) {
> + netdev_warn(vi->dev, "virtio_finalize_features failed during reset aborting\n");
> + goto err;
> + }
> +
> + ret = init_vqs(vi);
> + if (ret) {
> + netdev_warn(vi->dev, "init_vqs failed during reset aborting\n");
> + goto err;
> + }
> + virtio_device_ready(vi->vdev);
> +
> + if (netif_running(vi->dev)) {
> + for (i = 0; i < vi->curr_queue_pairs; i++)
> + if (!try_fill_recv(vi, &vi->rq[i], GFP_KERNEL))
> + schedule_delayed_work(&vi->refill, 0);
> +
> + for (i = 0; i < vi->max_queue_pairs; i++)
> + virtnet_napi_enable(&vi->rq[i]);
> + }
> + netif_device_attach(vi->dev);
> + /* Finally, tell the device we're all set */
> + status = vdev->config->get_status(vdev);
> + vdev->config->set_status(vdev, status | VIRTIO_CONFIG_S_DRIVER_OK);
> + virtio_config_enable(vdev);
> +
> + return 0;
> +err:
> + status = vdev->config->get_status(vdev);
> + vdev->config->set_status(vdev, status | VIRTIO_CONFIG_S_FAILED);
> + return ret;
> +}
> +
> static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog)
> {
> unsigned long int max_sz = PAGE_SIZE - sizeof(struct padded_vnet_hdr);
> struct virtnet_info *vi = netdev_priv(dev);
> struct bpf_prog *old_prog;
> u16 xdp_qp = 0, curr_qp;
> + unsigned int old_hr;
> int i, err;
>
> if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO4) ||
> @@ -1712,18 +1809,31 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog)
> return -ENOMEM;
> }
>
> - err = virtnet_set_queues(vi, curr_qp + xdp_qp);
> - if (err) {
> - dev_warn(&dev->dev, "XDP Device queue allocation failure.\n");
> - return err;
> - }
> -
> + old_hr = vi->headroom;
> if (prog) {
> prog = bpf_prog_add(prog, vi->max_queue_pairs - 1);
> - if (IS_ERR(prog)) {
> - virtnet_set_queues(vi, curr_qp);
> + if (IS_ERR(prog))
> return PTR_ERR(prog);
> - }
> + vi->headroom = VIRTIO_XDP_HEADROOM;
> + } else {
> + vi->headroom = 0;
> + }
> +
> + /* Changing the headroom in buffers is a disruptive operation because
> + * existing buffers must be flushed and reallocated. This will happen
> + * when a xdp program is initially added or xdp is disabled by removing
> + * the xdp program.
> + */
> + if (old_hr != vi->headroom) {
> + err = virtnet_xdp_reset(vi);
> + if (err)
> + goto err_reset;
> + }
> +
> + err = virtnet_set_queues(vi, curr_qp + xdp_qp);
> + if (err) {
> + dev_warn(&dev->dev, "XDP Device queue allocation failure.\n");
> + goto err_reset;
> }
>
> vi->xdp_queue_pairs = xdp_qp;
> @@ -1737,6 +1847,11 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog)
> }
>
> return 0;
> +err_reset:
> + if (prog)
> + bpf_prog_sub(prog, vi->max_queue_pairs - 1);
> + vi->headroom = old_hr;
> + return err;
> }
>
> static bool virtnet_xdp_query(struct net_device *dev)
> diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
> index 7062bb0..0e922b9 100644
> --- a/drivers/virtio/virtio.c
> +++ b/drivers/virtio/virtio.c
> @@ -145,14 +145,15 @@ void virtio_config_changed(struct virtio_device *dev)
> }
> EXPORT_SYMBOL_GPL(virtio_config_changed);
>
> -static void virtio_config_disable(struct virtio_device *dev)
> +void virtio_config_disable(struct virtio_device *dev)
> {
> spin_lock_irq(&dev->config_lock);
> dev->config_enabled = false;
> spin_unlock_irq(&dev->config_lock);
> }
> +EXPORT_SYMBOL_GPL(virtio_config_disable);
>
> -static void virtio_config_enable(struct virtio_device *dev)
> +void virtio_config_enable(struct virtio_device *dev)
> {
> spin_lock_irq(&dev->config_lock);
> dev->config_enabled = true;
> @@ -161,8 +162,9 @@ static void virtio_config_enable(struct virtio_device *dev)
> dev->config_change_pending = false;
> spin_unlock_irq(&dev->config_lock);
> }
> +EXPORT_SYMBOL_GPL(virtio_config_enable);
>
> -static int virtio_finalize_features(struct virtio_device *dev)
> +int virtio_finalize_features(struct virtio_device *dev)
> {
> int ret = dev->config->finalize_features(dev);
> unsigned status;
> @@ -182,6 +184,7 @@ static int virtio_finalize_features(struct virtio_device *dev)
> }
> return 0;
> }
> +EXPORT_SYMBOL_GPL(virtio_finalize_features);
>
> static int virtio_dev_probe(struct device *_d)
> {
> diff --git a/include/linux/virtio.h b/include/linux/virtio.h
> index d5eb547..eac8f05 100644
> --- a/include/linux/virtio.h
> +++ b/include/linux/virtio.h
> @@ -137,6 +137,9 @@ static inline struct virtio_device *dev_to_virtio(struct device *_dev)
>
> void virtio_break_device(struct virtio_device *dev);
>
> +void virtio_config_disable(struct virtio_device *dev);
> +void virtio_config_enable(struct virtio_device *dev);
> +int virtio_finalize_features(struct virtio_device *dev);
> void virtio_config_changed(struct virtio_device *dev);
> #ifdef CONFIG_PM_SLEEP
> int virtio_device_freeze(struct virtio_device *dev);
^ permalink raw reply
* Re: [net-next PATCH 1/3] Revert "icmp: avoid allocating large struct on stack"
From: Cong Wang @ 2017-01-12 22:21 UTC (permalink / raw)
To: Eric Dumazet
Cc: Jesper Dangaard Brouer, David Miller,
Linux Kernel Network Developers
In-Reply-To: <1484084891.21472.44.camel@edumazet-glaptop3.roam.corp.google.com>
On Tue, Jan 10, 2017 at 1:48 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Tue, 2017-01-10 at 21:08 +0100, Jesper Dangaard Brouer wrote:
>> On Tue, 10 Jan 2017 10:44:59 -0800 Cong Wang <xiyou.wangcong@gmail.com> wrote:
>>
>> > On Tue, Jan 10, 2017 at 10:12 AM, David Miller <davem@davemloft.net> wrote:
>> [...]
>> > > You can keep showing us how expertly you can deflect the real
>> > > issue we are discussion here, but that won't improve the situation
>> > > at all I am afraid.
>> >
>> > Of course, there are just too many people too lazy to do a google search:
>> >
>> > https://lists.debian.org/debian-kernel/2013/05/msg00500.html
>>
>> My analysis of the problem shown in above link is not related to using
>> all the stack space, but instead that skb->cb was not cleared. This
>> can cause the ip_options_echo() call in icmp_send() to access garbage
>> as this is: __ip_options_echo(dopt, skb, &IPCB(skb)->opt).
>>
>> Fixed by commit a622260254ee ("ip_tunnel: fix kernel panic with icmp_dest_unreach")
>> https://git.kernel.org/torvalds/c/a622260254ee
>>
>> Thus, it is (likely) the __ip_options_echo() call that violates stack
>> access, as it is passed in a pointer to the stack, and advance this
>> based on garbage "optlen".
>>
>
> I totally agree.
I can't agree, iptunnel or ipgre symbols are not in the above stack trace
at all. Although I do agree that the above stack usage is not aggressive,
especially when compared with the other I sent.
My vague memory told me the original problem I fixed is related to vxlan
but after trying to search all netdev archives in 2013 May/Jun, I still can't
find it, perhaps it was reported to LKML or somewhere else rather than
netdev. It was certainly a real problem.
Even though the irq stack is 16K, but it is too easy to stack netdevices
and stack qdisc's too, so for TX path I am not surprised at all if 16K could
be exhausted eventually. Yeah, it is hard to blame one of them in the call
chain, but 112 bytes _alone_ are aggressive for such a function deeply
in the call stack. That's my whole point.
^ permalink raw reply
* Re: [PATCH] tcp: fix tcp_fastopen unaligned access complaints on sparc
From: David Miller @ 2017-01-12 21:58 UTC (permalink / raw)
To: shannon.nelson
Cc: eric.dumazet, rob.gardner, netdev, sparclinux, linux-kernel
In-Reply-To: <a24f1f0e-457b-0316-b545-fe1362bd7dbe@oracle.com>
From: Shannon Nelson <shannon.nelson@oracle.com>
Date: Thu, 12 Jan 2017 13:58:10 -0800
>
>
> On 1/12/2017 1:47 PM, David Miller wrote:
>> From: Eric Dumazet <eric.dumazet@gmail.com>
>> Date: Thu, 12 Jan 2017 13:36:30 -0800
>>
>>> val should be an union, so that proper alignment is enforced by one
>>> member.
>>
>> Sure, annotating the type so that it is aligned correctly makes
>> sense.
>>
>
> ... and we should change the offending pointer assignment as well. I
> can use this and respin a v2 if we're happy with this solution.
I am.
^ permalink raw reply
* Re: [PATCH] tcp: fix tcp_fastopen unaligned access complaints on sparc
From: Shannon Nelson @ 2017-01-12 21:58 UTC (permalink / raw)
To: David Miller, eric.dumazet; +Cc: rob.gardner, netdev, sparclinux, linux-kernel
In-Reply-To: <20170112.164731.720625943370044951.davem@davemloft.net>
On 1/12/2017 1:47 PM, David Miller wrote:
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Thu, 12 Jan 2017 13:36:30 -0800
>
>> val should be an union, so that proper alignment is enforced by one
>> member.
>
> Sure, annotating the type so that it is aligned correctly makes
> sense.
>
... and we should change the offending pointer assignment as well. I
can use this and respin a v2 if we're happy with this solution.
sln
^ permalink raw reply
* Re: [PATCH net-next] ipv6: sr: static percpu allocation for hmac_ring
From: David Miller @ 2017-01-12 21:53 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, david.lebrun
In-Reply-To: <1484239810.15816.47.camel@edumazet-glaptop3.roam.corp.google.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 12 Jan 2017 08:50:10 -0800
> From: Eric Dumazet <edumazet@google.com>
>
> Current allocations are not NUMA aware, and lack proper
> cleanup in case of error.
>
> It is perfectly fine to use static per cpu allocations for 256 bytes
> per cpu.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: David Lebrun <david.lebrun@uclouvain.be>
Applied.
^ permalink raw reply
* Re: [PATCH net-next] liquidio: replace skb_tx_hash with fallback
From: David Miller @ 2017-01-12 21:51 UTC (permalink / raw)
To: eric.dumazet
Cc: felix.manlunas, netdev, raghu.vatsavayi, derek.chickles,
satananda.burla
In-Reply-To: <1484248218.3321.1.camel@edumazet-glaptop3.roam.corp.google.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 12 Jan 2017 11:10:18 -0800
> Why are you keeping these functions then ?
>
> Remove them completely, and remove .ndo_select_queue from your ops.
>
> Core networking stack will fallback automatically.
Agreed, if all the queue selection function is doing is invoking the
fallback, get rid of it.
^ permalink raw reply
* Re: [PATCH] net: thunderx: acpi: fix LMAC initialization
From: David Miller @ 2017-01-12 21:50 UTC (permalink / raw)
To: Vadim.Lomovtsev
Cc: linux-arm-kernel, netdev, linux-kernel, sgoutham, rric,
Radha.Chintakuntla
In-Reply-To: <1484234886-22172-1-git-send-email-Vadim.Lomovtsev@caviumnetworks.com>
From: Vadim Lomovtsev <Vadim.Lomovtsev@caviumnetworks.com>
Date: Thu, 12 Jan 2017 07:28:06 -0800
> While probing BGX we requesting appropriate QLM for it's configuration
> and get LMAC count by that request. Then, while reading configured
> MAC values from SSDT table we need to save them in proper mapping:
> BGX[i]->lmac[j].mac = <MAC value>
> to later provide for initialization stuff. In order to fill
> such mapping properly we need to add lmac index to be used while
> acpi initialization since at this moment bgx->lmac_count already contains
> actual value.
>
> Signed-off-by: Vadim Lomovtsev <Vadim.Lomovtsev@caviumnetworks.com>
Applied.
^ permalink raw reply
* Re: Marvell Phy (1510) issue since v4.7 kernel
From: Andrew Lunn @ 2017-01-12 21:49 UTC (permalink / raw)
To: Kwok, WingMan
Cc: rmk+kernel@arm.linux.org.uk, Karicheri, Muralidharan,
netdev@vger.kernel.org
In-Reply-To: <230CBA6E4B6B6B418E8730AC28E6FC7E15354EB0@DFLE11.ent.ti.com>
> But our problem is caused by the read_status function:
>
> if ((phydev->supported & SUPPORTED_FIBRE)) {
> err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_FIBER);
> if (err < 0)
> goto error;
>
> err = marvell_read_status_page(phydev, MII_M1111_FIBER);
> if (err < 0)
> goto error;
>
> /* If the fiber link is up, it is the selected and used link.
> * In this case, we need to stay in the fiber page.
> * Please to be careful about that, avoid to restore Copper page
> * in other functions which could break the behaviour
> * for some fiber phy like 88E1512.
> * */
> if (phydev->link)
> return 0;
>
> which keeps the fiber page if phydev->link is true (for some
> reason this is the case even though we are not using fiber)
How are you using the PHY. What phy-mode do you have set? Do you
happen to be using it as an RGMII to SERDES/SGMII bridge? This is what
Russell King is doing, i think.
Have you tried the patch Russell submitted recently.
Author: Russell King <rmk+kernel@armlinux.org.uk>
Date: Tue Jan 10 23:13:45 2017 +0000
net: phy: marvell: fix Marvell 88E1512 used in SGMII mode
When an Marvell 88E1512 PHY is connected to a nic in SGMII mode, the
fiber page is used for the SGMII host-side connection. The PHY driver
notices that SUPPORTED_FIBRE is set, so it tries reading the fiber page
for the link status, and ends up reading the MAC-side status instead of
the outgoing (copper) link. This leads to incorrect results reported
via ethtool.
If the PHY is connected via SGMII to the host, ignore the fiber page.
However, continue to allow the existing power management code to
suspend and resume the fiber page.
> However, this causes a problem in kernel reboot because neither
> the suspend/resume is called to restore the copper page and
> u-boot marvell phy driver does not support 1510 fiber, which
> will then result in writing to the wrong phy regs and causes
> a sgmii auto-nego time out.
This is still a u-boot bug. It should not assume the PHY is in a sane
state. It should reset it and configure it as needed. So far, i don't
think you have reported any issues with Linux usage of the PHY. There
clearly are bugs, but your real problem is u-boot.
> In addition to fixing the ! in suspend/resume, my suggestion
> would be to change also the read_status function to
> always restore the copper page after doing the fiber stuffs:
Nope. This is done deliberately, as the comment suggests:
> /* If the fiber link is up, it is the selected and used link.
> * In this case, we need to stay in the fiber page.
> * Please to be careful about that, avoid to restore Copper page
> * in other functions which could break the behaviour
> * for some fiber phy like 88E1512.
> * */
> if (phydev->link)
> return 0;
The point is, the phylib will continue polling the PHY registers,
reading them. If the FIBRE is up, we want to read the FIBRE values,
not the copper.
> Another issue is that, as of now, FIBER is enabled regardless
> of the specific 88e151x. But I believe there is 88e151x chip(s)
> that does not support fiber. Should fiber be enabled only for
> those that do support fiber?
Yes, we should look at register 30, page 18 any set SUPPORTED_FIBRE
based on that.
Andrew
^ permalink raw reply
* Re: [PATCH net-next] ipmr: improve hash scalability
From: David Miller @ 2017-01-12 21:48 UTC (permalink / raw)
To: nikolay; +Cc: netdev, roopa, sharpd
In-Reply-To: <1484232813-11473-1-git-send-email-nikolay@cumulusnetworks.com>
From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Date: Thu, 12 Jan 2017 15:53:33 +0100
> Recently we started using ipmr with thousands of entries and easily hit
> soft lockups on smaller devices. The reason is that the hash function
> uses the high order bits from the src and dst, but those don't change in
> many common cases, also the hash table is only 64 elements so with
> thousands it doesn't scale at all.
> This patch migrates the hash table to rhashtable, and in particular the
> rhl interface which allows for duplicate elements to be chained because
> of the MFC_PROXY support (*,G; *,*,oif cases) which allows for multiple
> duplicate entries to be added with different interfaces (IMO wrong, but
> it's been in for a long time).
>
> And here are some results from tests I've run in a VM:
> mr_table size (default, allocated for all namespaces):
> Before After
> 49304 bytes 2400 bytes
>
> Add 65000 routes (the diff is much larger on smaller devices):
> Before After
> 1m42s 58s
>
> Forwarding 256 byte packets with 65000 routes (test done in a VM):
> Before After
> 3 Mbps / ~1465 pps 122 Mbps / ~59000 pps
>
> As a bonus we no longer see the soft lockups on smaller devices which
> showed up even with 2000 entries before.
>
> Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Looks really nice, applied, thanks!
^ permalink raw reply
* Re: [PATCH] tcp: fix tcp_fastopen unaligned access complaints on sparc
From: David Miller @ 2017-01-12 21:47 UTC (permalink / raw)
To: eric.dumazet
Cc: shannon.nelson, rob.gardner, netdev, sparclinux, linux-kernel
In-Reply-To: <1484256990.13165.6.camel@edumazet-glaptop3.roam.corp.google.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 12 Jan 2017 13:36:30 -0800
> val should be an union, so that proper alignment is enforced by one
> member.
Sure, annotating the type so that it is aligned correctly makes
sense.
^ permalink raw reply
* [net PATCH 5/5] virtio_net: XDP support for adjust_head
From: John Fastabend @ 2017-01-12 21:45 UTC (permalink / raw)
To: jasowang, mst
Cc: john.r.fastabend, netdev, john.fastabend, alexei.starovoitov,
daniel
In-Reply-To: <20170112213919.3039.54165.stgit@john-Precision-Tower-5810>
Add support for XDP adjust head by allocating a 256B header region
that XDP programs can grow into. This is only enabled when a XDP
program is loaded.
In order to ensure that we do not have to unwind queue headroom push
queue setup below bpf_prog_add. It reads better to do a prog ref
unwind vs another queue setup call.
At the moment this code must do a full reset to ensure old buffers
without headroom on program add or with headroom on program removal
are not used incorrectly in the datapath. Ideally we would only
have to disable/enable the RX queues being updated but there is no
API to do this at the moment in virtio so use the big hammer. In
practice it is likely not that big of a problem as this will only
happen when XDP is enabled/disabled changing programs does not
require the reset. There is some risk that the driver may either
have an allocation failure or for some reason fail to correctly
negotiate with the underlying backend in this case the driver will
be left uninitialized. I have not seen this ever happen on my test
systems and for what its worth this same failure case can occur
from probe and other contexts in virtio framework.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
drivers/net/virtio_net.c | 155 ++++++++++++++++++++++++++++++++++++++++------
drivers/virtio/virtio.c | 9 ++-
include/linux/virtio.h | 3 +
3 files changed, 144 insertions(+), 23 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 6041828..8b897e7 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -28,6 +28,7 @@
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/average.h>
+#include <linux/pci.h>
#include <net/busy_poll.h>
static int napi_weight = NAPI_POLL_WEIGHT;
@@ -159,6 +160,9 @@ struct virtnet_info {
/* Ethtool settings */
u8 duplex;
u32 speed;
+
+ /* Headroom allocated in RX Queue */
+ unsigned int headroom;
};
struct padded_vnet_hdr {
@@ -359,6 +363,7 @@ static void virtnet_xdp_xmit(struct virtnet_info *vi,
}
if (vi->mergeable_rx_bufs) {
+ xdp->data -= sizeof(struct virtio_net_hdr_mrg_rxbuf);
/* Zero header and leave csum up to XDP layers */
hdr = xdp->data;
memset(hdr, 0, vi->hdr_len);
@@ -375,7 +380,9 @@ static void virtnet_xdp_xmit(struct virtnet_info *vi,
num_sg = 2;
sg_init_table(sq->sg, 2);
sg_set_buf(sq->sg, hdr, vi->hdr_len);
- skb_to_sgvec(skb, sq->sg + 1, 0, skb->len);
+ skb_to_sgvec(skb, sq->sg + 1,
+ xdp->data - xdp->data_hard_start,
+ xdp->data_end - xdp->data);
}
err = virtqueue_add_outbuf(sq->vq, sq->sg, num_sg,
data, GFP_ATOMIC);
@@ -401,7 +408,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
struct bpf_prog *xdp_prog;
len -= vi->hdr_len;
- skb_trim(skb, len);
rcu_read_lock();
xdp_prog = rcu_dereference(rq->xdp_prog);
@@ -413,11 +419,15 @@ static struct sk_buff *receive_small(struct net_device *dev,
if (unlikely(hdr->hdr.gso_type || hdr->hdr.flags))
goto err_xdp;
- xdp.data = skb->data;
+ xdp.data_hard_start = skb->data;
+ xdp.data = skb->data + vi->headroom;
xdp.data_end = xdp.data + len;
act = bpf_prog_run_xdp(xdp_prog, &xdp);
switch (act) {
case XDP_PASS:
+ /* Recalculate length in case bpf program changed it */
+ len = xdp.data_end - xdp.data;
+ __skb_pull(skb, xdp.data - xdp.data_hard_start);
break;
case XDP_TX:
virtnet_xdp_xmit(vi, rq, &xdp, skb);
@@ -432,6 +442,7 @@ static struct sk_buff *receive_small(struct net_device *dev,
}
rcu_read_unlock();
+ skb_trim(skb, len);
return skb;
err_xdp:
@@ -569,7 +580,11 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
if (unlikely(hdr->hdr.gso_type))
goto err_xdp;
+ /* Allow consuming headroom but reserve enough space to push
+ * the descriptor on if we get an XDP_TX return code.
+ */
data = page_address(xdp_page) + offset;
+ xdp.data_hard_start = data - vi->headroom + desc_room;
xdp.data = data + desc_room;
xdp.data_end = xdp.data + (len - vi->hdr_len);
act = bpf_prog_run_xdp(xdp_prog, &xdp);
@@ -748,20 +763,21 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
static int add_recvbuf_small(struct virtnet_info *vi, struct receive_queue *rq,
gfp_t gfp)
{
+ int headroom = GOOD_PACKET_LEN + vi->headroom;
struct sk_buff *skb;
struct virtio_net_hdr_mrg_rxbuf *hdr;
int err;
- skb = __netdev_alloc_skb_ip_align(vi->dev, GOOD_PACKET_LEN, gfp);
+ skb = __netdev_alloc_skb_ip_align(vi->dev, headroom, gfp);
if (unlikely(!skb))
return -ENOMEM;
- skb_put(skb, GOOD_PACKET_LEN);
+ skb_put(skb, headroom);
hdr = skb_vnet_hdr(skb);
sg_init_table(rq->sg, 2);
sg_set_buf(rq->sg, hdr, vi->hdr_len);
- skb_to_sgvec(skb, rq->sg + 1, 0, skb->len);
+ skb_to_sgvec(skb, rq->sg + 1, vi->headroom, skb->len - vi->headroom);
err = virtqueue_add_inbuf(rq->vq, rq->sg, 2, skb, gfp);
if (err < 0)
@@ -829,24 +845,27 @@ static unsigned int get_mergeable_buf_len(struct ewma_pkt_len *avg_pkt_len)
return ALIGN(len, MERGEABLE_BUFFER_ALIGN);
}
-static int add_recvbuf_mergeable(struct receive_queue *rq, gfp_t gfp)
+static int add_recvbuf_mergeable(struct virtnet_info *vi,
+ struct receive_queue *rq, gfp_t gfp)
{
struct page_frag *alloc_frag = &rq->alloc_frag;
+ unsigned int headroom = vi->headroom;
char *buf;
unsigned long ctx;
int err;
unsigned int len, hole;
len = get_mergeable_buf_len(&rq->mrg_avg_pkt_len);
- if (unlikely(!skb_page_frag_refill(len, alloc_frag, gfp)))
+ if (unlikely(!skb_page_frag_refill(len + headroom, alloc_frag, gfp)))
return -ENOMEM;
buf = (char *)page_address(alloc_frag->page) + alloc_frag->offset;
+ buf += headroom; /* advance address leaving hole at front of pkt */
ctx = mergeable_buf_to_ctx(buf, len);
get_page(alloc_frag->page);
- alloc_frag->offset += len;
+ alloc_frag->offset += len + headroom;
hole = alloc_frag->size - alloc_frag->offset;
- if (hole < len) {
+ if (hole < len + headroom) {
/* To avoid internal fragmentation, if there is very likely not
* enough space for another buffer, add the remaining space to
* the current buffer. This extra space is not included in
@@ -880,7 +899,7 @@ static bool try_fill_recv(struct virtnet_info *vi, struct receive_queue *rq,
gfp |= __GFP_COLD;
do {
if (vi->mergeable_rx_bufs)
- err = add_recvbuf_mergeable(rq, gfp);
+ err = add_recvbuf_mergeable(vi, rq, gfp);
else if (vi->big_packets)
err = add_recvbuf_big(vi, rq, gfp);
else
@@ -1675,12 +1694,90 @@ static void virtnet_init_settings(struct net_device *dev)
.set_settings = virtnet_set_settings,
};
+#define VIRTIO_XDP_HEADROOM 256
+
+static int init_vqs(struct virtnet_info *vi);
+static void remove_vq_common(struct virtnet_info *vi, bool lock);
+
+/* Reset virtio device with RTNL held this is very similar to the
+ * freeze()/restore() logic except we need to ensure locking. It is
+ * possible that this routine may fail and leave the driver in a
+ * failed state. However assuming the driver negotiated correctly
+ * at probe time we _should_ be able to (re)negotiate driver again.
+ */
+static int virtnet_xdp_reset(struct virtnet_info *vi)
+{
+ struct virtio_device *vdev = vi->vdev;
+ unsigned int status;
+ int i, ret;
+
+ /* Disable and unwind rings */
+ virtio_config_disable(vdev);
+ vdev->failed = vdev->config->get_status(vdev) & VIRTIO_CONFIG_S_FAILED;
+
+ netif_device_detach(vi->dev);
+ cancel_delayed_work_sync(&vi->refill);
+ if (netif_running(vi->dev)) {
+ for (i = 0; i < vi->max_queue_pairs; i++)
+ napi_disable(&vi->rq[i].napi);
+ }
+
+ remove_vq_common(vi, false);
+
+ /* Do a reset per virtio spec recommendation */
+ vdev->config->reset(vdev);
+
+ /* Acknowledge that we've seen the device. */
+ status = vdev->config->get_status(vdev);
+ vdev->config->set_status(vdev, status | VIRTIO_CONFIG_S_ACKNOWLEDGE);
+
+ /* Notify driver is up and finalize features per specification. The
+ * error code from finalize features is checked here but should not
+ * fail because we assume features were previously synced successfully.
+ */
+ status = vdev->config->get_status(vdev);
+ vdev->config->set_status(vdev, status | VIRTIO_CONFIG_S_DRIVER);
+ ret = virtio_finalize_features(vdev);
+ if (ret) {
+ netdev_warn(vi->dev, "virtio_finalize_features failed during reset aborting\n");
+ goto err;
+ }
+
+ ret = init_vqs(vi);
+ if (ret) {
+ netdev_warn(vi->dev, "init_vqs failed during reset aborting\n");
+ goto err;
+ }
+ virtio_device_ready(vi->vdev);
+
+ if (netif_running(vi->dev)) {
+ for (i = 0; i < vi->curr_queue_pairs; i++)
+ if (!try_fill_recv(vi, &vi->rq[i], GFP_KERNEL))
+ schedule_delayed_work(&vi->refill, 0);
+
+ for (i = 0; i < vi->max_queue_pairs; i++)
+ virtnet_napi_enable(&vi->rq[i]);
+ }
+ netif_device_attach(vi->dev);
+ /* Finally, tell the device we're all set */
+ status = vdev->config->get_status(vdev);
+ vdev->config->set_status(vdev, status | VIRTIO_CONFIG_S_DRIVER_OK);
+ virtio_config_enable(vdev);
+
+ return 0;
+err:
+ status = vdev->config->get_status(vdev);
+ vdev->config->set_status(vdev, status | VIRTIO_CONFIG_S_FAILED);
+ return ret;
+}
+
static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog)
{
unsigned long int max_sz = PAGE_SIZE - sizeof(struct padded_vnet_hdr);
struct virtnet_info *vi = netdev_priv(dev);
struct bpf_prog *old_prog;
u16 xdp_qp = 0, curr_qp;
+ unsigned int old_hr;
int i, err;
if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO4) ||
@@ -1712,18 +1809,31 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog)
return -ENOMEM;
}
- err = virtnet_set_queues(vi, curr_qp + xdp_qp);
- if (err) {
- dev_warn(&dev->dev, "XDP Device queue allocation failure.\n");
- return err;
- }
-
+ old_hr = vi->headroom;
if (prog) {
prog = bpf_prog_add(prog, vi->max_queue_pairs - 1);
- if (IS_ERR(prog)) {
- virtnet_set_queues(vi, curr_qp);
+ if (IS_ERR(prog))
return PTR_ERR(prog);
- }
+ vi->headroom = VIRTIO_XDP_HEADROOM;
+ } else {
+ vi->headroom = 0;
+ }
+
+ /* Changing the headroom in buffers is a disruptive operation because
+ * existing buffers must be flushed and reallocated. This will happen
+ * when a xdp program is initially added or xdp is disabled by removing
+ * the xdp program.
+ */
+ if (old_hr != vi->headroom) {
+ err = virtnet_xdp_reset(vi);
+ if (err)
+ goto err_reset;
+ }
+
+ err = virtnet_set_queues(vi, curr_qp + xdp_qp);
+ if (err) {
+ dev_warn(&dev->dev, "XDP Device queue allocation failure.\n");
+ goto err_reset;
}
vi->xdp_queue_pairs = xdp_qp;
@@ -1737,6 +1847,11 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog)
}
return 0;
+err_reset:
+ if (prog)
+ bpf_prog_sub(prog, vi->max_queue_pairs - 1);
+ vi->headroom = old_hr;
+ return err;
}
static bool virtnet_xdp_query(struct net_device *dev)
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 7062bb0..0e922b9 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -145,14 +145,15 @@ void virtio_config_changed(struct virtio_device *dev)
}
EXPORT_SYMBOL_GPL(virtio_config_changed);
-static void virtio_config_disable(struct virtio_device *dev)
+void virtio_config_disable(struct virtio_device *dev)
{
spin_lock_irq(&dev->config_lock);
dev->config_enabled = false;
spin_unlock_irq(&dev->config_lock);
}
+EXPORT_SYMBOL_GPL(virtio_config_disable);
-static void virtio_config_enable(struct virtio_device *dev)
+void virtio_config_enable(struct virtio_device *dev)
{
spin_lock_irq(&dev->config_lock);
dev->config_enabled = true;
@@ -161,8 +162,9 @@ static void virtio_config_enable(struct virtio_device *dev)
dev->config_change_pending = false;
spin_unlock_irq(&dev->config_lock);
}
+EXPORT_SYMBOL_GPL(virtio_config_enable);
-static int virtio_finalize_features(struct virtio_device *dev)
+int virtio_finalize_features(struct virtio_device *dev)
{
int ret = dev->config->finalize_features(dev);
unsigned status;
@@ -182,6 +184,7 @@ static int virtio_finalize_features(struct virtio_device *dev)
}
return 0;
}
+EXPORT_SYMBOL_GPL(virtio_finalize_features);
static int virtio_dev_probe(struct device *_d)
{
diff --git a/include/linux/virtio.h b/include/linux/virtio.h
index d5eb547..eac8f05 100644
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -137,6 +137,9 @@ static inline struct virtio_device *dev_to_virtio(struct device *_dev)
void virtio_break_device(struct virtio_device *dev);
+void virtio_config_disable(struct virtio_device *dev);
+void virtio_config_enable(struct virtio_device *dev);
+int virtio_finalize_features(struct virtio_device *dev);
void virtio_config_changed(struct virtio_device *dev);
#ifdef CONFIG_PM_SLEEP
int virtio_device_freeze(struct virtio_device *dev);
^ permalink raw reply related
* [net PATCH 4/5] virtio_net: remove duplicate queue pair binding in XDP
From: John Fastabend @ 2017-01-12 21:44 UTC (permalink / raw)
To: jasowang, mst
Cc: john.r.fastabend, netdev, john.fastabend, alexei.starovoitov,
daniel
In-Reply-To: <20170112213919.3039.54165.stgit@john-Precision-Tower-5810>
Factor out qp assignment.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
drivers/net/virtio_net.c | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index ec54644..6041828 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -332,15 +332,19 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
static void virtnet_xdp_xmit(struct virtnet_info *vi,
struct receive_queue *rq,
- struct send_queue *sq,
struct xdp_buff *xdp,
void *data)
{
struct virtio_net_hdr_mrg_rxbuf *hdr;
unsigned int num_sg, len;
+ struct send_queue *sq;
+ unsigned int qp;
void *xdp_sent;
int err;
+ qp = vi->curr_queue_pairs - vi->xdp_queue_pairs + smp_processor_id();
+ sq = &vi->sq[qp];
+
/* Free up any pending old buffers before queueing new ones. */
while ((xdp_sent = virtqueue_get_buf(sq->vq, &len)) != NULL) {
if (vi->mergeable_rx_bufs) {
@@ -404,7 +408,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
if (xdp_prog) {
struct virtio_net_hdr_mrg_rxbuf *hdr = buf;
struct xdp_buff xdp;
- unsigned int qp;
u32 act;
if (unlikely(hdr->hdr.gso_type || hdr->hdr.flags))
@@ -417,10 +420,7 @@ static struct sk_buff *receive_small(struct net_device *dev,
case XDP_PASS:
break;
case XDP_TX:
- qp = vi->curr_queue_pairs -
- vi->xdp_queue_pairs +
- smp_processor_id();
- virtnet_xdp_xmit(vi, rq, &vi->sq[qp], &xdp, skb);
+ virtnet_xdp_xmit(vi, rq, &xdp, skb);
rcu_read_unlock();
goto xdp_xmit;
default:
@@ -546,7 +546,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
int desc_room = sizeof(struct virtio_net_hdr_mrg_rxbuf);
struct page *xdp_page;
struct xdp_buff xdp;
- unsigned int qp;
void *data;
u32 act;
@@ -587,10 +586,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
}
break;
case XDP_TX:
- qp = vi->curr_queue_pairs -
- vi->xdp_queue_pairs +
- smp_processor_id();
- virtnet_xdp_xmit(vi, rq, &vi->sq[qp], &xdp, data);
+ virtnet_xdp_xmit(vi, rq, &xdp, data);
ewma_pkt_len_add(&rq->mrg_avg_pkt_len, len);
if (unlikely(xdp_page != page))
goto err_xdp;
^ permalink raw reply related
* [net PATCH 3/5] virtio_net: factor out xdp handler for readability
From: John Fastabend @ 2017-01-12 21:44 UTC (permalink / raw)
To: jasowang, mst
Cc: john.r.fastabend, netdev, john.fastabend, alexei.starovoitov,
daniel
In-Reply-To: <20170112213919.3039.54165.stgit@john-Precision-Tower-5810>
At this point the do_xdp_prog is mostly if/else branches handling
the different modes of virtio_net. So remove it and handle running
the program in the per mode handlers.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
drivers/net/virtio_net.c | 76 +++++++++++++++++-----------------------------
1 file changed, 28 insertions(+), 48 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 43cb2e0..ec54644 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -388,49 +388,6 @@ static void virtnet_xdp_xmit(struct virtnet_info *vi,
virtqueue_kick(sq->vq);
}
-static u32 do_xdp_prog(struct virtnet_info *vi,
- struct receive_queue *rq,
- struct bpf_prog *xdp_prog,
- void *data, int len)
-{
- int hdr_padded_len;
- struct xdp_buff xdp;
- void *buf;
- unsigned int qp;
- u32 act;
-
- if (vi->mergeable_rx_bufs) {
- hdr_padded_len = sizeof(struct virtio_net_hdr_mrg_rxbuf);
- xdp.data = data + hdr_padded_len;
- xdp.data_end = xdp.data + (len - vi->hdr_len);
- buf = data;
- } else { /* small buffers */
- struct sk_buff *skb = data;
-
- xdp.data = skb->data;
- xdp.data_end = xdp.data + len;
- buf = skb->data;
- }
-
- act = bpf_prog_run_xdp(xdp_prog, &xdp);
- switch (act) {
- case XDP_PASS:
- return XDP_PASS;
- case XDP_TX:
- qp = vi->curr_queue_pairs -
- vi->xdp_queue_pairs +
- smp_processor_id();
- xdp.data = buf;
- virtnet_xdp_xmit(vi, rq, &vi->sq[qp], &xdp, data);
- return XDP_TX;
- default:
- bpf_warn_invalid_xdp_action(act);
- case XDP_ABORTED:
- case XDP_DROP:
- return XDP_DROP;
- }
-}
-
static struct sk_buff *receive_small(struct net_device *dev,
struct virtnet_info *vi,
struct receive_queue *rq,
@@ -446,19 +403,30 @@ static struct sk_buff *receive_small(struct net_device *dev,
xdp_prog = rcu_dereference(rq->xdp_prog);
if (xdp_prog) {
struct virtio_net_hdr_mrg_rxbuf *hdr = buf;
+ struct xdp_buff xdp;
+ unsigned int qp;
u32 act;
if (unlikely(hdr->hdr.gso_type || hdr->hdr.flags))
goto err_xdp;
- act = do_xdp_prog(vi, rq, xdp_prog, skb, len);
+
+ xdp.data = skb->data;
+ xdp.data_end = xdp.data + len;
+ act = bpf_prog_run_xdp(xdp_prog, &xdp);
switch (act) {
case XDP_PASS:
break;
case XDP_TX:
+ qp = vi->curr_queue_pairs -
+ vi->xdp_queue_pairs +
+ smp_processor_id();
+ virtnet_xdp_xmit(vi, rq, &vi->sq[qp], &xdp, skb);
rcu_read_unlock();
goto xdp_xmit;
- case XDP_DROP:
default:
+ bpf_warn_invalid_xdp_action(act);
+ case XDP_ABORTED:
+ case XDP_DROP:
goto err_xdp;
}
}
@@ -575,7 +543,11 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
rcu_read_lock();
xdp_prog = rcu_dereference(rq->xdp_prog);
if (xdp_prog) {
+ int desc_room = sizeof(struct virtio_net_hdr_mrg_rxbuf);
struct page *xdp_page;
+ struct xdp_buff xdp;
+ unsigned int qp;
+ void *data;
u32 act;
/* This happens when rx buffer size is underestimated */
@@ -598,8 +570,10 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
if (unlikely(hdr->hdr.gso_type))
goto err_xdp;
- act = do_xdp_prog(vi, rq, xdp_prog,
- page_address(xdp_page) + offset, len);
+ data = page_address(xdp_page) + offset;
+ xdp.data = data + desc_room;
+ xdp.data_end = xdp.data + (len - vi->hdr_len);
+ act = bpf_prog_run_xdp(xdp_prog, &xdp);
switch (act) {
case XDP_PASS:
/* We can only create skb based on xdp_page. */
@@ -613,13 +587,19 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
}
break;
case XDP_TX:
+ qp = vi->curr_queue_pairs -
+ vi->xdp_queue_pairs +
+ smp_processor_id();
+ virtnet_xdp_xmit(vi, rq, &vi->sq[qp], &xdp, data);
ewma_pkt_len_add(&rq->mrg_avg_pkt_len, len);
if (unlikely(xdp_page != page))
goto err_xdp;
rcu_read_unlock();
goto xdp_xmit;
- case XDP_DROP:
default:
+ bpf_warn_invalid_xdp_action(act);
+ case XDP_ABORTED:
+ case XDP_DROP:
if (unlikely(xdp_page != page))
__free_pages(xdp_page, 0);
ewma_pkt_len_add(&rq->mrg_avg_pkt_len, len);
^ permalink raw reply related
* [net PATCH 2/5] net: virtio: wrap rtnl_lock in test for calling with lock already held
From: John Fastabend @ 2017-01-12 21:44 UTC (permalink / raw)
To: jasowang, mst
Cc: john.r.fastabend, netdev, john.fastabend, alexei.starovoitov,
daniel
In-Reply-To: <20170112213919.3039.54165.stgit@john-Precision-Tower-5810>
For XDP use case and to allow ethtool reset tests it is useful to be
able to use reset routines from contexts where rtnl lock is already
held.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
drivers/net/virtio_net.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index d97bb71..43cb2e0 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1864,12 +1864,13 @@ static void virtnet_free_queues(struct virtnet_info *vi)
kfree(vi->sq);
}
-static void free_receive_bufs(struct virtnet_info *vi)
+static void free_receive_bufs(struct virtnet_info *vi, bool need_lock)
{
struct bpf_prog *old_prog;
int i;
- rtnl_lock();
+ if (need_lock)
+ rtnl_lock();
for (i = 0; i < vi->max_queue_pairs; i++) {
while (vi->rq[i].pages)
__free_pages(get_a_page(&vi->rq[i], GFP_KERNEL), 0);
@@ -1879,7 +1880,8 @@ static void free_receive_bufs(struct virtnet_info *vi)
if (old_prog)
bpf_prog_put(old_prog);
}
- rtnl_unlock();
+ if (need_lock)
+ rtnl_unlock();
}
static void free_receive_page_frags(struct virtnet_info *vi)
@@ -2351,14 +2353,14 @@ static int virtnet_probe(struct virtio_device *vdev)
return err;
}
-static void remove_vq_common(struct virtnet_info *vi)
+static void remove_vq_common(struct virtnet_info *vi, bool lock)
{
vi->vdev->config->reset(vi->vdev);
/* Free unused buffers in both send and recv, if any. */
free_unused_bufs(vi);
- free_receive_bufs(vi);
+ free_receive_bufs(vi, lock);
free_receive_page_frags(vi);
@@ -2376,7 +2378,7 @@ static void virtnet_remove(struct virtio_device *vdev)
unregister_netdev(vi->dev);
- remove_vq_common(vi);
+ remove_vq_common(vi, true);
free_percpu(vi->stats);
free_netdev(vi->dev);
@@ -2401,7 +2403,7 @@ static int virtnet_freeze(struct virtio_device *vdev)
napi_disable(&vi->rq[i].napi);
}
- remove_vq_common(vi);
+ remove_vq_common(vi, true);
return 0;
}
^ permalink raw reply related
* [net PATCH 1/5] virtio_net: use dev_kfree_skb for small buffer XDP receive
From: John Fastabend @ 2017-01-12 21:43 UTC (permalink / raw)
To: jasowang, mst
Cc: john.r.fastabend, netdev, john.fastabend, alexei.starovoitov,
daniel
In-Reply-To: <20170112213919.3039.54165.stgit@john-Precision-Tower-5810>
In the small buffer case during driver unload we currently use
put_page instead of dev_kfree_skb. Resolve this by adding a check
for virtnet mode when checking XDP queue type. Also name the
function so that the code reads correctly to match the additional
check.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
drivers/net/virtio_net.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 4a10500..d97bb71 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1890,8 +1890,12 @@ static void free_receive_page_frags(struct virtnet_info *vi)
put_page(vi->rq[i].alloc_frag.page);
}
-static bool is_xdp_queue(struct virtnet_info *vi, int q)
+static bool is_xdp_raw_buffer_queue(struct virtnet_info *vi, int q)
{
+ /* For small receive mode always use kfree_skb variants */
+ if (!vi->mergeable_rx_bufs)
+ return false;
+
if (q < (vi->curr_queue_pairs - vi->xdp_queue_pairs))
return false;
else if (q < vi->curr_queue_pairs)
@@ -1908,7 +1912,7 @@ static void free_unused_bufs(struct virtnet_info *vi)
for (i = 0; i < vi->max_queue_pairs; i++) {
struct virtqueue *vq = vi->sq[i].vq;
while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) {
- if (!is_xdp_queue(vi, i))
+ if (!is_xdp_raw_buffer_queue(vi, i))
dev_kfree_skb(buf);
else
put_page(virt_to_head_page(buf));
^ permalink raw reply related
* [net PATCH 0/5] virtio_net XDP fixes and ajust_header xupport
From: John Fastabend @ 2017-01-12 21:43 UTC (permalink / raw)
To: jasowang, mst
Cc: john.r.fastabend, netdev, john.fastabend, alexei.starovoitov,
daniel
This has a fix to handle small buffer free logic correctly and then
also adds adjust head support.
I pushed adjust head at net (even though its rc3) to avoid having
to push another exception case into virtio_net to catch if the
program uses adjust_head and then block it. If there are any strong
objections to this we can push it at net-next and use a patch from
Jakub to add the exception handling but then user space has to deal
with it either via try/fail logic or via kernel version checks. Granted
we already have some cases that need to be configured to enable XDP
but I don't see any reason to have yet another one when we can fix it
now vs delaying a kernel version.
---
John Fastabend (5):
virtio_net: use dev_kfree_skb for small buffer XDP receive
net: virtio: wrap rtnl_lock in test for calling with lock already held
virtio_net: factor out xdp handler for readability
virtio_net: remove duplicate queue pair binding in XDP
virtio_net: XDP support for adjust_head
drivers/net/virtio_net.c | 251 ++++++++++++++++++++++++++++++++--------------
drivers/virtio/virtio.c | 9 +-
include/linux/virtio.h | 3 +
3 files changed, 183 insertions(+), 80 deletions(-)
^ permalink raw reply
* Re: Marvell Phy (1510) issue since v4.7 kernel
From: Russell King - ARM Linux @ 2017-01-12 21:41 UTC (permalink / raw)
To: Kwok, WingMan
Cc: Andrew Lunn, Karicheri, Muralidharan, netdev@vger.kernel.org
In-Reply-To: <230CBA6E4B6B6B418E8730AC28E6FC7E15354EB0@DFLE11.ent.ti.com>
On Thu, Jan 12, 2017 at 09:31:27PM +0000, Kwok, WingMan wrote:
>
> > > I double checked that ours is actually a 88E1514. According
> > > to Marvell's brief description, it seems that it does support
> > > fiber.
> > >
> > > Reading page 18 reg 30 returns 6.
> >
> > O.K, that is consistent. Looking at the Marvell SDK:
> >
> > phy/Include/madApiDefs.h:#define MAD_SUB_88E1510 4 /* 88E1510 */
> > phy/Include/madApiDefs.h:#define MAD_SUB_88E1518 5 /* 88E1518 */
> > phy/Include/madApiDefs.h:#define MAD_SUB_88E1512 6 /*
> > 88E1512/88E1514 */
> >
> > I took another look at the patch adding Fibre support. The
> > suspend/resume functions are wrong.
> >
> > /* Suspend the fiber mode first */
> > if (!(phydev->supported & SUPPORTED_FIBRE)) {
> >
> > The ! should not be there. Does removing them both fix your problem?
> >
>
> Hi Andrew,
>
> Thanks for taking the time to look into those patches. Yes we notice
> the error in the suspend/resume functions also.
>
> But our problem is caused by the read_status function:
>
> if ((phydev->supported & SUPPORTED_FIBRE)) {
> err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_FIBER);
> if (err < 0)
> goto error;
>
> err = marvell_read_status_page(phydev, MII_M1111_FIBER);
> if (err < 0)
> goto error;
>
> /* If the fiber link is up, it is the selected and used link.
> * In this case, we need to stay in the fiber page.
> * Please to be careful about that, avoid to restore Copper page
> * in other functions which could break the behaviour
> * for some fiber phy like 88E1512.
> * */
> if (phydev->link)
> return 0;
>
> which keeps the fiber page if phydev->link is true (for some
> reason this is the case even though we are not using fiber)
See below.
> However, this causes a problem in kernel reboot because neither
> the suspend/resume is called to restore the copper page and
> u-boot marvell phy driver does not support 1510 fiber, which
> will then result in writing to the wrong phy regs and causes
> a sgmii auto-nego time out.
So what we need to do is to have a .shutdown function installed - but
it's not that simple...
.mdiodrv = {
.driver = {
.shutdown = mv88e1512_shutdown,
},
},
in the appropriate phy_driver array element, and then have:
static void mv88e1512_shutdown(struct device *dev)
{
struct phy_device *phydev = to_phy_device(dev);
phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_COPPER);
}
which will restore the copper page on non-emergency reboots. For
emergency reboots, we're out of luck... the real fix would be for
uboot to ensure that when it detects this PHY, it ensures that the
right page is selected.
Now, that all said, there's a bug in this code, which is fixed by
a patch I recently submitted. If you have an 88E151x connected via
SGMII, then the read_status function incorrectly believes it should
be reading from the fiber page - when in fact the fiber page is
reporting the status of the host-side link. So, before trying the
above modification, please try this patch - it's already been merged
into the net tree, so should hit -rc soon.
My guess from what you've said above is that your 88E151x is connected
via SGMII, so you need the patch below rather than trying to install
a shutdown function.
8<====
From: Russell King <rmk+kernel@armlinux.org.uk>
Subject: [PATCH] net: phy: marvell: fix Marvell 88E1512 used in SGMII mode
When an Marvell 88E1512 PHY is connected to a nic in SGMII mode, the
fiber page is used for the SGMII host-side connection. The PHY driver
notices that SUPPORTED_FIBRE is set, so it tries reading the fiber page
for the link status, and ends up reading the MAC-side status instead of
the outgoing (copper) link. This leads to incorrect results reported
via ethtool.
If the PHY is connected via SGMII to the host, ignore the fiber page.
However, continue to allow the existing power management code to
suspend and resume the fiber page.
Fixes: 6cfb3bcc0641 ("Marvell phy: check link status in case of fiber link.")
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/marvell.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 6ad76829c7cd..04e439ad5cff 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -1190,7 +1190,8 @@ static int marvell_read_status(struct phy_device *phydev)
int err;
/* Check the fiber mode first */
- if (phydev->supported & SUPPORTED_FIBRE) {
+ if (phydev->supported & SUPPORTED_FIBRE &&
+ phydev->interface != PHY_INTERFACE_MODE_SGMII) {
err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_FIBER);
if (err < 0)
goto error;
--
2.7.4
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply related
* Re: [PATCH] tcp: fix tcp_fastopen unaligned access complaints on sparc
From: Eric Dumazet @ 2017-01-12 21:36 UTC (permalink / raw)
To: David Miller
Cc: shannon.nelson, rob.gardner, netdev, sparclinux, linux-kernel
In-Reply-To: <20170112.161852.1469407145449781531.davem@davemloft.net>
On Thu, 2017-01-12 at 16:18 -0500, David Miller wrote:
> From: Shannon Nelson <shannon.nelson@oracle.com>
> Date: Thu, 12 Jan 2017 12:56:08 -0800
>
> >
> >
> > On 1/12/2017 12:41 PM, David Miller wrote:
> >> From: Shannon Nelson <shannon.nelson@oracle.com>
> >> Date: Thu, 12 Jan 2017 12:30:38 -0800
> >>
> >>> On 1/12/2017 12:25 PM, Eric Dumazet wrote:
> >>>> On Thu, 2017-01-12 at 13:15 -0700, Rob Gardner wrote:
> >>>>
> >>>>>
> >>>>> I suspect that someplace, somebody is casting val to an int * or
> >>>>> something like that.
> >>>>
> >>>> Then that would be the bug. Can we root cause this please ?
> >>>>
> >>>>
> >>>
> >>> Look in net/ipv4/tcp_fastopen.c:tcp_fastopen_cookie_gen() for the line
> >>>
> >>> struct in6_addr *buf = (struct in6_addr *) tmp.val;
> >>
> >> Oh yeah, that's it. I didn't notice that at all.
> >>
> >
> > It looked to me like swapping the data fields would be the easiest and
> > least impactive way to fix this. I didn't want to mess with the
> > logic. I'm certainly open to other suggestions.
>
> Given the nature of the problem, your fix is probably fine.
>
> Eric, any objections?
I am still objecting to this fix.
gcc makes no provision for aligning an variable that has alignof() = 1
We had such issues in the past.
We need the proper annotation on ->val field itself, to get proper
alignment.
Then moving around the other field is a matter of avoiding a hole.
val should be an union, so that proper alignment is enforced by one
member.
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index fc5848dad7a43216b3f124c4afdaa6b64b23910c..5b790abf4c16313c9110996683be3a7fb368b66f 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -62,8 +62,13 @@ static inline unsigned int tcp_optlen(const struct sk_buff *skb)
/* TCP Fast Open Cookie as stored in memory */
struct tcp_fastopen_cookie {
+ union {
+ u8 val[TCP_FASTOPEN_COOKIE_MAX];
+#if IS_ENABLED(CONFIG_IPV6)
+ struct in6_addr addr;
+#endif
+ };
s8 len;
- u8 val[TCP_FASTOPEN_COOKIE_MAX];
bool exp; /* In RFC6994 experimental option format */
};
^ permalink raw reply related
* Re: [PATCH v2 2/2] stmmac: rename it to synopsys
From: Florian Fainelli @ 2017-01-12 19:42 UTC (permalink / raw)
To: Joao Pinto, davem
Cc: lars.persson, niklass, peppe.cavallaro, alexandre.torgue, netdev
In-Reply-To: <a2d2e457-47e5-bb73-a059-0cb907a29ae0@synopsys.com>
On 01/12/2017 01:43 AM, Joao Pinto wrote:
>
> First of all, I am suggesting an alternative way of organizing the code, and
> that's it, I have no second intentions about anything :).
>
> Please don't see this as a take-over or erase Stmicro from credits, please... it
> makes no sense. You can leave STMicro license and all the credits fine by me and
> I insist on it. But lets name it for something that makes sense... lets call it
> dwc (designware controllers), I am totally open to suggestions.
I don't understand how you reached this conclusion based on what I
wrote, but I have no concerns about take over or anything, and keep in
mind that maintainership is by nature a volatile thing. One day, a group
of people can be in charge of some piece of code, and in the future, it
could be another group of people, let's be agile.
>
> I don't understand the hostility of some comments, honestly.
It was not my intention to be hostile and I am sorry if this was how you
perceived it.
As an occasional contributor to netdev and the stmmac driver what I
welcome more than anything is more eyeballs and dedicated people
maintaining the driver, because it's always a good sign that there is
interesting in making the driver rock solid and feature full. As a
non-Linux kernel developer (OpenWrt/LEDE) what I care about is being
able to quickly backport fixes without going through too many hoops
(including driver rename, relocation etc.).
>
> The easiest way is to keep things like they are today, and believe me I have a
> lot of things to do, like adding the support of multi-queues / multi-channels to
> stmmac, so I not suggesting this because it is fun.
I believe this is what David is also asking for here.
>
> I am suggesting this because it is what I am used to seeing in other subsystems.
> USB has dwc2 and dwc3 folders that clearly identifies that they are Designware
> (synopsys) extensions to the USB 2.0 and 3.0. The author of dwc3 was Texas
> Instruments, and they did not name it ti/usb. For example I use an AXS101
> Development board that does not have a stmicro SoC but has a Designware Ethernet
> IP in it, so uses stmicro/stmmac. For me it is confusing.
The examples you are giving unfortunately unveil the same pattern: a
customer of the DWC/SNPS IP was first in the upstreaming business, and
because of that they were able to dictate how the initial submission
would look like, this was noticed, and you are now as a company
remedying that, and this is great!
There are ways to improve the situation to avoid the confusion:
- provide clear Kconfig help texts that indicate that the driver is not
just for STMicro but for SNPS IPs in general
- provide a Documentation/networking/ entry that explains the history,
why the driver remains with/has this name, and eventually technical
information about it
>
> Lets not name it synopsys, for me it is totally fine, but naming it
> stmicro/stmmac is not the right way because it seems like it is a driver just
> for stmicro products, which is not, is for products that use Designware Ethernet
> IPs.
>
> I am volunteering to do this work, let's discuss this.
I would focus on what has value: adding features, support for newer
versions of the IP and fixing bugs, not moving the code around which is
just fixing a cosmetic and historical problem, but not a functional
problem. By moving the code you are making the job of David and other
kernel maintainers dealing with -stable backports nearly impossible,
ultimately arming your relationship with the community over something
that is not considered an essential change.
Let me give you another example, when Broadcom sold its bnx2x LoB to
Qlogic, the driver was not renamed, nor moved, and now that Qlogic has
been acquired by Cavium, it still remains under the same directory. Yes,
it is presenting a singularity and is technically not correct, because
the IP now belongs to Cavium, but it is what it is for historical reasons.
--
Florian
^ permalink raw reply
* RE: Marvell Phy (1510) issue since v4.7 kernel
From: Kwok, WingMan @ 2017-01-12 21:31 UTC (permalink / raw)
To: Andrew Lunn
Cc: rmk+kernel@arm.linux.org.uk, Karicheri, Muralidharan,
netdev@vger.kernel.org
In-Reply-To: <20170112010658.GA25391@lunn.ch>
> > I double checked that ours is actually a 88E1514. According
> > to Marvell's brief description, it seems that it does support
> > fiber.
> >
> > Reading page 18 reg 30 returns 6.
>
> O.K, that is consistent. Looking at the Marvell SDK:
>
> phy/Include/madApiDefs.h:#define MAD_SUB_88E1510 4 /* 88E1510 */
> phy/Include/madApiDefs.h:#define MAD_SUB_88E1518 5 /* 88E1518 */
> phy/Include/madApiDefs.h:#define MAD_SUB_88E1512 6 /*
> 88E1512/88E1514 */
>
> I took another look at the patch adding Fibre support. The
> suspend/resume functions are wrong.
>
> /* Suspend the fiber mode first */
> if (!(phydev->supported & SUPPORTED_FIBRE)) {
>
> The ! should not be there. Does removing them both fix your problem?
>
Hi Andrew,
Thanks for taking the time to look into those patches. Yes we notice
the error in the suspend/resume functions also.
But our problem is caused by the read_status function:
if ((phydev->supported & SUPPORTED_FIBRE)) {
err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_FIBER);
if (err < 0)
goto error;
err = marvell_read_status_page(phydev, MII_M1111_FIBER);
if (err < 0)
goto error;
/* If the fiber link is up, it is the selected and used link.
* In this case, we need to stay in the fiber page.
* Please to be careful about that, avoid to restore Copper page
* in other functions which could break the behaviour
* for some fiber phy like 88E1512.
* */
if (phydev->link)
return 0;
which keeps the fiber page if phydev->link is true (for some
reason this is the case even though we are not using fiber)
However, this causes a problem in kernel reboot because neither
the suspend/resume is called to restore the copper page and
u-boot marvell phy driver does not support 1510 fiber, which
will then result in writing to the wrong phy regs and causes
a sgmii auto-nego time out.
In addition to fixing the ! in suspend/resume, my suggestion
would be to change also the read_status function to
always restore the copper page after doing the fiber stuffs:
if ((phydev->supported & SUPPORTED_FIBRE)) {
err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_FIBER);
if (err < 0)
goto error;
err = marvell_read_status_page(phydev, MII_M1111_FIBER);
if (err < 0)
goto error;
err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_COPPER);
if (err < 0)
goto error;
/* If the fiber link is up, it is the selected and used link.
* In this case, we need to stay in the fiber page.
* Please to be careful about that, avoid to restore Copper page
* in other functions which could break the behaviour
* for some fiber phy like 88E1512.
* */
if (phydev->link)
return 0;
This makes sure that it is always the copper page brought up
and whenever it needs to do some fiber stuffs, the fiber page
needs to be brought out explicitly, which is already the case
currently.
Another issue is that, as of now, FIBER is enabled regardless
of the specific 88e151x. But I believe there is 88e151x chip(s)
that does not support fiber. Should fiber be enabled only for
those that do support fiber?
WingMan
^ permalink raw reply
* Re: kill off pci_enable_msi_{exact,range}
From: Bjorn Helgaas @ 2017-01-12 21:29 UTC (permalink / raw)
To: Christoph Hellwig
Cc: linux-pci, Mauro Carvalho Chehab, netdev, linux-media,
Tom Lendacky
In-Reply-To: <1483994260-19797-1-git-send-email-hch@lst.de>
On Mon, Jan 09, 2017 at 09:37:37PM +0100, Christoph Hellwig wrote:
> I had hope that we could kill these old interfaces of for 4.10-rc,
> but as of today Linus tree still has two users:
>
> (1) the cobalt media driver, for which I sent a patch long time ago,
> it got missed in the merge window.
> (2) the new xgbe driver was merged in 4.10-rc but used the old interfaces
> anyway
>
> This series resend the patch for (1) and adds a new one for (2), as well
> as having the final removal patch behind it. Maybe we should just queue
> up all three together in the PCI tree for 4.11?
Applied all three (with Tom's ack on the amd-xgbe patch) to pci/msi for
v4.11, thanks!
^ permalink raw reply
* Re: [PATCH net-next v2 05/10] drivers: base: Add device_find_class()
From: David Miller @ 2017-01-12 21:21 UTC (permalink / raw)
To: f.fainelli
Cc: netdev, jason, andrew, sebastian.hesselbarth, gregory.clement,
linux, vivien.didelot, linux-arm-kernel, linux-kernel, gregkh
In-Reply-To: <20170112034121.27697-6-f.fainelli@gmail.com>
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Wed, 11 Jan 2017 19:41:16 -0800
> Add a helper function to lookup a device reference given a class name.
> This is a preliminary patch to remove adhoc code from net/dsa/dsa.c and
> make it more generic.
>
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
> drivers/base/core.c | 19 +++++++++++++++++++
> include/linux/device.h | 1 +
> 2 files changed, 20 insertions(+)
>
> diff --git a/drivers/base/core.c b/drivers/base/core.c
> index 020ea7f05520..3dd6047c10d8 100644
> --- a/drivers/base/core.c
> +++ b/drivers/base/core.c
> @@ -2065,6 +2065,25 @@ struct device *device_find_child(struct device *parent, void *data,
> }
> EXPORT_SYMBOL_GPL(device_find_child);
>
> +static int dev_is_class(struct device *dev, void *class)
I know you are just moving code, but this class argumnet is a string
and thus should be "char *" or even "const char *".
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox