* [PATCH 1/2] qed: Replace memset with eth_zero_addr
From: Shyam Saini @ 2017-01-16 3:44 UTC (permalink / raw)
To: Yuval.Mintz; +Cc: Ariel.Elior, everest-linux-l2, netdev, Shyam Saini
Use eth_zero_addr to assign zero address to the given address array
instead of memset when the second argument in memset is address
of zero. Also, it makes the code clearer
Signed-off-by: Shyam Saini <mayhs11saini@gmail.com>
---
drivers/net/ethernet/qlogic/qed/qed_l2.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_l2.c b/drivers/net/ethernet/qlogic/qed/qed_l2.c
index 6a3727c..778c52c 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_l2.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_l2.c
@@ -1776,7 +1776,7 @@ static int qed_fill_eth_dev_info(struct qed_dev *cdev,
qed_fill_dev_info(cdev, &info->common);
if (IS_VF(cdev))
- memset(info->common.hw_mac, 0, ETH_ALEN);
+ eth_zero_addr(info->common.hw_mac);
return 0;
}
--
2.7.4
^ permalink raw reply related
* Re: [PATCH net] openvswitch: maintain correct checksum state in conntrack actions
From: David Miller @ 2017-01-16 3:16 UTC (permalink / raw)
To: lrichard; +Cc: netdev, dev
In-Reply-To: <1484267598-4493-1-git-send-email-lrichard@redhat.com>
From: Lance Richardson <lrichard@redhat.com>
Date: Thu, 12 Jan 2017 19:33:18 -0500
> When executing conntrack actions on skbuffs with checksum mode
> CHECKSUM_COMPLETE, the checksum must be updated to account for
> header pushes and pulls. Otherwise we get "hw csum failure"
> logs similar to this (ICMP packet received on geneve tunnel
> via ixgbe NIC):
...
> Fixes: 7f8a436eaa2c ("openvswitch: Add conntrack action")
> Signed-off-by: Lance Richardson <lrichard@redhat.com>
Applied and queued up for -stable.
^ permalink raw reply
* Re: [patch net-next] stmmac: indent an if statement
From: David Miller @ 2017-01-16 3:14 UTC (permalink / raw)
To: dan.carpenter
Cc: peppe.cavallaro, Joao.Pinto, alexandre.torgue, netdev,
linux-kernel, kernel-janitors
In-Reply-To: <20170112184631.GA12157@mwanda>
From: Dan Carpenter <dan.carpenter@oracle.com>
Date: Thu, 12 Jan 2017 21:46:32 +0300
> The break statement should be indented one more tab.
>
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Applied, but like Julia I think we might have a missing of_node_put()
here.
^ permalink raw reply
* Re: [PATCH] synopsys: remove dwc_eth_qos driver
From: David Miller @ 2017-01-16 3:12 UTC (permalink / raw)
To: Joao.Pinto
Cc: lars.persson, niklass, peppe.cavallaro, alexandre.torgue, netdev
In-Reply-To: <2d50f9fea61de2eb082b217d435334d40e3e01ad.1484214626.git.jpinto@synopsys.com>
From: Joao Pinto <Joao.Pinto@synopsys.com>
Date: Thu, 12 Jan 2017 09:56:18 +0000
> This driver is no longer necessary since it was merged into stmmac.
>
> Acked-by: Lars Persson <larper@axis.com>
> Signed-off-by: Joao Pinto <jpinto@synopsys.com>
Applied.
^ permalink raw reply
* (unknown),
From: unsubscribe.me @ 2017-01-16 2:18 UTC (permalink / raw)
To: netdev
[-- Attachment #1: EMAIL_33007_netdev.zip --]
[-- Type: application/zip, Size: 25 bytes --]
^ permalink raw reply
* Re: Potential issues (security and otherwise) with the current cgroup-bpf API
From: Tejun Heo @ 2017-01-16 1:19 UTC (permalink / raw)
To: Michal Hocko
Cc: Peter Zijlstra, Andy Lutomirski, David Ahern, Alexei Starovoitov,
Andy Lutomirski, Daniel Mack, Mickaël Salaün, Kees Cook,
Jann Horn, David S. Miller, Thomas Graf, Michael Kerrisk,
Linux API, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Network Development
In-Reply-To: <20170103102559.GA30129-2MMpYkNvuYDjFM9bn6wA6Q@public.gmane.org>
Hello,
Sorry about the delay. Some fire fighthing followed the holidays.
On Tue, Jan 03, 2017 at 11:25:59AM +0100, Michal Hocko wrote:
> > So from what I understand the proposed cgroup is not in fact
> > hierarchical at all.
> >
> > @TJ, I thought you were enforcing all new cgroups to be properly
> > hierarchical, that would very much include this one.
>
> I would be interested in that as well. We have made that mistake in
> memcg v1 where hierarchy could be disabled for performance reasons and
> that turned out to be major PITA in the end. Why do we want to repeat
> the same mistake here?
Across the different threads on this subject, there have been multiple
explanations but I'll try to sum it up more clearly.
The big issue here is whether this is a cgroup thing or a bpf thing.
I don't think there's anything inherently wrong with one approach or
the other. Forget about the proposed cgroup bpf extentions but thinkg
about how iptables does cgroups. Whether it's the netcls/netprio in
v1 or direct membership matching in v2, it is the network side testing
for cgroup membership one way or the other. The only part where
cgroup is involved in is answering that test.
This also holds true for the perf controller. While it is implemented
as a controller, it isn't visible to cgroup users in any way and the
only function it serves is providing the membership test to perf
subsystem. perf is the one which decides whether and how it is to be
used. cgroup providing membership test to other subsystems is
completely acceptable and established.
Now coming back to bpf, the current implementation is just that.
Sure, cgroup hosts the rules in its data structures but that isn't
something conceptually relevant. We might as well implement it as a
prefixed hash table from bpf side. Having pointers in struct cgroup
is just a more efficient and easier way of achieving the same result.
In fact, IIUC, this whole thing was born out of discussions around
implementing scalable cgroup membership matching from bpf programs.
So, what's proposed is a proper part of bpf. In terms of
implementation, cgroup helps by hosting the pointers but that doesn't
necessarily affect the conceptual structure of it. Given that, I
don't think it'd be a good idea to add anything to cgroup interface
for this feature. Introspection is great to have but this should be
introspectable together with other bpf programs using the same
mechanism. That's where it belongs.
None of the issues that people have been raising here is actually an
issue if one thinks of it as a part of bpf. Its security model is
exactly the same as any other bpf programs. Recursive behavior is
exactly the same as how other external cgroup descendant membership
testing work. There is no issue here whatsoever.
Now, I'm not claiming that a bpf mechanism which is a proper part of
cgrou isn't attractive. It is, especially with delegation; however,
that is also where we don't quite know how to proceed. This doesn't
have much to do with cgroup. If something is delegatable to non-priv
users and scoped, cgroup's fine with it and if that's not possible it
simply isn't something which is delegatable and putting it on cgroup
doesn't change that.
I'm far from being a bpf expert, so I could be wrong here, but I don't
think there's anything fundamental which prevents bpf from being
delegatable but at the same time bpf is something which is extremely
flexible and nobody really thought about or worked that much on
delegating bpf. If there's enough need for it, I'm sure we'll
eventually get there but from what I hear it isn't something we can
pull off in a restricted timeframe.
There's nothing which makes the currently implemented mechanism
exclusive with a cgroup controller based one. The hooks are the
expensive part but can be shared, the rest is just about which
programs to execute in what order and how they should be chained.
There are a lot of immediate use cases which can benefit from the
proposed cgroup bpf mechanism and they're all fine with it being a
part of bpf and behaving like any other network mechanism behaves in
terms of configuration and delegation. I don't see a reason why we
would hold back on merging this. All the raised issues are coming
from confusing this as a part of cgroup. It isn't. It is a part of
bpf. If we want a bpf cgroup controller, great, but that is a
separate thing.
Thanks.
--
tejun
^ permalink raw reply
* [net PATCH v4 6/6] virtio_net: XDP support for adjust_head
From: John Fastabend @ 2017-01-16 0:01 UTC (permalink / raw)
To: jasowang, mst
Cc: john.r.fastabend, netdev, john.fastabend, alexei.starovoitov,
daniel
In-Reply-To: <20170115235528.28980.85142.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 | 110 ++++++++++++++++++++++++++++++++++------------
1 file changed, 82 insertions(+), 28 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index ac853b9..2cc59db 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -41,6 +41,9 @@
#define GOOD_PACKET_LEN (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN)
#define GOOD_COPY_LEN 128
+/* Amount of XDP headroom to prepend to packets for use by xdp_adjust_head */
+#define VIRTIO_XDP_HEADROOM 256
+
/* RX packet size EWMA. The average packet size is used to determine the packet
* buffer size when refilling RX rings. As the entire RX ring may be refilled
* at once, the weight is chosen so that the EWMA will be insensitive to short-
@@ -359,6 +362,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 +379,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 +407,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 +418,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 + VIRTIO_XDP_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 */
+ __skb_pull(skb, xdp.data - xdp.data_hard_start);
+ len = xdp.data_end - xdp.data;
break;
case XDP_TX:
virtnet_xdp_xmit(vi, rq, &xdp, skb);
@@ -432,6 +441,7 @@ static struct sk_buff *receive_small(struct net_device *dev,
}
rcu_read_unlock();
+ skb_trim(skb, len);
return skb;
err_xdp:
@@ -480,7 +490,7 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
unsigned int *len)
{
struct page *page = alloc_page(GFP_ATOMIC);
- unsigned int page_off = 0;
+ unsigned int page_off = VIRTIO_XDP_HEADROOM;
if (!page)
return NULL;
@@ -516,7 +526,8 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
put_page(p);
}
- *len = page_off;
+ /* Headroom does not contribute to packet length */
+ *len = page_off - VIRTIO_XDP_HEADROOM;
return page;
err_buf:
__free_pages(page, 0);
@@ -555,7 +566,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
page, offset, &len);
if (!xdp_page)
goto err_xdp;
- offset = 0;
+ offset = VIRTIO_XDP_HEADROOM;
} else {
xdp_page = page;
}
@@ -568,18 +579,29 @@ 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 - VIRTIO_XDP_HEADROOM + vi->hdr_len;
xdp.data = data + vi->hdr_len;
xdp.data_end = xdp.data + (len - vi->hdr_len);
act = bpf_prog_run_xdp(xdp_prog, &xdp);
switch (act) {
case XDP_PASS:
+ /* recalculate offset to account for any header
+ * adjustments. Note other cases do not build an
+ * skb and avoid using offset
+ */
+ offset = xdp.data -
+ page_address(xdp_page) - vi->hdr_len;
+
/* We can only create skb based on xdp_page. */
if (unlikely(xdp_page != page)) {
rcu_read_unlock();
put_page(page);
head_skb = page_to_skb(vi, rq, xdp_page,
- 0, len, PAGE_SIZE);
+ offset, len, PAGE_SIZE);
ewma_pkt_len_add(&rq->mrg_avg_pkt_len, len);
return head_skb;
}
@@ -744,23 +766,30 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
dev_kfree_skb(skb);
}
+static unsigned int virtnet_get_headroom(struct virtnet_info *vi)
+{
+ return vi->xdp_queue_pairs ? VIRTIO_XDP_HEADROOM : 0;
+}
+
static int add_recvbuf_small(struct virtnet_info *vi, struct receive_queue *rq,
gfp_t gfp)
{
+ int headroom = GOOD_PACKET_LEN + virtnet_get_headroom(vi);
+ unsigned int xdp_headroom = virtnet_get_headroom(vi);
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, xdp_headroom, skb->len - xdp_headroom);
err = virtqueue_add_inbuf(rq->vq, rq->sg, 2, skb, gfp);
if (err < 0)
@@ -828,24 +857,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 = virtnet_get_headroom(vi);
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
@@ -879,7 +911,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
@@ -1689,7 +1721,7 @@ 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;
+ u16 oxdp_qp, xdp_qp = 0, curr_qp;
int i, err;
if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO4) ||
@@ -1721,21 +1753,32 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog)
return -ENOMEM;
}
+ if (prog) {
+ prog = bpf_prog_add(prog, vi->max_queue_pairs - 1);
+ if (IS_ERR(prog))
+ return PTR_ERR(prog);
+ }
+
err = _virtnet_set_queues(vi, curr_qp + xdp_qp);
if (err) {
dev_warn(&dev->dev, "XDP Device queue allocation failure.\n");
- return err;
+ goto virtio_queue_err;
}
- if (prog) {
- prog = bpf_prog_add(prog, vi->max_queue_pairs - 1);
- if (IS_ERR(prog)) {
- _virtnet_set_queues(vi, curr_qp);
- return PTR_ERR(prog);
- }
+ oxdp_qp = vi->xdp_queue_pairs;
+
+ /* 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 resulting in number of XDP queues changing.
+ */
+ if (vi->xdp_queue_pairs != xdp_qp) {
+ vi->xdp_queue_pairs = xdp_qp;
+ err = virtio_device_reset(vi->vdev);
+ if (err)
+ goto virtio_reset_err;
}
- vi->xdp_queue_pairs = xdp_qp;
netif_set_real_num_rx_queues(dev, curr_qp + xdp_qp);
for (i = 0; i < vi->max_queue_pairs; i++) {
@@ -1746,6 +1789,21 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog)
}
return 0;
+
+virtio_reset_err:
+ /* On reset error do our best to unwind XDP changes inflight and return
+ * error up to user space for resolution. The underlying PCI reset hung
+ * on us so not much we can do here.
+ */
+ dev_warn(&dev->dev, "XDP reset failure and queues unstable\n");
+ vi->xdp_queue_pairs = oxdp_qp;
+virtio_queue_err:
+ /* On queue set error we can unwind bpf ref count and user space can
+ * retry this is most likely an allocation failure.
+ */
+ if (prog)
+ bpf_prog_sub(prog, vi->max_queue_pairs - 1);
+ return err;
}
static bool virtnet_xdp_query(struct net_device *dev)
@@ -2373,7 +2431,6 @@ static void virtnet_remove(struct virtio_device *vdev)
free_netdev(vi->dev);
}
-#ifdef CONFIG_PM_SLEEP
static int virtnet_freeze(struct virtio_device *vdev)
{
struct virtnet_info *vi = vdev->priv;
@@ -2430,7 +2487,6 @@ static int virtnet_restore(struct virtio_device *vdev)
return 0;
}
-#endif
static struct virtio_device_id id_table[] = {
{ VIRTIO_ID_NET, VIRTIO_DEV_ANY_ID },
@@ -2470,10 +2526,8 @@ static int virtnet_restore(struct virtio_device *vdev)
.probe = virtnet_probe,
.remove = virtnet_remove,
.config_changed = virtnet_config_changed,
-#ifdef CONFIG_PM_SLEEP
.freeze = virtnet_freeze,
.restore = virtnet_restore,
-#endif
};
static __init int virtio_net_driver_init(void)
^ permalink raw reply related
* [net PATCH v4 5/6] virtio: add pci_down/pci_up configuration
From: John Fastabend @ 2017-01-16 0:01 UTC (permalink / raw)
To: jasowang, mst
Cc: john.r.fastabend, netdev, john.fastabend, alexei.starovoitov,
daniel
In-Reply-To: <20170115235528.28980.85142.stgit@john-Precision-Tower-5810>
In virtio_net we need to do a full reset of the device to support
queue reconfiguration and also we can trigger this via ethtool
commands. So instead of open coding this in net driver push this
into generic code in virtio. This also avoid exporting a handful
of internal virtio routines.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
drivers/virtio/virtio.c | 14 ++++++++++++--
drivers/virtio/virtio_balloon.c | 4 ----
drivers/virtio/virtio_input.c | 4 ----
include/linux/virtio.h | 5 +----
4 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 7062bb0..681fcfb 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -339,7 +339,6 @@ void unregister_virtio_device(struct virtio_device *dev)
}
EXPORT_SYMBOL_GPL(unregister_virtio_device);
-#ifdef CONFIG_PM_SLEEP
int virtio_device_freeze(struct virtio_device *dev)
{
struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
@@ -400,7 +399,18 @@ int virtio_device_restore(struct virtio_device *dev)
return ret;
}
EXPORT_SYMBOL_GPL(virtio_device_restore);
-#endif
+
+int virtio_device_reset(struct virtio_device *dev)
+{
+ int err;
+
+ err = virtio_device_freeze(dev);
+ if (err)
+ return err;
+
+ return virtio_device_restore(dev);
+}
+EXPORT_SYMBOL_GPL(virtio_device_reset);
static int virtio_init(void)
{
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 181793f..4ca6220 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -620,7 +620,6 @@ static void virtballoon_remove(struct virtio_device *vdev)
kfree(vb);
}
-#ifdef CONFIG_PM_SLEEP
static int virtballoon_freeze(struct virtio_device *vdev)
{
struct virtio_balloon *vb = vdev->priv;
@@ -649,7 +648,6 @@ static int virtballoon_restore(struct virtio_device *vdev)
update_balloon_size(vb);
return 0;
}
-#endif
static unsigned int features[] = {
VIRTIO_BALLOON_F_MUST_TELL_HOST,
@@ -666,10 +664,8 @@ static int virtballoon_restore(struct virtio_device *vdev)
.probe = virtballoon_probe,
.remove = virtballoon_remove,
.config_changed = virtballoon_changed,
-#ifdef CONFIG_PM_SLEEP
.freeze = virtballoon_freeze,
.restore = virtballoon_restore,
-#endif
};
module_virtio_driver(virtio_balloon_driver);
diff --git a/drivers/virtio/virtio_input.c b/drivers/virtio/virtio_input.c
index 350a2a5..d3517e2 100644
--- a/drivers/virtio/virtio_input.c
+++ b/drivers/virtio/virtio_input.c
@@ -328,7 +328,6 @@ static void virtinput_remove(struct virtio_device *vdev)
kfree(vi);
}
-#ifdef CONFIG_PM_SLEEP
static int virtinput_freeze(struct virtio_device *vdev)
{
struct virtio_input *vi = vdev->priv;
@@ -356,7 +355,6 @@ static int virtinput_restore(struct virtio_device *vdev)
virtinput_fill_evt(vi);
return 0;
}
-#endif
static unsigned int features[] = {
/* none */
@@ -374,10 +372,8 @@ static int virtinput_restore(struct virtio_device *vdev)
.id_table = id_table,
.probe = virtinput_probe,
.remove = virtinput_remove,
-#ifdef CONFIG_PM_SLEEP
.freeze = virtinput_freeze,
.restore = virtinput_restore,
-#endif
};
module_virtio_driver(virtio_input_driver);
diff --git a/include/linux/virtio.h b/include/linux/virtio.h
index d5eb547..ff69f9a 100644
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -138,10 +138,9 @@ static inline struct virtio_device *dev_to_virtio(struct device *_dev)
void virtio_break_device(struct virtio_device *dev);
void virtio_config_changed(struct virtio_device *dev);
-#ifdef CONFIG_PM_SLEEP
int virtio_device_freeze(struct virtio_device *dev);
int virtio_device_restore(struct virtio_device *dev);
-#endif
+int virtio_device_reset(struct virtio_device *dev);
/**
* virtio_driver - operations for a virtio I/O driver
@@ -167,10 +166,8 @@ struct virtio_driver {
void (*scan)(struct virtio_device *dev);
void (*remove)(struct virtio_device *dev);
void (*config_changed)(struct virtio_device *dev);
-#ifdef CONFIG_PM
int (*freeze)(struct virtio_device *dev);
int (*restore)(struct virtio_device *dev);
-#endif
};
static inline struct virtio_driver *drv_to_virtio(struct device_driver *drv)
^ permalink raw reply related
* [net PATCH v4 4/6] virtio_net: remove duplicate queue pair binding in XDP
From: John Fastabend @ 2017-01-16 0:00 UTC (permalink / raw)
To: jasowang, mst
Cc: john.r.fastabend, netdev, john.fastabend, alexei.starovoitov,
daniel
In-Reply-To: <20170115235528.28980.85142.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 7dda206..ac853b9 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:
@@ -545,7 +545,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
if (xdp_prog) {
struct page *xdp_page;
struct xdp_buff xdp;
- unsigned int qp;
void *data;
u32 act;
@@ -586,10 +585,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 v4 3/6] virtio_net: factor out xdp handler for readability
From: John Fastabend @ 2017-01-16 0:00 UTC (permalink / raw)
To: jasowang, mst
Cc: john.r.fastabend, netdev, john.fastabend, alexei.starovoitov,
daniel
In-Reply-To: <20170115235528.28980.85142.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 | 75 +++++++++++++++++-----------------------------
1 file changed, 27 insertions(+), 48 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index bc3b1f8..7dda206 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;
}
}
@@ -576,6 +544,9 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
xdp_prog = rcu_dereference(rq->xdp_prog);
if (xdp_prog) {
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 +569,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 + vi->hdr_len;
+ 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 +586,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 v4 2/6] virtio_net: wrap rtnl_lock in test for calling with lock already held
From: John Fastabend @ 2017-01-15 23:59 UTC (permalink / raw)
To: jasowang, mst
Cc: john.r.fastabend, netdev, john.fastabend, alexei.starovoitov,
daniel
In-Reply-To: <20170115235528.28980.85142.stgit@john-Precision-Tower-5810>
For XDP use case and to allow ethtool reset tests it is useful to be
able to use reset paths from contexts where rtnl lock is already
held.
This requries updating virtnet_set_queues and free_receive_bufs the
two places where rtnl_lock is taken in virtio_net. To do this we
use the following pattern,
_foo(...) { do stuff }
foo(...) { rtnl_lock(); _foo(...); rtnl_unlock()};
And then in locations that were previously locked,
if (is_rtnl_locked()) _foo(); else foo();
this allows us to use freeze()/restore() flow from both contexts.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
drivers/net/virtio_net.c | 41 +++++++++++++++++++++++++++++------------
1 file changed, 29 insertions(+), 12 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index d97bb71..bc3b1f8 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1331,7 +1331,7 @@ static void virtnet_ack_link_announce(struct virtnet_info *vi)
rtnl_unlock();
}
-static int virtnet_set_queues(struct virtnet_info *vi, u16 queue_pairs)
+static int _virtnet_set_queues(struct virtnet_info *vi, u16 queue_pairs)
{
struct scatterlist sg;
struct net_device *dev = vi->dev;
@@ -1357,6 +1357,16 @@ static int virtnet_set_queues(struct virtnet_info *vi, u16 queue_pairs)
return 0;
}
+static int virtnet_set_queues(struct virtnet_info *vi, u16 queue_pairs)
+{
+ int err;
+
+ rtnl_lock();
+ err = _virtnet_set_queues(vi, queue_pairs);
+ rtnl_unlock();
+ return err;
+}
+
static int virtnet_close(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
@@ -1609,7 +1619,7 @@ static int virtnet_set_channels(struct net_device *dev,
return -EINVAL;
get_online_cpus();
- err = virtnet_set_queues(vi, queue_pairs);
+ err = _virtnet_set_queues(vi, queue_pairs);
if (!err) {
netif_set_real_num_tx_queues(dev, queue_pairs);
netif_set_real_num_rx_queues(dev, queue_pairs);
@@ -1736,7 +1746,7 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog)
return -ENOMEM;
}
- err = virtnet_set_queues(vi, curr_qp + xdp_qp);
+ err = _virtnet_set_queues(vi, curr_qp + xdp_qp);
if (err) {
dev_warn(&dev->dev, "XDP Device queue allocation failure.\n");
return err;
@@ -1745,7 +1755,7 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog)
if (prog) {
prog = bpf_prog_add(prog, vi->max_queue_pairs - 1);
if (IS_ERR(prog)) {
- virtnet_set_queues(vi, curr_qp);
+ _virtnet_set_queues(vi, curr_qp);
return PTR_ERR(prog);
}
}
@@ -1864,12 +1874,11 @@ 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)
{
struct bpf_prog *old_prog;
int i;
- 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,6 +1888,12 @@ static void free_receive_bufs(struct virtnet_info *vi)
if (old_prog)
bpf_prog_put(old_prog);
}
+}
+
+static void free_receive_bufs(struct virtnet_info *vi)
+{
+ rtnl_lock();
+ _free_receive_bufs(vi);
rtnl_unlock();
}
@@ -2317,9 +2332,7 @@ static int virtnet_probe(struct virtio_device *vdev)
goto free_unregister_netdev;
}
- rtnl_lock();
virtnet_set_queues(vi, vi->curr_queue_pairs);
- rtnl_unlock();
/* Assume link up if device can't report link status,
otherwise get link status from config. */
@@ -2358,7 +2371,10 @@ static void remove_vq_common(struct virtnet_info *vi)
/* Free unused buffers in both send and recv, if any. */
free_unused_bufs(vi);
- free_receive_bufs(vi);
+ if (rtnl_is_locked())
+ _free_receive_bufs(vi);
+ else
+ free_receive_bufs(vi);
free_receive_page_frags(vi);
@@ -2428,9 +2444,10 @@ static int virtnet_restore(struct virtio_device *vdev)
netif_device_attach(vi->dev);
- rtnl_lock();
- virtnet_set_queues(vi, vi->curr_queue_pairs);
- rtnl_unlock();
+ if (rtnl_is_locked())
+ _virtnet_set_queues(vi, vi->curr_queue_pairs);
+ else
+ virtnet_set_queues(vi, vi->curr_queue_pairs);
err = virtnet_cpu_notif_add(vi);
if (err)
^ permalink raw reply related
* [net PATCH v4 1/6] virtio_net: use dev_kfree_skb for small buffer XDP receive
From: John Fastabend @ 2017-01-15 23:59 UTC (permalink / raw)
To: jasowang, mst
Cc: john.r.fastabend, netdev, john.fastabend, alexei.starovoitov,
daniel
In-Reply-To: <20170115235528.28980.85142.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.
Fixes: bb91accf2733 ("virtio-net: XDP support for small buffers")
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Acked-by: Jason Wang <jasowang@redhat.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 v4 0/6] virtio_net XDP fixes and adjust_header support
From: John Fastabend @ 2017-01-15 23:59 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.
v2: fix spelling error, convert unsigned -> unsigned int
v3: v2 git crashed during send so retrying sorry for the noise
v4: changed layout of rtnl_lock fixes (Stephen)
moved reset logic into virtio core with new patch (MST)
fixed up linearize and some code cleanup (Jason)
Otherwise did some generic code cleanup so might be a bit
cleaner this time at least that is the hope.
Thanks everyone for the v3 review.
---
John Fastabend (6):
virtio_net: use dev_kfree_skb for small buffer XDP receive
virtio_net: 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: add pci_down/pci_up configuration
virtio_net: XDP support for adjust_head
drivers/net/virtio_net.c | 228 ++++++++++++++++++++++++---------------
drivers/virtio/virtio.c | 14 ++
drivers/virtio/virtio_balloon.c | 4 -
drivers/virtio/virtio_input.c | 4 -
include/linux/virtio.h | 5 -
5 files changed, 152 insertions(+), 103 deletions(-)
^ permalink raw reply
* [PATCH] net: jme: use new api ethtool_{get|set}_link_ksettings
From: Philippe Reynes @ 2017-01-15 22:18 UTC (permalink / raw)
To: cooldavid, davem; +Cc: netdev, linux-kernel, Philippe Reynes
The ethtool api {get|set}_settings is deprecated.
We move this driver to new api {get|set}_link_ksettings.
As I don't have the hardware, I'd be very pleased if
someone may test this patch.
Signed-off-by: Philippe Reynes <tremyfr@gmail.com>
---
drivers/net/ethernet/jme.c | 34 +++++++++++++++++-----------------
drivers/net/ethernet/jme.h | 6 +++---
2 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c
index f9fcab5..f580b49 100644
--- a/drivers/net/ethernet/jme.c
+++ b/drivers/net/ethernet/jme.c
@@ -1879,7 +1879,7 @@
jme_phy_on(jme);
if (test_bit(JME_FLAG_SSET, &jme->flags))
- jme_set_settings(netdev, &jme->old_ecmd);
+ jme_set_link_ksettings(netdev, &jme->old_cmd);
else
jme_reset_phy_processor(jme);
jme_phy_calibration(jme);
@@ -2374,7 +2374,7 @@ static void jme_drop_tx_map(struct jme_adapter *jme, int startidx, int count)
jme->phylink = 0;
jme_reset_phy_processor(jme);
if (test_bit(JME_FLAG_SSET, &jme->flags))
- jme_set_settings(netdev, &jme->old_ecmd);
+ jme_set_link_ksettings(netdev, &jme->old_cmd);
/*
* Force to Reset the link again
@@ -2648,27 +2648,27 @@ static inline void jme_resume_rx(struct jme_adapter *jme)
}
static int
-jme_get_settings(struct net_device *netdev,
- struct ethtool_cmd *ecmd)
+jme_get_link_ksettings(struct net_device *netdev,
+ struct ethtool_link_ksettings *cmd)
{
struct jme_adapter *jme = netdev_priv(netdev);
int rc;
spin_lock_bh(&jme->phy_lock);
- rc = mii_ethtool_gset(&(jme->mii_if), ecmd);
+ rc = mii_ethtool_get_link_ksettings(&jme->mii_if, cmd);
spin_unlock_bh(&jme->phy_lock);
return rc;
}
static int
-jme_set_settings(struct net_device *netdev,
- struct ethtool_cmd *ecmd)
+jme_set_link_ksettings(struct net_device *netdev,
+ const struct ethtool_link_ksettings *cmd)
{
struct jme_adapter *jme = netdev_priv(netdev);
int rc, fdc = 0;
- if (ethtool_cmd_speed(ecmd) == SPEED_1000
- && ecmd->autoneg != AUTONEG_ENABLE)
+ if (cmd->base.speed == SPEED_1000 &&
+ cmd->base.autoneg != AUTONEG_ENABLE)
return -EINVAL;
/*
@@ -2676,18 +2676,18 @@ static inline void jme_resume_rx(struct jme_adapter *jme)
* Hardware would not generate link change interrupt.
*/
if (jme->mii_if.force_media &&
- ecmd->autoneg != AUTONEG_ENABLE &&
- (jme->mii_if.full_duplex != ecmd->duplex))
+ cmd->base.autoneg != AUTONEG_ENABLE &&
+ (jme->mii_if.full_duplex != cmd->base.duplex))
fdc = 1;
spin_lock_bh(&jme->phy_lock);
- rc = mii_ethtool_sset(&(jme->mii_if), ecmd);
+ rc = mii_ethtool_set_link_ksettings(&jme->mii_if, cmd);
spin_unlock_bh(&jme->phy_lock);
if (!rc) {
if (fdc)
jme_reset_link(jme);
- jme->old_ecmd = *ecmd;
+ jme->old_cmd = *cmd;
set_bit(JME_FLAG_SSET, &jme->flags);
}
@@ -2716,7 +2716,7 @@ static inline void jme_resume_rx(struct jme_adapter *jme)
if (!rc && (cmd == SIOCSMIIREG)) {
if (duplex_chg)
jme_reset_link(jme);
- jme_get_settings(netdev, &jme->old_ecmd);
+ jme_get_link_ksettings(netdev, &jme->old_cmd);
set_bit(JME_FLAG_SSET, &jme->flags);
}
@@ -2915,8 +2915,6 @@ static void jme_netpoll(struct net_device *dev)
.set_pauseparam = jme_set_pauseparam,
.get_wol = jme_get_wol,
.set_wol = jme_set_wol,
- .get_settings = jme_get_settings,
- .set_settings = jme_set_settings,
.get_link = jme_get_link,
.get_msglevel = jme_get_msglevel,
.set_msglevel = jme_set_msglevel,
@@ -2924,6 +2922,8 @@ static void jme_netpoll(struct net_device *dev)
.get_eeprom_len = jme_get_eeprom_len,
.get_eeprom = jme_get_eeprom,
.set_eeprom = jme_set_eeprom,
+ .get_link_ksettings = jme_get_link_ksettings,
+ .set_link_ksettings = jme_set_link_ksettings,
};
static int
@@ -3306,7 +3306,7 @@ static void jme_netpoll(struct net_device *dev)
jme_clear_pm_disable_wol(jme);
jme_phy_on(jme);
if (test_bit(JME_FLAG_SSET, &jme->flags))
- jme_set_settings(netdev, &jme->old_ecmd);
+ jme_set_link_ksettings(netdev, &jme->old_cmd);
else
jme_reset_phy_processor(jme);
jme_phy_calibration(jme);
diff --git a/drivers/net/ethernet/jme.h b/drivers/net/ethernet/jme.h
index 58cd67c..89535c0 100644
--- a/drivers/net/ethernet/jme.h
+++ b/drivers/net/ethernet/jme.h
@@ -447,7 +447,7 @@ struct jme_adapter {
u8 chip_sub_rev;
u8 pcirev;
u32 msg_enable;
- struct ethtool_cmd old_ecmd;
+ struct ethtool_link_ksettings old_cmd;
unsigned int old_mtu;
struct dynpcc_info dpi;
atomic_t intr_sem;
@@ -1270,8 +1270,8 @@ static inline int new_phy_power_ctrl(u8 chip_main_rev)
/*
* Function prototypes
*/
-static int jme_set_settings(struct net_device *netdev,
- struct ethtool_cmd *ecmd);
+static int jme_set_link_ksettings(struct net_device *netdev,
+ const struct ethtool_link_ksettings *cmd);
static void jme_set_unicastaddr(struct net_device *netdev);
static void jme_set_multi(struct net_device *netdev);
--
1.7.4.4
^ permalink raw reply related
* Re: sctp: kernel memory overwrite attempt detected in sctp_getsockopt_assoc_stats
From: Neil Horman @ 2017-01-15 20:35 UTC (permalink / raw)
To: Dmitry Vyukov
Cc: Vladislav Yasevich, David Miller, linux-sctp, netdev, LKML,
Kees Cook, syzkaller
In-Reply-To: <CACT4Y+ZDPa+spEh6P_ip9=hsNfeZ8KJfwJu5jTrPKVkGJUaZSg@mail.gmail.com>
On Sun, Jan 15, 2017 at 06:29:59PM +0100, Dmitry Vyukov wrote:
> Hello,
>
> I've enabled CONFIG_HARDENED_USERCOPY_PAGESPAN on syzkaller fuzzer and
> now I am seeing lots of:
>
If I'm not mistaken, its because thats specifically what that option does. From
the Kconfig:
onfig HARDENED_USERCOPY_PAGESPAN
bool "Refuse to copy allocations that span multiple pages"
depends on HARDENED_USERCOPY
depends on EXPERT
help
When a multi-page allocation is done without __GFP_COMP,
hardened usercopy will reject attempts to copy it. There are,
however, several cases of this in the kernel that have not all
been removed. This config is intended to be used only while
trying to find such users.
So, if the fuzzer does a setsockopt and the data it passes crosses a page
boundary, it seems like this will get triggered. Based on the fact that its
only used to find users that do this, it seems like not the sort of thing that
you want enabled while running a fuzzer that might do it arbitrarily.
Regards
Neil
> usercopy: kernel memory overwrite attempt detected to ffff8801a74f6f10
> (<spans multiple pages>) (256 bytes)
>
> kernel BUG at mm/usercopy.c:75!
> invalid opcode: 0000 [#1] SMP KASAN
> Dumping ftrace buffer:
> (ftrace buffer empty)
> Modules linked in:
> CPU: 1 PID: 15686 Comm: syz-executor3 Not tainted 4.9.0 #1
> Hardware name: Google Google Compute Engine/Google Compute Engine,
> BIOS Google 01/01/2011
> task: ffff8801c89b2500 task.stack: ffff8801a74f0000
> RIP: 0010:[<ffffffff81a1b041>] [<ffffffff81a1b041>] report_usercopy
> mm/usercopy.c:67 [inline]
> RIP: 0010:[<ffffffff81a1b041>] [<ffffffff81a1b041>]
> __check_object_size+0x2d1/0x9ec mm/usercopy.c:278
> RSP: 0018:ffff8801a74f6cd0 EFLAGS: 00010286
> RAX: 000000000000006b RBX: ffffffff84500120 RCX: 0000000000000000
> RDX: 000000000000006b RSI: ffffffff815a7791 RDI: ffffed0034e9ed8c
> RBP: ffff8801a74f6e48 R08: 0000000000000001 R09: 0000000000000000
> R10: 0000000000000000 R11: 0000000000000001 R12: ffff8801a74f6f10
> R13: 0000000000000100 R14: ffffffff845000e0 R15: ffff8801a74f700f
> FS: 00007f80918de700(0000) GS:ffff8801dc100000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 0000000020058ffc CR3: 00000001cc1cc000 CR4: 00000000001406e0
> Stack:
> ffffffff8598fcc8 0000000000000000 000077ff80000000 ffffea0005c99608
> ffffffff844fff40 ffffffff844fff40 0000000041b58ab3 ffffffff84ae0fa0
> ffffffff81a1ad70 ffff8801c89b2500 dead000000000100 ffffffff814d4425
> Call Trace:
> [<ffffffff83e4ece9>] check_object_size include/linux/thread_info.h:129 [inline]
> [<ffffffff83e4ece9>] copy_from_user arch/x86/include/asm/uaccess.h:692 [inline]
> [<ffffffff83e4ece9>] sctp_getsockopt_assoc_stats+0x169/0xa10
> net/sctp/socket.c:6182
> [<ffffffff83e5cc52>] sctp_getsockopt+0x1af2/0x66a0 net/sctp/socket.c:6556
> [<ffffffff834f92c5>] sock_common_getsockopt+0x95/0xd0 net/core/sock.c:2649
> [<ffffffff834f4910>] SYSC_getsockopt net/socket.c:1788 [inline]
> [<ffffffff834f4910>] SyS_getsockopt+0x240/0x380 net/socket.c:1770
> [<ffffffff81009798>] do_syscall_64+0x2e8/0x930 arch/x86/entry/common.c:280
> [<ffffffff84370a49>] entry_SYSCALL64_slow_path+0x25/0x25
> Code: b0 fe ff ff e8 e1 25 ce ff 48 8b 85 b0 fe ff ff 4d 89 e9 4c 89
> e1 4c 89 f2 48 89 de 48 c7 c7 a0 01 50 84 49 89 c0 e8 51 d9 e0 ff <0f>
> 0b e8 b8 25 ce ff 4c 89 f2 4c 89 ee 4c 89 e7 e8 6a 1b fc ff
> RIP [<ffffffff81a1b041>] report_usercopy mm/usercopy.c:67 [inline]
> RIP [<ffffffff81a1b041>] __check_object_size+0x2d1/0x9ec mm/usercopy.c:278
> RSP <ffff8801a74f6cd0>
> ---[ end trace 5e438996b2c0b35d ]---
>
>
> I am not sure why check_object_size flags this an a bug,
> copy_from_user copies into a stack object:
>
> static int sctp_getsockopt_assoc_stats(struct sock *sk, int len,
> char __user *optval,
> int __user *optlen)
> {
> struct sctp_assoc_stats sas;
> len = min_t(size_t, len, sizeof(sas));
> if (copy_from_user(&sas, optval, len))
> return -EFAULT;
>
> Kees, can this be a false positive?
>
> On commit f4d3935e4f4884ba80561db5549394afb8eef8f7.
>
^ permalink raw reply
* [PATCH net-next v2 1/3] net: ipv6: Allow shorthand delete of all nexthops in multipath route
From: David Ahern @ 2017-01-15 20:07 UTC (permalink / raw)
To: netdev; +Cc: ddutt, David Ahern
In-Reply-To: <1484510826-2723-1-git-send-email-dsa@cumulusnetworks.com>
IPv4 allows multipath routes to be deleted using just the prefix and
length. For example:
$ ip ro ls vrf red
unreachable default metric 8192
1.1.1.0/24
nexthop via 10.100.1.254 dev eth1 weight 1
nexthop via 10.11.200.2 dev eth11.200 weight 1
10.11.200.0/24 dev eth11.200 proto kernel scope link src 10.11.200.3
10.100.1.0/24 dev eth1 proto kernel scope link src 10.100.1.3
$ ip ro del 1.1.1.0/24 vrf red
$ ip ro ls vrf red
unreachable default metric 8192
10.11.200.0/24 dev eth11.200 proto kernel scope link src 10.11.200.3
10.100.1.0/24 dev eth1 proto kernel scope link src 10.100.1.3
The same notation does not work with IPv6 because of how multipath routes
are implemented for IPv6. For IPv6 only the first nexthop of a multipath
route is deleted if the request contains only a prefix and length. This
leads to unnecessary complexity in userspace dealing with IPv6 multipath
routes.
This patch allows all nexthops to be deleted without specifying each one
in the delete request by passing a new flag, RTM_F_ALL_NEXTHOPS, in
rtm_flags. Internally, this is done by walking the sibling list of the
route matching the specifications given (prefix, length, metric, protocol,
etc).
With this patch (and an updated iproute2 command):
$ ip -6 ro ls vrf red
2001:db8::/120 via 2001:db8:1::62 dev eth1 metric 256 pref medium
2001:db8::/120 via 2001:db8:1::61 dev eth1 metric 256 pref medium
2001:db8::/120 via 2001:db8:1::60 dev eth1 metric 256 pref medium
2001:db8:1::/120 dev eth1 proto kernel metric 256 pref medium
...
$ ip -6 ro del vrf red 1111::1/120
$ ip -6 ro ls vrf red
2001:db8:1::/120 dev eth1 proto kernel metric 256 pref medium
...
The flag is added to fib6_config by converting fc_type to a u16 (as
noted fc_type only uses 8 bits). The new u16 hole is a bitmap with
fc_delete_all_nexthop as the first bit.
Suggested-by: Dinesh Dutt <ddutt@cumulusnetworks.com>
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
v2
- switched example to rfc 3849 documentation address per request
- changed delete loop to explicitly look at siblings list for
first route matching specs given (metric, protocol, etc)
include/net/ip6_fib.h | 4 +++-
include/uapi/linux/rtnetlink.h | 1 +
net/ipv6/route.c | 28 +++++++++++++++++++++++++---
3 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index a74e2aa40ef4..11ab99e87c5f 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -37,7 +37,9 @@ struct fib6_config {
int fc_ifindex;
u32 fc_flags;
u32 fc_protocol;
- u32 fc_type; /* only 8 bits are used */
+ u16 fc_type; /* only 8 bits are used */
+ u16 fc_delete_all_nexthop : 1,
+ __unused : 15;
struct in6_addr fc_dst;
struct in6_addr fc_src;
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index 8c93ad1ef9ab..7fb206bc42f9 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -276,6 +276,7 @@ enum rt_scope_t {
#define RTM_F_EQUALIZE 0x400 /* Multipath equalizer: NI */
#define RTM_F_PREFIX 0x800 /* Prefix addresses */
#define RTM_F_LOOKUP_TABLE 0x1000 /* set rtm_table to FIB lookup result */
+#define RTM_F_ALL_NEXTHOPS 0x2000 /* delete all nexthops (IPv6) */
/* Reserved table identifiers */
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index ce5aaf448c54..c95e2f941468 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2143,6 +2143,26 @@ int ip6_del_rt(struct rt6_info *rt)
return __ip6_del_rt(rt, &info);
}
+/* called with table lock held */
+static int __ip6_route_del(struct rt6_info *rt, struct fib6_config *cfg)
+{
+ int err;
+
+ if (rt->rt6i_nsiblings && cfg->fc_delete_all_nexthop) {
+ struct rt6_info *sibling, *next_sibling;
+
+ list_for_each_entry_safe(sibling, next_sibling,
+ &rt->rt6i_siblings,
+ rt6i_siblings) {
+ err = fib6_del(sibling, &cfg->fc_nlinfo);
+ if (err)
+ return err;
+ }
+ }
+
+ return fib6_del(rt, &cfg->fc_nlinfo);
+}
+
static int ip6_route_del(struct fib6_config *cfg)
{
struct fib6_table *table;
@@ -2176,10 +2196,9 @@ static int ip6_route_del(struct fib6_config *cfg)
continue;
if (cfg->fc_protocol && cfg->fc_protocol != rt->rt6i_protocol)
continue;
- dst_hold(&rt->dst);
- read_unlock_bh(&table->tb6_lock);
- return __ip6_del_rt(rt, &cfg->fc_nlinfo);
+ err = __ip6_route_del(rt, cfg);
+ break;
}
}
read_unlock_bh(&table->tb6_lock);
@@ -2849,6 +2868,9 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
if (rtm->rtm_flags & RTM_F_CLONED)
cfg->fc_flags |= RTF_CACHE;
+ if (rtm->rtm_flags & RTM_F_ALL_NEXTHOPS)
+ cfg->fc_delete_all_nexthop = 1;
+
cfg->fc_nlinfo.portid = NETLINK_CB(skb).portid;
cfg->fc_nlinfo.nlh = nlh;
cfg->fc_nlinfo.nl_net = sock_net(skb->sk);
--
2.1.4
^ permalink raw reply related
* [PATCH net-next 0/3] net: ipv6: Improve user experience with multipath routes
From: David Ahern @ 2017-01-15 20:07 UTC (permalink / raw)
To: netdev; +Cc: ddutt, David Ahern
This series closes a couple of gaps between IPv4 and IPv6 with respect
to multipath routes.
Patch 1 allows IPv6 multipath routes to be deleted using just the prefix
and length - similar to what IPv4 allows.
Patch 2 removes the nowait arg which is always 0.
Patch 3 allows IPv6 multipath routes to be returned encoded in the
RTA_MULTIPATH attribute as opposed to a series of single routes.
Backwards compatibility for both patch 1 and 3 is maintained by
requiring users to opt in to the new behavior via change in the
request sent to the kernel.
David Ahern (3):
net: ipv6: Allow shorthand delete of all nexthops in multipath route
net: ipv6: remove nowait arg to rt6_fill_node
net: ipv6: Add option to dump multipath routes via RTA_MULTIPATH
attribute
include/linux/mroute6.h | 2 +-
include/net/ip6_fib.h | 4 +-
include/net/ip6_route.h | 1 +
include/uapi/linux/rtnetlink.h | 1 +
net/ipv6/ip6_fib.c | 29 +++++++-
net/ipv6/ip6mr.c | 9 +--
net/ipv6/route.c | 152 +++++++++++++++++++++++++++++++----------
7 files changed, 153 insertions(+), 45 deletions(-)
--
2.1.4
^ permalink raw reply
* [PATCH net-next 3/3] net: ipv6: Add option to dump multipath routes via RTA_MULTIPATH attribute
From: David Ahern @ 2017-01-15 20:07 UTC (permalink / raw)
To: netdev; +Cc: ddutt, David Ahern
In-Reply-To: <1484510826-2723-1-git-send-email-dsa@cumulusnetworks.com>
IPv6 returns multipath routes as a series of individual routes making
their display different than IPv4 and putting the burden on the user to
see that a route is part of a multipath route. This patch addresses this
difference, allowing users to request multipath routes to be returned
using the RTA_MULTIPATH attribute.
To maintain backwards compatibility, a user has to request the change
in behavior. Unfortunately, adding a flag to the header similar to a
previous patch does not work here as the netlink header for route dumps
can be either rtgenmsg or ifinfomsg. sysctl is the other commonly used
option for backwards compatibility but it is overly abused and is not
really appropriate for this situation since each request should be able
to specify the preference for the RTA_MULTIPATH attribute (e.g, one
command may understand RTA_MULTIPATH for IPv6 while another may not).
This patch relies on the existence of the RTA_MULTIPATH attribute
appeneded to the dump request -- similar to how attributes can be appended
to link dumps. Kernel side if the RTA_MULTIPATH attribute exists in the
dump request then the RTM_F_ALL_NEXTHOPS is set in a new rtm_flags
variable added to rt6_rtnl_dump_arg. The rtm_flags is then used by
rt6_dump_route to decided if the RTA_MULTIPATH attribute is used.
If it is enabled then rt6_fill_node walks the sibling list for a route
and encodes each as a next hop within RTA_MULTIPATH, and then
fib6_dump_node advances its cursor to the last sibling route in the
current route.
The end result is that IPv6 multipath routes can be displayed in a format
similar to IPv4:
$ ip -6 ro ls vrf red
2001:db8::/120 metric 1024
nexthop via 2001:db8:1::62 dev eth1 weight 1
nexthop via 2001:db8:1::61 dev eth1 weight 1
nexthop via 2001:db8:1::60 dev eth1 weight 1
nexthop via 2001:db8:1::59 dev eth1 weight 1
2001:db8:1::/120 dev eth1 proto kernel metric 256 pref medium
...
Suggested-by: Dinesh Dutt <ddutt@cumulusnetworks.com>
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
include/net/ip6_route.h | 1 +
net/ipv6/ip6_fib.c | 29 ++++++++++++-
net/ipv6/route.c | 107 +++++++++++++++++++++++++++++++++++++++---------
3 files changed, 116 insertions(+), 21 deletions(-)
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 9dc2c182a263..7620974826a5 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -154,6 +154,7 @@ struct rt6_rtnl_dump_arg {
struct sk_buff *skb;
struct netlink_callback *cb;
struct net *net;
+ unsigned int rtm_flags;
};
int rt6_dump_route(struct rt6_info *rt, void *p_arg);
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index ef5485204522..429713819c9f 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -308,16 +308,27 @@ static void __net_init fib6_tables_init(struct net *net)
static int fib6_dump_node(struct fib6_walker *w)
{
+ struct rt6_rtnl_dump_arg *arg = (struct rt6_rtnl_dump_arg *)w->args;
int res;
struct rt6_info *rt;
for (rt = w->leaf; rt; rt = rt->dst.rt6_next) {
- res = rt6_dump_route(rt, w->args);
+ res = rt6_dump_route(rt, arg);
if (res < 0) {
/* Frame is full, suspend walking */
w->leaf = rt;
return 1;
}
+
+ /* if multipath routes are dumped in one route with
+ * the RTA_MULTIPATH attribute, then jump rt to point
+ * to the last sibling of this route (no need to dump
+ * the sibling routes again)
+ */
+ if ((arg->rtm_flags & RTM_F_ALL_NEXTHOPS) && rt->rt6i_nsiblings)
+ rt = list_last_entry(&rt->rt6i_siblings,
+ struct rt6_info,
+ rt6i_siblings);
}
w->leaf = NULL;
return 0;
@@ -392,13 +403,16 @@ static int fib6_dump_table(struct fib6_table *table, struct sk_buff *skb,
static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
{
struct net *net = sock_net(skb->sk);
+ struct nlattr *nlattr[RTA_MAX + 1];
unsigned int h, s_h;
unsigned int e = 0, s_e;
struct rt6_rtnl_dump_arg arg;
struct fib6_walker *w;
struct fib6_table *tb;
struct hlist_head *head;
+ unsigned int flags = 0;
int res = 0;
+ int hdrlen;
s_h = cb->args[0];
s_e = cb->args[1];
@@ -422,9 +436,22 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
cb->args[2] = (long)w;
}
+ hdrlen = nlmsg_len(cb->nlh) < sizeof(struct ifinfomsg) ?
+ sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg);
+
+ if (nlmsg_parse(cb->nlh, hdrlen, nlattr, RTA_MAX, NULL) >= 0) {
+ /* existence of RTA_MULTIPATH attribute in dump
+ * request means user wants multipath routes
+ * returned using RTA_MULTIPATH attribute
+ */
+ if (nlattr[RTA_MULTIPATH])
+ flags |= RTM_F_ALL_NEXTHOPS;
+ }
+
arg.skb = skb;
arg.cb = cb;
arg.net = net;
+ arg.rtm_flags = flags;
w->args = &arg;
rcu_read_lock();
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 9f6f28ecd065..041ff245ba03 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -3187,11 +3187,66 @@ static inline size_t rt6_nlmsg_size(struct rt6_info *rt)
+ lwtunnel_get_encap_size(rt->dst.lwtstate);
}
+static int rt6_nexthop_info(struct sk_buff *skb, struct rt6_info *rt,
+ unsigned int *flags)
+{
+ if (!netif_carrier_ok(rt->dst.dev)) {
+ *flags |= RTNH_F_LINKDOWN;
+ if (rt->rt6i_idev->cnf.ignore_routes_with_linkdown)
+ *flags |= RTNH_F_DEAD;
+ }
+
+ if (rt->rt6i_flags & RTF_GATEWAY) {
+ if (nla_put_in6_addr(skb, RTA_GATEWAY, &rt->rt6i_gateway) < 0)
+ goto nla_put_failure;
+ }
+
+ if (rt->dst.dev &&
+ nla_put_u32(skb, RTA_OIF, rt->dst.dev->ifindex))
+ goto nla_put_failure;
+
+ if (rt->dst.lwtstate &&
+ lwtunnel_fill_encap(skb, rt->dst.lwtstate) < 0)
+ goto nla_put_failure;
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
+static int rt6_add_nexthop(struct sk_buff *skb, struct rt6_info *rt)
+{
+ struct rtnexthop *rtnh;
+ unsigned int flags = 0;
+
+ rtnh = nla_reserve_nohdr(skb, sizeof(*rtnh));
+ if (!rtnh)
+ goto nla_put_failure;
+
+ rtnh->rtnh_hops = 0;
+ rtnh->rtnh_ifindex = rt->dst.dev ? rt->dst.dev->ifindex : 0;
+
+ if (rt6_nexthop_info(skb, rt, &flags) < 0)
+ goto nla_put_failure;
+
+ rtnh->rtnh_flags = flags;
+
+ /* length of rtnetlink header + attributes */
+ rtnh->rtnh_len = nlmsg_get_pos(skb) - (void *)rtnh;
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
static int rt6_fill_node(struct net *net,
struct sk_buff *skb, struct rt6_info *rt,
struct in6_addr *dst, struct in6_addr *src,
int iif, int type, u32 portid, u32 seq,
- int prefix, unsigned int flags)
+ int prefix, unsigned int nlm_flags,
+ unsigned int rtm_flags)
{
u32 metrics[RTAX_MAX];
struct rtmsg *rtm;
@@ -3206,7 +3261,7 @@ static int rt6_fill_node(struct net *net,
}
}
- nlh = nlmsg_put(skb, portid, seq, type, sizeof(*rtm), flags);
+ nlh = nlmsg_put(skb, portid, seq, type, sizeof(*rtm), nlm_flags);
if (!nlh)
return -EMSGSIZE;
@@ -3245,11 +3300,6 @@ static int rt6_fill_node(struct net *net,
else
rtm->rtm_type = RTN_UNICAST;
rtm->rtm_flags = 0;
- if (!netif_carrier_ok(rt->dst.dev)) {
- rtm->rtm_flags |= RTNH_F_LINKDOWN;
- if (rt->rt6i_idev->cnf.ignore_routes_with_linkdown)
- rtm->rtm_flags |= RTNH_F_DEAD;
- }
rtm->rtm_scope = RT_SCOPE_UNIVERSE;
rtm->rtm_protocol = rt->rt6i_protocol;
if (rt->rt6i_flags & RTF_DYNAMIC)
@@ -3313,17 +3363,36 @@ static int rt6_fill_node(struct net *net,
if (rtnetlink_put_metrics(skb, metrics) < 0)
goto nla_put_failure;
- if (rt->rt6i_flags & RTF_GATEWAY) {
- if (nla_put_in6_addr(skb, RTA_GATEWAY, &rt->rt6i_gateway) < 0)
- goto nla_put_failure;
- }
-
- if (rt->dst.dev &&
- nla_put_u32(skb, RTA_OIF, rt->dst.dev->ifindex))
- goto nla_put_failure;
if (nla_put_u32(skb, RTA_PRIORITY, rt->rt6i_metric))
goto nla_put_failure;
+ /* if user wants nexthops included via the RTA_MULTIPATH
+ * attribute, then walk the siblings list and add each
+ * as a nexthop
+ */
+ if ((rtm_flags & RTM_F_ALL_NEXTHOPS) && rt->rt6i_nsiblings) {
+ struct rt6_info *sibling, *next_sibling;
+ struct nlattr *mp;
+
+ mp = nla_nest_start(skb, RTA_MULTIPATH);
+ if (!mp)
+ goto nla_put_failure;
+
+ if (rt6_add_nexthop(skb, rt) < 0)
+ goto nla_put_failure;
+
+ list_for_each_entry_safe(sibling, next_sibling,
+ &rt->rt6i_siblings, rt6i_siblings) {
+ if (rt6_add_nexthop(skb, sibling) < 0)
+ goto nla_put_failure;
+ }
+
+ nla_nest_end(skb, mp);
+ } else {
+ if (rt6_nexthop_info(skb, rt, &rtm->rtm_flags) < 0)
+ goto nla_put_failure;
+ }
+
expires = (rt->rt6i_flags & RTF_EXPIRES) ? rt->dst.expires - jiffies : 0;
if (rtnl_put_cacheinfo(skb, &rt->dst, 0, expires, rt->dst.error) < 0)
@@ -3332,8 +3401,6 @@ static int rt6_fill_node(struct net *net,
if (nla_put_u8(skb, RTA_PREF, IPV6_EXTRACT_PREF(rt->rt6i_flags)))
goto nla_put_failure;
- lwtunnel_fill_encap(skb, rt->dst.lwtstate);
-
nlmsg_end(skb, nlh);
return 0;
@@ -3356,7 +3423,7 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg)
return rt6_fill_node(arg->net,
arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE,
NETLINK_CB(arg->cb->skb).portid, arg->cb->nlh->nlmsg_seq,
- prefix, NLM_F_MULTI);
+ prefix, NLM_F_MULTI, arg->rtm_flags);
}
static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh)
@@ -3447,7 +3514,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh)
err = rt6_fill_node(net, skb, rt, &fl6.daddr, &fl6.saddr, iif,
RTM_NEWROUTE, NETLINK_CB(in_skb).portid,
- nlh->nlmsg_seq, 0, 0);
+ nlh->nlmsg_seq, 0, 0, 0);
if (err < 0) {
kfree_skb(skb);
goto errout;
@@ -3474,7 +3541,7 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info,
goto errout;
err = rt6_fill_node(net, skb, rt, NULL, NULL, 0,
- event, info->portid, seq, 0, nlm_flags);
+ event, info->portid, seq, 0, nlm_flags, 0);
if (err < 0) {
/* -EMSGSIZE implies BUG in rt6_nlmsg_size() */
WARN_ON(err == -EMSGSIZE);
--
2.1.4
^ permalink raw reply related
* [PATCH net-next 2/3] net: ipv6: remove nowait arg to rt6_fill_node
From: David Ahern @ 2017-01-15 20:07 UTC (permalink / raw)
To: netdev; +Cc: ddutt, David Ahern
In-Reply-To: <1484510826-2723-1-git-send-email-dsa@cumulusnetworks.com>
All callers of rt6_fill_node pass 0 for nowait arg. Remove the arg and
simplify rt6_fill_node accordingly.
rt6_fill_node passes the nowait of 0 to ip6mr_get_route. Remove the
nowait arg from it as well.
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
include/linux/mroute6.h | 2 +-
net/ipv6/ip6mr.c | 9 ++-------
net/ipv6/route.c | 27 ++++++++++-----------------
3 files changed, 13 insertions(+), 25 deletions(-)
diff --git a/include/linux/mroute6.h b/include/linux/mroute6.h
index 19a1c0c2993b..ce44e3e96d27 100644
--- a/include/linux/mroute6.h
+++ b/include/linux/mroute6.h
@@ -116,7 +116,7 @@ struct mfc6_cache {
struct rtmsg;
extern int ip6mr_get_route(struct net *net, struct sk_buff *skb,
- struct rtmsg *rtm, int nowait, u32 portid);
+ struct rtmsg *rtm, u32 portid);
#ifdef CONFIG_IPV6_MROUTE
extern struct sock *mroute6_socket(struct net *net, struct sk_buff *skb);
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index e275077e8af2..babaf3ec2742 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -2288,7 +2288,7 @@ static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
}
int ip6mr_get_route(struct net *net, struct sk_buff *skb, struct rtmsg *rtm,
- int nowait, u32 portid)
+ u32 portid)
{
int err;
struct mr6_table *mrt;
@@ -2315,11 +2315,6 @@ int ip6mr_get_route(struct net *net, struct sk_buff *skb, struct rtmsg *rtm,
struct net_device *dev;
int vif;
- if (nowait) {
- read_unlock(&mrt_lock);
- return -EAGAIN;
- }
-
dev = skb->dev;
if (!dev || (vif = ip6mr_find_vif(mrt, dev)) < 0) {
read_unlock(&mrt_lock);
@@ -2357,7 +2352,7 @@ int ip6mr_get_route(struct net *net, struct sk_buff *skb, struct rtmsg *rtm,
return err;
}
- if (!nowait && (rtm->rtm_flags&RTM_F_NOTIFY))
+ if (rtm->rtm_flags & RTM_F_NOTIFY)
cache->mfc_flags |= MFC_NOTIFY;
err = __ip6mr_fill_mroute(mrt, skb, cache, rtm);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index c95e2f941468..9f6f28ecd065 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -3191,7 +3191,7 @@ static int rt6_fill_node(struct net *net,
struct sk_buff *skb, struct rt6_info *rt,
struct in6_addr *dst, struct in6_addr *src,
int iif, int type, u32 portid, u32 seq,
- int prefix, int nowait, unsigned int flags)
+ int prefix, unsigned int flags)
{
u32 metrics[RTAX_MAX];
struct rtmsg *rtm;
@@ -3283,19 +3283,12 @@ static int rt6_fill_node(struct net *net,
if (iif) {
#ifdef CONFIG_IPV6_MROUTE
if (ipv6_addr_is_multicast(&rt->rt6i_dst.addr)) {
- int err = ip6mr_get_route(net, skb, rtm, nowait,
- portid);
-
- if (err <= 0) {
- if (!nowait) {
- if (err == 0)
- return 0;
- goto nla_put_failure;
- } else {
- if (err == -EMSGSIZE)
- goto nla_put_failure;
- }
- }
+ int err = ip6mr_get_route(net, skb, rtm, portid);
+
+ if (err == 0)
+ return 0;
+ if (err < 0)
+ goto nla_put_failure;
} else
#endif
if (nla_put_u32(skb, RTA_IIF, iif))
@@ -3363,7 +3356,7 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg)
return rt6_fill_node(arg->net,
arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE,
NETLINK_CB(arg->cb->skb).portid, arg->cb->nlh->nlmsg_seq,
- prefix, 0, NLM_F_MULTI);
+ prefix, NLM_F_MULTI);
}
static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh)
@@ -3454,7 +3447,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh)
err = rt6_fill_node(net, skb, rt, &fl6.daddr, &fl6.saddr, iif,
RTM_NEWROUTE, NETLINK_CB(in_skb).portid,
- nlh->nlmsg_seq, 0, 0, 0);
+ nlh->nlmsg_seq, 0, 0);
if (err < 0) {
kfree_skb(skb);
goto errout;
@@ -3481,7 +3474,7 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info,
goto errout;
err = rt6_fill_node(net, skb, rt, NULL, NULL, 0,
- event, info->portid, seq, 0, 0, nlm_flags);
+ event, info->portid, seq, 0, nlm_flags);
if (err < 0) {
/* -EMSGSIZE implies BUG in rt6_nlmsg_size() */
WARN_ON(err == -EMSGSIZE);
--
2.1.4
^ permalink raw reply related
* Re: [PATCH for bnxt_re V3 03/21] bnxt_re: register with the NIC driver
From: Leon Romanovsky @ 2017-01-15 19:41 UTC (permalink / raw)
To: Selvin Xavier
Cc: dledford, linux-rdma, netdev, michael.chan, Eddie Wai,
Devesh Sharma, Somnath Kotur, Sriharsha Basavapatna
In-Reply-To: <1482225211-22423-4-git-send-email-selvin.xavier@broadcom.com>
[-- Attachment #1: Type: text/plain, Size: 5447 bytes --]
On Tue, Dec 20, 2016 at 01:13:13AM -0800, Selvin Xavier wrote:
> This patch handles the registration with the bnxt_en driver.
> The bnxt_re driver first registers with netdev notifier chain and upon
> receiving the NETDEV_REGISTER event, it registers with bnxt_en driver.
>
> 1. bnxt_en's ulp_probe function returns a structure that contains
> information about the device and additional entry points.
> 2. bnxt_en driver returns 'struct bnxt_eth_dev' that contains set
> of operation vectors that bnxt_re driver invokes later.
> 3. bnxt_request_msix() allows the bnxt_re driver to specify the
> number of MSI-X vectors that are needed.
> 4. bnxt_send_fw_msg () is used to send messages to the FW
> 5. bnxt_register_async_events() is used to register for async
> event callbacks.
>
> v2: Remove some sparse warning. Also, remove some unused code from unreg
> path.
> v3: Removed condition checks for rdev reported during static code analysis.
> Check the return value of try_module_get while getting bnxt_en
> reference.
>
> Signed-off-by: Eddie Wai <eddie.wai@broadcom.com>
> Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
> Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
> Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
> Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
> ---
> drivers/infiniband/hw/bnxtre/bnxt_re.h | 51 ++++
> drivers/infiniband/hw/bnxtre/bnxt_re_main.c | 448 ++++++++++++++++++++++++++++
> 2 files changed, 499 insertions(+)
>
> diff --git a/drivers/infiniband/hw/bnxtre/bnxt_re.h b/drivers/infiniband/hw/bnxtre/bnxt_re.h
> index f9b8542..8b73e3d 100644
> --- a/drivers/infiniband/hw/bnxtre/bnxt_re.h
> +++ b/drivers/infiniband/hw/bnxtre/bnxt_re.h
> @@ -42,5 +42,56 @@
> #define ROCE_DRV_MODULE_NAME "bnxt_re"
> #define ROCE_DRV_MODULE_VERSION "1.0.0"
>
> +#define BNXT_RE_REF_WAIT_COUNT 10
> #define BNXT_RE_DESC "Broadcom NetXtreme-C/E RoCE Driver"
> +
> +struct bnxt_re_work {
> + struct work_struct work;
> + unsigned long event;
> + struct bnxt_re_dev *rdev;
> + struct net_device *vlan_dev;
> +};
> +
> +#define BNXT_RE_MIN_MSIX 2
> +#define BNXT_RE_MAX_MSIX 16
> +struct bnxt_re_dev {
> + struct ib_device ibdev;
> + struct list_head list;
> + atomic_t ref_count;
> + unsigned long flags;
> +#define BNXT_RE_FLAG_NETDEV_REGISTERED 0
> +#define BNXT_RE_FLAG_IBDEV_REGISTERED 1
> +#define BNXT_RE_FLAG_GOT_MSIX 2
> +#define BNXT_RE_FLAG_RCFW_CHANNEL_EN 8
> +#define BNXT_RE_FLAG_QOS_WORK_REG 16
> + struct net_device *netdev;
> + unsigned int version, major, minor;
> + struct bnxt_en_dev *en_dev;
> + struct bnxt_msix_entry msix_entries[BNXT_RE_MAX_MSIX];
> + int num_msix;
> +
> + int id;
> +
> + atomic_t qp_count;
> + struct mutex qp_lock; /* protect qp list */
> + struct list_head qp_list;
> +
> + atomic_t cq_count;
> + atomic_t srq_count;
> + atomic_t mr_count;
> + atomic_t mw_count;
> + /* Max of 2 lossless traffic class supported per port */
> + u16 cosq[2];
> +};
> +
> +#define to_bnxt_re_dev(ptr, member) \
> + container_of((ptr), struct bnxt_re_dev, member)
> +
> +static inline struct device *rdev_to_dev(struct bnxt_re_dev *rdev)
> +{
> + if (rdev)
> + return &rdev->ibdev.dev;
> + return NULL;
> +}
> +
> #endif
> diff --git a/drivers/infiniband/hw/bnxtre/bnxt_re_main.c b/drivers/infiniband/hw/bnxtre/bnxt_re_main.c
> index 6c22d51..fbd2ad3 100644
> --- a/drivers/infiniband/hw/bnxtre/bnxt_re_main.c
> +++ b/drivers/infiniband/hw/bnxtre/bnxt_re_main.c
> @@ -38,10 +38,24 @@
>
> #include <linux/module.h>
> #include <linux/netdevice.h>
> +#include <linux/ethtool.h>
> #include <linux/mutex.h>
> #include <linux/list.h>
> #include <linux/rculist.h>
> +#include <linux/spinlock.h>
> +#include <linux/pci.h>
> +#include <net/ipv6.h>
> +#include <net/addrconf.h>
> +
> +#include <rdma/ib_verbs.h>
> +#include <rdma/ib_user_verbs.h>
> +#include <rdma/ib_umem.h>
> +#include <rdma/ib_addr.h>
> +
> +#include "bnxt_ulp.h"
> +#include "bnxt_re_hsi.h"
> #include "bnxt_re.h"
> +#include "bnxt.h"
> static char version[] =
> BNXT_RE_DESC " v" ROCE_DRV_MODULE_VERSION "\n";
>
> @@ -55,6 +69,384 @@ static struct list_head bnxt_re_dev_list = LIST_HEAD_INIT(bnxt_re_dev_list);
> /* Mutex to protect the list of bnxt_re devices added */
> static DEFINE_MUTEX(bnxt_re_dev_lock);
> static struct workqueue_struct *bnxt_re_wq;
> +
> +/* for handling bnxt_en callbacks later */
> +static void bnxt_re_stop(void *p)
> +{
> +}
> +
> +static void bnxt_re_start(void *p)
> +{
> +}
> +
> +static void bnxt_re_sriov_config(void *p, int num_vfs)
> +{
> +}
> +
> +static struct bnxt_ulp_ops bnxt_re_ulp_ops = {
> + .ulp_async_notifier = NULL,
> + .ulp_stop = bnxt_re_stop,
> + .ulp_start = bnxt_re_start,
> + .ulp_sriov_config = bnxt_re_sriov_config
> +};
> +
> +/* The rdev ref_count is to protect immature removal of the device */
> +static inline void bnxt_re_hold(struct bnxt_re_dev *rdev)
> +{
> + atomic_inc(&rdev->ref_count);
> +}
> +
> +static inline void bnxt_re_put(struct bnxt_re_dev *rdev)
> +{
> + atomic_dec(&rdev->ref_count);
> +}
Recently, in one of our submission to netdev and rdma, we got
a reminder that inline functions shouldn't be in *.c. Let for
the compiler to decide.
IMHO, it should be open-coded without wrappers and honestly I failed to
understand why do you need so many wrappers for one line standard kernel
functions.
Thanks
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH net-next v3 06/10] net: dsa: Migrate to device_find_class()
From: Andrew Lunn @ 2017-01-15 19:16 UTC (permalink / raw)
To: Florian Fainelli
Cc: Jason Cooper, Vivien Didelot, Greg KH, Russell King, open list,
netdev, Gregory Clement, David S. Miller,
moderated list:ARM SUB-ARCHITECTURES, Sebastian Hesselbarth
In-Reply-To: <a9ea1f45-b9a5-d840-68e0-9bf9bc7a6598@gmail.com>
> > What exactly is the relationship between these devices (a ascii-art tree
> > or sysfs tree output might be nice) so I can try to understand what is
> > going on here.
Hi Greg, Florian
A few diagrams and trees which might help understand what is going on.
The first diagram comes from the 2008 patch which added all this code:
+-----------+ +-----------+
| | RGMII | |
| +-------+ +------ 1000baseT MDI ("WAN")
| | | 6-port +------ 1000baseT MDI ("LAN1")
| CPU | | ethernet +------ 1000baseT MDI ("LAN2")
| |MIImgmt| switch +------ 1000baseT MDI ("LAN3")
| +-------+ w/5 PHYs +------ 1000baseT MDI ("LAN4")
| | | |
+-----------+ +-----------+
We have an ethernet switch and a host CPU. The switch is connected to
the CPU in two different ways. RGMII allows us to get Ethernet frames
from the CPU into the switch. MIImgmt, is the management bus normally
used for Ethernet PHYs, but Marvell switches also use it for Managing
switches.
The diagram above is the simplest setup. You can have multiple
Ethernet switches, connected together via switch ports. Each switch
has its own MIImgmt connect to the CPU, but there is only one RGMII
link.
When this code was designed back in 2008, it was decided to represent
this is a platform device, and it has a platform_data, which i have
slightly edited to keep it simple:
struct dsa_platform_data {
/*
* Reference to a Linux network interface that connects
* to the root switch chip of the tree.
*/
struct device *netdev;
/*
* Info structs describing each of the switch chips
* connected via this network interface.
*/
int nr_chips;
struct dsa_chip_data *chip;
};
This netdev is the CPU side of the RGMII interface.
Each switch has a dsa_chip_data, again edited:
struct dsa_chip_data {
/*
* How to access the switch configuration registers.
*/
struct device *host_dev;
int sw_addr;
...
}
The host_dev is the CPU side of the MIImgmt, and we have the address
the switch is using on the bus.
During probe of this platform device, we need to get from the
struct device *netdev to a struct net_device *dev.
So the code looks in the device net class to find the device
| | | |-- f1074000.ethernet
| | | | |-- deferred_probe
| | | | |-- driver -> ../../../../../bus/platform/drivers/mvneta
| | | | |-- driver_override
| | | | |-- modalias
| | | | |-- net
| | | | | `-- eth1
| | | | | |-- addr_assign_type
| | | | | |-- address
| | | | | |-- addr_len
| | | | | |-- broadcast
| | | | | |-- carrier
| | | | | |-- carrier_changes
| | | | | |-- deferred_probe
| | | | | |-- device -> ../../../f1074000.ethernet
and then use container_of() to get the net_device.
Similarly, the code needs to get from struct device *host_dev to a struct mii_bus *.
| | | |-- f1072004.mdio
| | | | |-- deferred_probe
| | | | |-- driver -> ../../../../../bus/platform/drivers/orion-mdio
| | | | |-- driver_override
| | | | |-- mdio_bus
| | | | | `-- f1072004.mdio-mi
| | | | | |-- deferred_probe
| | | | | |-- device -> ../../../f1072004.mdio
Andrew
^ permalink raw reply
* Re: [PATCH net-next] net/sched: cls_flower: Add user specified data
From: John Fastabend @ 2017-01-15 19:08 UTC (permalink / raw)
To: Paul Blakey, Jiri Pirko, Jamal Hadi Salim
Cc: David S. Miller, netdev, Jiri Pirko, Hadar Hen Zion, Or Gerlitz,
Roi Dayan, Roman Mashak
In-Reply-To: <040c6876-a323-0a35-229f-46bc33b6de11@mellanox.com>
On 17-01-15 09:36 AM, Paul Blakey wrote:
>
>
> On 08/01/2017 19:12, Jiri Pirko wrote:
>> Mon, Jan 02, 2017 at 03:59:49PM CET, jhs@mojatatu.com wrote:
>>>
>>> We have been using a cookie as well for actions (which we have been
>>> using but have been too lazy to submit so far). I am going to port
>>> it over to the newer kernels and post it.
>>
>> Hard to deal with something we can't look at :)
>>
>>
>>> In our case that is intended to be opaque to the kernel i.e kernel
>>> never inteprets it; in that case it is similar to the kernel
>>> FIB protocol field.
>>
>> In case of this patch, kernel also never interprets it. What makes you
>> think otherwise. Bot kernel, it is always a binary blob.
>>
>>
>>>
>>> In your case - could this cookie have been a class/flowid
>>> (a 32 bit)?
>>> And would it not make more sense for it the cookie to be
>>> generic to all classifiers? i.e why is it specific to flower?
>>
>> Correct, makes sense to have it generic for all cls and perhaps also
>> acts.
>>
>>
>
> Hi all,
> I've started implementing a general cookie for all classifiers,
> I added the cookie on tcf_proto struct but then I realized that it won't work as
> I want. What I want is cookie per internal element (those that are identified by
> handles), which we can have many per one tcf_proto:
>
> tc filter add dev <DEV> parent ffff: prio 1 cookie 0x123 basic action drop
> tc filter add dev <DEV> parent ffff: prio 1 cookie 0x456 "port6" basic action drop
> tc filter add dev <DEV> parent ffff: prio 1 cookie 0x777 basic action drop
>
> So there is three options to do that:
> 1) Implement it in each classifier, using some generic function. (kinda like
> stats, where classifiler_dump() calls tcf_exts_dump_stats())
> 2) Have a global hash table for cookies [prio,handle]->[cookie]
> 3) Have it on flower only for now :)
>
> With the first one we will have to change each classifier (or leave it
> unsupported as default).
> Second is less code to change (instead of changing each classifier), but might
> be slower. I'm afraid how it will affect dumping several filters.
> Third is this patch.
>
> Thanks,
> Paul.
Avoid (2) it creates way more problems than its worth like is it locked/not
locked, how is it synced, collisions, etc. Seems way overkill.
I like the generic functionality of (1) but unless we see this pop up in
different filters I wouldn't require it for now. If you just do it in flower
(option 3) when its added to another classifier we can generalize it. As a
middle ground creating nice helper routines as needed goes a long way.
.John
^ permalink raw reply
* Re: net: stmmac: don't use netdev_[dbg, info, ..] before net_device is registered
From: Heiner Kallweit @ 2017-01-15 18:28 UTC (permalink / raw)
To: Joe Perches, David S. Miller; +Cc: netdev@vger.kernel.org
In-Reply-To: <1484504620.14692.8.camel@perches.com>
Am 15.01.2017 um 19:23 schrieb Joe Perches:
> On Sun, 2017-01-15 at 19:17 +0100, Heiner Kallweit wrote:
>> Don't use netdev_info and friends before the net_device is registered.
>> This avoids ugly messages like
>> "meson8b-dwmac c9410000.ethernet (unnamed net_device) (uninitialized):
>> Enable RX Mitigation via HW Watchdog Timer"
>
> It'd be nice to mention the new message prefix.
>
Sorry, I thought it's obvious because here the message trail looks
like this:
meson8b-dwmac c9410000.ethernet: DMA HW capability register supported
meson8b-dwmac c9410000.ethernet: Normal descriptors
meson8b-dwmac c9410000.ethernet: RX Checksum Offload Engine supported
meson8b-dwmac c9410000.ethernet: COE Type 2
meson8b-dwmac c9410000.ethernet: TX Checksum insertion supported
meson8b-dwmac c9410000.ethernet: Wake-Up On Lan supported
meson8b-dwmac c9410000.ethernet (unnamed net_device) (uninitialized): Enable RX Mitigation via HW Watchdog Timer
Better update the commit message and send a v2?
^ permalink raw reply
* Re: net: stmmac: don't use netdev_[dbg, info, ..] before net_device is registered
From: Joe Perches @ 2017-01-15 18:23 UTC (permalink / raw)
To: Heiner Kallweit, David S. Miller; +Cc: netdev@vger.kernel.org
In-Reply-To: <da21972e-87cd-370c-e9ff-219fc82ebd10@gmail.com>
On Sun, 2017-01-15 at 19:17 +0100, Heiner Kallweit wrote:
> Don't use netdev_info and friends before the net_device is registered.
> This avoids ugly messages like
> "meson8b-dwmac c9410000.ethernet (unnamed net_device) (uninitialized):
> Enable RX Mitigation via HW Watchdog Timer"
It'd be nice to mention the new message prefix.
^ permalink raw reply
* [PATCH] net: stmmac: don't use netdev_[dbg, info, ..] before net_device is registered
From: Heiner Kallweit @ 2017-01-15 18:19 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev@vger.kernel.org
Don't use netdev_info and friends before the net_device is registered.
This avoids ugly messages like
"meson8b-dwmac c9410000.ethernet (unnamed net_device) (uninitialized):
Enable RX Mitigation via HW Watchdog Timer"
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index d481c5f7..38e1fb75 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -3305,9 +3305,9 @@ int stmmac_dvr_probe(struct device *device,
(priv->plat->maxmtu >= ndev->min_mtu))
ndev->max_mtu = priv->plat->maxmtu;
else if (priv->plat->maxmtu < ndev->min_mtu)
- netdev_warn(priv->dev,
- "%s: warning: maxmtu having invalid value (%d)\n",
- __func__, priv->plat->maxmtu);
+ dev_warn(priv->device,
+ "%s: warning: maxmtu having invalid value (%d)\n",
+ __func__, priv->plat->maxmtu);
if (flow_ctrl)
priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */
@@ -3319,7 +3319,8 @@ int stmmac_dvr_probe(struct device *device,
*/
if ((priv->synopsys_id >= DWMAC_CORE_3_50) && (!priv->plat->riwt_off)) {
priv->use_riwt = 1;
- netdev_info(priv->dev, "Enable RX Mitigation via HW Watchdog Timer\n");
+ dev_info(priv->device,
+ "Enable RX Mitigation via HW Watchdog Timer\n");
}
netif_napi_add(ndev, &priv->napi, stmmac_poll, 64);
@@ -3345,17 +3346,17 @@ int stmmac_dvr_probe(struct device *device,
/* MDIO bus Registration */
ret = stmmac_mdio_register(ndev);
if (ret < 0) {
- netdev_err(priv->dev,
- "%s: MDIO bus (id: %d) registration failed",
- __func__, priv->plat->bus_id);
+ dev_err(priv->device,
+ "%s: MDIO bus (id: %d) registration failed",
+ __func__, priv->plat->bus_id);
goto error_mdio_register;
}
}
ret = register_netdev(ndev);
if (ret) {
- netdev_err(priv->dev, "%s: ERROR %i registering the device\n",
- __func__, ret);
+ dev_err(priv->device, "%s: ERROR %i registering the device\n",
+ __func__, ret);
goto error_netdev_register;
}
--
2.11.0
^ permalink raw reply related
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