* [PATCH 6/7] net: qrtr: Use sk_buff->cb in receive path
From: Bjorn Andersson @ 2017-09-07 6:03 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, linux-kernel, linux-arm-msm, Chris Lew
In-Reply-To: <20170907060329.32402-1-bjorn.andersson@linaro.org>
Rather than parsing the header of incoming messages throughout the
implementation do it once when we retrieve the message and store the
relevant information in the "cb" member of the sk_buff.
This allows us to, in a later commit, decode version 2 messages into
this same structure.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
net/qrtr/qrtr.c | 70 ++++++++++++++++++++++++++++++++-------------------------
1 file changed, 40 insertions(+), 30 deletions(-)
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index f28ecd7d735b..5042999756ce 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -48,6 +48,16 @@ struct qrtr_hdr {
__le32 dst_port_id;
} __packed;
+struct qrtr_cb {
+ u32 src_node;
+ u32 src_port;
+ u32 dst_node;
+ u32 dst_port;
+
+ u8 type;
+ u8 confirm_rx;
+};
+
#define QRTR_HDR_SIZE sizeof(struct qrtr_hdr)
struct qrtr_sock {
@@ -216,6 +226,7 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
struct qrtr_node *node = ep->node;
const struct qrtr_hdr *phdr = data;
struct sk_buff *skb;
+ struct qrtr_cb *cb;
unsigned int psize;
unsigned int size;
unsigned int type;
@@ -245,8 +256,15 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
if (!skb)
return -ENOMEM;
- skb_reset_transport_header(skb);
- skb_put_data(skb, data, len);
+ cb = (struct qrtr_cb *)skb->cb;
+ cb->src_node = le32_to_cpu(phdr->src_node_id);
+ cb->src_port = le32_to_cpu(phdr->src_port_id);
+ cb->dst_node = le32_to_cpu(phdr->dst_node_id);
+ cb->dst_port = le32_to_cpu(phdr->dst_port_id);
+ cb->type = type;
+ cb->confirm_rx = !!phdr->confirm_rx;
+
+ skb_put_data(skb, data + QRTR_HDR_SIZE, size);
skb_queue_tail(&node->rx_queue, skb);
schedule_work(&node->work);
@@ -295,26 +313,20 @@ static void qrtr_node_rx_work(struct work_struct *work)
struct sk_buff *skb;
while ((skb = skb_dequeue(&node->rx_queue)) != NULL) {
- const struct qrtr_hdr *phdr;
- u32 dst_node, dst_port;
struct qrtr_sock *ipc;
- u32 src_node;
+ struct qrtr_cb *cb;
int confirm;
- phdr = (const struct qrtr_hdr *)skb_transport_header(skb);
- src_node = le32_to_cpu(phdr->src_node_id);
- dst_node = le32_to_cpu(phdr->dst_node_id);
- dst_port = le32_to_cpu(phdr->dst_port_id);
- confirm = !!phdr->confirm_rx;
+ cb = (struct qrtr_cb *)skb->cb;
+ src.sq_node = cb->src_node;
+ src.sq_port = cb->src_port;
+ dst.sq_node = cb->dst_node;
+ dst.sq_port = cb->dst_port;
+ confirm = !!cb->confirm_rx;
- src.sq_node = src_node;
- src.sq_port = le32_to_cpu(phdr->src_port_id);
- dst.sq_node = dst_node;
- dst.sq_port = dst_port;
+ qrtr_node_assign(node, cb->src_node);
- qrtr_node_assign(node, src_node);
-
- ipc = qrtr_port_lookup(dst_port);
+ ipc = qrtr_port_lookup(cb->dst_port);
if (!ipc) {
kfree_skb(skb);
} else {
@@ -604,7 +616,7 @@ static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb,
struct sockaddr_qrtr *to)
{
struct qrtr_sock *ipc;
- struct qrtr_hdr *phdr;
+ struct qrtr_cb *cb;
ipc = qrtr_port_lookup(to->sq_port);
if (!ipc || &ipc->sk == skb->sk) { /* do not send to self */
@@ -612,11 +624,9 @@ static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb,
return -ENODEV;
}
- phdr = skb_push(skb, QRTR_HDR_SIZE);
- skb_reset_transport_header(skb);
-
- phdr->src_node_id = cpu_to_le32(from->sq_node);
- phdr->src_port_id = cpu_to_le32(from->sq_port);
+ cb = (struct qrtr_cb *)skb->cb;
+ cb->src_node = from->sq_node;
+ cb->src_port = from->sq_port;
if (sock_queue_rcv_skb(&ipc->sk, skb)) {
qrtr_port_put(ipc);
@@ -750,9 +760,9 @@ static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg,
size_t size, int flags)
{
DECLARE_SOCKADDR(struct sockaddr_qrtr *, addr, msg->msg_name);
- const struct qrtr_hdr *phdr;
struct sock *sk = sock->sk;
struct sk_buff *skb;
+ struct qrtr_cb *cb;
int copied, rc;
lock_sock(sk);
@@ -769,22 +779,22 @@ static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg,
return rc;
}
- phdr = (const struct qrtr_hdr *)skb_transport_header(skb);
- copied = le32_to_cpu(phdr->size);
+ copied = skb->len;
if (copied > size) {
copied = size;
msg->msg_flags |= MSG_TRUNC;
}
- rc = skb_copy_datagram_msg(skb, QRTR_HDR_SIZE, msg, copied);
+ rc = skb_copy_datagram_msg(skb, 0, msg, copied);
if (rc < 0)
goto out;
rc = copied;
if (addr) {
+ cb = (struct qrtr_cb *)skb->cb;
addr->sq_family = AF_QIPCRTR;
- addr->sq_node = le32_to_cpu(phdr->src_node_id);
- addr->sq_port = le32_to_cpu(phdr->src_port_id);
+ addr->sq_node = cb->src_node;
+ addr->sq_port = cb->src_port;
msg->msg_namelen = sizeof(*addr);
}
@@ -877,7 +887,7 @@ static int qrtr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
case TIOCINQ:
skb = skb_peek(&sk->sk_receive_queue);
if (skb)
- len = skb->len - QRTR_HDR_SIZE;
+ len = skb->len;
rc = put_user(len, (int __user *)argp);
break;
case SIOCGIFADDR:
--
2.12.0
^ permalink raw reply related
* [PATCH 5/7] net: qrtr: Clean up control packet handling
From: Bjorn Andersson @ 2017-09-07 6:03 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, linux-kernel, linux-arm-msm, Chris Lew
In-Reply-To: <20170907060329.32402-1-bjorn.andersson@linaro.org>
As the message header generation is deferred the internal functions for
generating control packets can be simplified.
This patch modifies qrtr_alloc_ctrl_packet() to, in addition to the
sk_buff, return a reference to a struct qrtr_ctrl_pkt, which clarifies
and simplifies the helpers to the point that these functions can be
folded back into the callers.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
net/qrtr/qrtr.c | 93 ++++++++++++++++++---------------------------------------
1 file changed, 29 insertions(+), 64 deletions(-)
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index bcec2432b833..f28ecd7d735b 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -255,9 +255,18 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
}
EXPORT_SYMBOL_GPL(qrtr_endpoint_post);
-static struct sk_buff *qrtr_alloc_ctrl_packet(u32 type, size_t pkt_len,
- u32 src_node, u32 dst_node)
+/**
+ * qrtr_alloc_ctrl_packet() - allocate control packet skb
+ * @pkt: reference to qrtr_ctrl_pkt pointer
+ *
+ * Returns newly allocated sk_buff, or NULL on failure
+ *
+ * This function allocates a sk_buff large enough to carry a qrtr_ctrl_pkt and
+ * on success returns a reference to the control packet in @pkt.
+ */
+static struct sk_buff *qrtr_alloc_ctrl_packet(struct qrtr_ctrl_pkt **pkt)
{
+ const int pkt_len = sizeof(struct qrtr_ctrl_pkt);
struct sk_buff *skb;
skb = alloc_skb(QRTR_HDR_SIZE + pkt_len, GFP_KERNEL);
@@ -265,64 +274,7 @@ static struct sk_buff *qrtr_alloc_ctrl_packet(u32 type, size_t pkt_len,
return NULL;
skb_reserve(skb, QRTR_HDR_SIZE);
-
- return skb;
-}
-
-/* Allocate and construct a resume-tx packet. */
-static struct sk_buff *qrtr_alloc_resume_tx(u32 src_node,
- u32 dst_node, u32 port)
-{
- const int pkt_len = 20;
- struct sk_buff *skb;
- __le32 *buf;
-
- skb = qrtr_alloc_ctrl_packet(QRTR_TYPE_RESUME_TX, pkt_len,
- src_node, dst_node);
- if (!skb)
- return NULL;
-
- buf = skb_put_zero(skb, pkt_len);
- buf[0] = cpu_to_le32(QRTR_TYPE_RESUME_TX);
- buf[1] = cpu_to_le32(src_node);
- buf[2] = cpu_to_le32(port);
-
- return skb;
-}
-
-/* Allocate and construct a BYE message to signal remote termination */
-static struct sk_buff *qrtr_alloc_local_bye(u32 src_node)
-{
- const int pkt_len = 20;
- struct sk_buff *skb;
- __le32 *buf;
-
- skb = qrtr_alloc_ctrl_packet(QRTR_TYPE_BYE, pkt_len,
- src_node, qrtr_local_nid);
- if (!skb)
- return NULL;
-
- buf = skb_put_zero(skb, pkt_len);
- buf[0] = cpu_to_le32(QRTR_TYPE_BYE);
-
- return skb;
-}
-
-static struct sk_buff *qrtr_alloc_del_client(struct sockaddr_qrtr *sq)
-{
- const int pkt_len = 20;
- struct sk_buff *skb;
- __le32 *buf;
-
- skb = qrtr_alloc_ctrl_packet(QRTR_TYPE_DEL_CLIENT, pkt_len,
- sq->sq_node, QRTR_NODE_BCAST);
- if (!skb)
- return NULL;
-
- buf = skb_put_zero(skb, pkt_len);
- buf[0] = cpu_to_le32(QRTR_TYPE_DEL_CLIENT);
- buf[1] = cpu_to_le32(sq->sq_node);
- buf[2] = cpu_to_le32(sq->sq_port);
+ *pkt = skb_put_zero(skb, pkt_len);
return skb;
}
@@ -337,6 +289,7 @@ static void qrtr_port_put(struct qrtr_sock *ipc);
static void qrtr_node_rx_work(struct work_struct *work)
{
struct qrtr_node *node = container_of(work, struct qrtr_node, work);
+ struct qrtr_ctrl_pkt *pkt;
struct sockaddr_qrtr dst;
struct sockaddr_qrtr src;
struct sk_buff *skb;
@@ -372,10 +325,14 @@ static void qrtr_node_rx_work(struct work_struct *work)
}
if (confirm) {
- skb = qrtr_alloc_resume_tx(dst_node, node->nid, dst_port);
+ skb = qrtr_alloc_ctrl_packet(&pkt);
if (!skb)
break;
+ pkt->cmd = cpu_to_le32(QRTR_TYPE_RESUME_TX);
+ pkt->client.node = cpu_to_le32(dst.sq_node);
+ pkt->client.port = cpu_to_le32(dst.sq_port);
+
if (qrtr_node_enqueue(node, skb, QRTR_TYPE_RESUME_TX,
&dst, &src))
break;
@@ -429,6 +386,7 @@ void qrtr_endpoint_unregister(struct qrtr_endpoint *ep)
struct qrtr_node *node = ep->node;
struct sockaddr_qrtr src = {AF_QIPCRTR, node->nid, QRTR_PORT_CTRL};
struct sockaddr_qrtr dst = {AF_QIPCRTR, qrtr_local_nid, QRTR_PORT_CTRL};
+ struct qrtr_ctrl_pkt *pkt;
struct sk_buff *skb;
mutex_lock(&node->ep_lock);
@@ -436,9 +394,11 @@ void qrtr_endpoint_unregister(struct qrtr_endpoint *ep)
mutex_unlock(&node->ep_lock);
/* Notify the local controller about the event */
- skb = qrtr_alloc_local_bye(node->nid);
- if (skb)
+ skb = qrtr_alloc_ctrl_packet(&pkt);
+ if (skb) {
+ pkt->cmd = cpu_to_le32(QRTR_TYPE_BYE);
qrtr_local_enqueue(NULL, skb, QRTR_TYPE_BYE, &src, &dst);
+ }
qrtr_node_release(node);
ep->node = NULL;
@@ -474,6 +434,7 @@ static void qrtr_port_put(struct qrtr_sock *ipc)
/* Remove port assignment. */
static void qrtr_port_remove(struct qrtr_sock *ipc)
{
+ struct qrtr_ctrl_pkt *pkt;
struct sk_buff *skb;
int port = ipc->us.sq_port;
struct sockaddr_qrtr to;
@@ -482,8 +443,12 @@ static void qrtr_port_remove(struct qrtr_sock *ipc)
to.sq_node = QRTR_NODE_BCAST;
to.sq_port = QRTR_PORT_CTRL;
- skb = qrtr_alloc_del_client(&ipc->us);
+ skb = qrtr_alloc_ctrl_packet(&pkt);
if (skb) {
+ pkt->cmd = cpu_to_le32(QRTR_TYPE_DEL_CLIENT);
+ pkt->client.node = cpu_to_le32(ipc->us.sq_node);
+ pkt->client.port = cpu_to_le32(ipc->us.sq_port);
+
skb_set_owner_w(skb, &ipc->sk);
qrtr_bcast_enqueue(NULL, skb, QRTR_TYPE_DEL_CLIENT, &ipc->us,
&to);
--
2.12.0
^ permalink raw reply related
* [PATCH 4/7] net: qrtr: Pass source and destination to enqueue functions
From: Bjorn Andersson @ 2017-09-07 6:03 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, linux-kernel, linux-arm-msm, Chris Lew
In-Reply-To: <20170907060329.32402-1-bjorn.andersson@linaro.org>
Defer writing the message header to the skb until its time to enqueue
the packet. As the receive path is reworked to decode the message header
as it's received from the transport and only pass around the payload in
the skb this change means that we do not have to fill out the full
message header just to decode it immediately in qrtr_local_enqueue().
In the future this change also makes it possible to prepend message
headers based on the version of each link.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
net/qrtr/qrtr.c | 120 ++++++++++++++++++++++++++++++++------------------------
1 file changed, 69 insertions(+), 51 deletions(-)
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index fac7cd6ea445..bcec2432b833 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -97,8 +97,12 @@ struct qrtr_node {
struct list_head item;
};
-static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb);
-static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb);
+static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb,
+ int type, struct sockaddr_qrtr *from,
+ struct sockaddr_qrtr *to);
+static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb,
+ int type, struct sockaddr_qrtr *from,
+ struct sockaddr_qrtr *to);
/* Release node resources and free the node.
*
@@ -136,10 +140,27 @@ static void qrtr_node_release(struct qrtr_node *node)
}
/* Pass an outgoing packet socket buffer to the endpoint driver. */
-static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb)
+static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb,
+ int type, struct sockaddr_qrtr *from,
+ struct sockaddr_qrtr *to)
{
+ struct qrtr_hdr *hdr;
+ size_t len = skb->len;
int rc = -ENODEV;
+ hdr = skb_push(skb, QRTR_HDR_SIZE);
+ hdr->version = cpu_to_le32(QRTR_PROTO_VER);
+ hdr->type = cpu_to_le32(type);
+ hdr->src_node_id = cpu_to_le32(from->sq_node);
+ hdr->src_port_id = cpu_to_le32(from->sq_port);
+ hdr->dst_node_id = cpu_to_le32(to->sq_node);
+ hdr->dst_port_id = cpu_to_le32(to->sq_port);
+
+ hdr->size = cpu_to_le32(len);
+ hdr->confirm_rx = 0;
+
+ skb_put_padto(skb, ALIGN(len, 4));
+
mutex_lock(&node->ep_lock);
if (node->ep)
rc = node->ep->xmit(node->ep, skb);
@@ -237,23 +258,13 @@ EXPORT_SYMBOL_GPL(qrtr_endpoint_post);
static struct sk_buff *qrtr_alloc_ctrl_packet(u32 type, size_t pkt_len,
u32 src_node, u32 dst_node)
{
- struct qrtr_hdr *hdr;
struct sk_buff *skb;
skb = alloc_skb(QRTR_HDR_SIZE + pkt_len, GFP_KERNEL);
if (!skb)
return NULL;
- skb_reset_transport_header(skb);
- hdr = skb_put(skb, QRTR_HDR_SIZE);
- hdr->version = cpu_to_le32(QRTR_PROTO_VER);
- hdr->type = cpu_to_le32(type);
- hdr->src_node_id = cpu_to_le32(src_node);
- hdr->src_port_id = cpu_to_le32(QRTR_PORT_CTRL);
- hdr->confirm_rx = cpu_to_le32(0);
- hdr->size = cpu_to_le32(pkt_len);
- hdr->dst_node_id = cpu_to_le32(dst_node);
- hdr->dst_port_id = cpu_to_le32(QRTR_PORT_CTRL);
+ skb_reserve(skb, QRTR_HDR_SIZE);
return skb;
}
@@ -326,6 +337,8 @@ static void qrtr_port_put(struct qrtr_sock *ipc);
static void qrtr_node_rx_work(struct work_struct *work)
{
struct qrtr_node *node = container_of(work, struct qrtr_node, work);
+ struct sockaddr_qrtr dst;
+ struct sockaddr_qrtr src;
struct sk_buff *skb;
while ((skb = skb_dequeue(&node->rx_queue)) != NULL) {
@@ -341,6 +354,11 @@ static void qrtr_node_rx_work(struct work_struct *work)
dst_port = le32_to_cpu(phdr->dst_port_id);
confirm = !!phdr->confirm_rx;
+ src.sq_node = src_node;
+ src.sq_port = le32_to_cpu(phdr->src_port_id);
+ dst.sq_node = dst_node;
+ dst.sq_port = dst_port;
+
qrtr_node_assign(node, src_node);
ipc = qrtr_port_lookup(dst_port);
@@ -357,7 +375,9 @@ static void qrtr_node_rx_work(struct work_struct *work)
skb = qrtr_alloc_resume_tx(dst_node, node->nid, dst_port);
if (!skb)
break;
- if (qrtr_node_enqueue(node, skb))
+
+ if (qrtr_node_enqueue(node, skb, QRTR_TYPE_RESUME_TX,
+ &dst, &src))
break;
}
}
@@ -407,6 +427,8 @@ EXPORT_SYMBOL_GPL(qrtr_endpoint_register);
void qrtr_endpoint_unregister(struct qrtr_endpoint *ep)
{
struct qrtr_node *node = ep->node;
+ struct sockaddr_qrtr src = {AF_QIPCRTR, node->nid, QRTR_PORT_CTRL};
+ struct sockaddr_qrtr dst = {AF_QIPCRTR, qrtr_local_nid, QRTR_PORT_CTRL};
struct sk_buff *skb;
mutex_lock(&node->ep_lock);
@@ -416,7 +438,7 @@ void qrtr_endpoint_unregister(struct qrtr_endpoint *ep)
/* Notify the local controller about the event */
skb = qrtr_alloc_local_bye(node->nid);
if (skb)
- qrtr_local_enqueue(NULL, skb);
+ qrtr_local_enqueue(NULL, skb, QRTR_TYPE_BYE, &src, &dst);
qrtr_node_release(node);
ep->node = NULL;
@@ -454,11 +476,17 @@ static void qrtr_port_remove(struct qrtr_sock *ipc)
{
struct sk_buff *skb;
int port = ipc->us.sq_port;
+ struct sockaddr_qrtr to;
+
+ to.sq_family = AF_QIPCRTR;
+ to.sq_node = QRTR_NODE_BCAST;
+ to.sq_port = QRTR_PORT_CTRL;
skb = qrtr_alloc_del_client(&ipc->us);
if (skb) {
skb_set_owner_w(skb, &ipc->sk);
- qrtr_bcast_enqueue(NULL, skb);
+ qrtr_bcast_enqueue(NULL, skb, QRTR_TYPE_DEL_CLIENT, &ipc->us,
+ &to);
}
if (port == QRTR_PORT_CTRL)
@@ -606,19 +634,25 @@ static int qrtr_bind(struct socket *sock, struct sockaddr *saddr, int len)
}
/* Queue packet to local peer socket. */
-static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb)
+static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb,
+ int type, struct sockaddr_qrtr *from,
+ struct sockaddr_qrtr *to)
{
- const struct qrtr_hdr *phdr;
struct qrtr_sock *ipc;
+ struct qrtr_hdr *phdr;
- phdr = (const struct qrtr_hdr *)skb_transport_header(skb);
-
- ipc = qrtr_port_lookup(le32_to_cpu(phdr->dst_port_id));
+ ipc = qrtr_port_lookup(to->sq_port);
if (!ipc || &ipc->sk == skb->sk) { /* do not send to self */
kfree_skb(skb);
return -ENODEV;
}
+ phdr = skb_push(skb, QRTR_HDR_SIZE);
+ skb_reset_transport_header(skb);
+
+ phdr->src_node_id = cpu_to_le32(from->sq_node);
+ phdr->src_port_id = cpu_to_le32(from->sq_port);
+
if (sock_queue_rcv_skb(&ipc->sk, skb)) {
qrtr_port_put(ipc);
kfree_skb(skb);
@@ -631,7 +665,9 @@ static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb)
}
/* Queue packet for broadcast. */
-static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb)
+static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb,
+ int type, struct sockaddr_qrtr *from,
+ struct sockaddr_qrtr *to)
{
struct sk_buff *skbn;
@@ -641,11 +677,11 @@ static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb)
if (!skbn)
break;
skb_set_owner_w(skbn, skb->sk);
- qrtr_node_enqueue(node, skbn);
+ qrtr_node_enqueue(node, skbn, type, from, to);
}
mutex_unlock(&qrtr_node_lock);
- qrtr_local_enqueue(node, skb);
+ qrtr_local_enqueue(node, skb, type, from, to);
return 0;
}
@@ -653,13 +689,14 @@ static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb)
static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
{
DECLARE_SOCKADDR(struct sockaddr_qrtr *, addr, msg->msg_name);
- int (*enqueue_fn)(struct qrtr_node *, struct sk_buff *);
+ int (*enqueue_fn)(struct qrtr_node *, struct sk_buff *, int,
+ struct sockaddr_qrtr *, struct sockaddr_qrtr *);
struct qrtr_sock *ipc = qrtr_sk(sock->sk);
struct sock *sk = sock->sk;
struct qrtr_node *node;
- struct qrtr_hdr *hdr;
struct sk_buff *skb;
size_t plen;
+ u32 type = QRTR_TYPE_DATA;
int rc;
if (msg->msg_flags & ~(MSG_DONTWAIT))
@@ -713,32 +750,14 @@ static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
if (!skb)
goto out_node;
- skb_reset_transport_header(skb);
- skb_put(skb, len + QRTR_HDR_SIZE);
-
- hdr = (struct qrtr_hdr *)skb_transport_header(skb);
- hdr->version = cpu_to_le32(QRTR_PROTO_VER);
- hdr->src_node_id = cpu_to_le32(ipc->us.sq_node);
- hdr->src_port_id = cpu_to_le32(ipc->us.sq_port);
- hdr->confirm_rx = cpu_to_le32(0);
- hdr->size = cpu_to_le32(len);
- hdr->dst_node_id = cpu_to_le32(addr->sq_node);
- hdr->dst_port_id = cpu_to_le32(addr->sq_port);
+ skb_reserve(skb, QRTR_HDR_SIZE);
- rc = skb_copy_datagram_from_iter(skb, QRTR_HDR_SIZE,
- &msg->msg_iter, len);
+ rc = memcpy_from_msg(skb_put(skb, len), msg, len);
if (rc) {
kfree_skb(skb);
goto out_node;
}
- if (plen != len) {
- rc = skb_pad(skb, plen - len);
- if (rc)
- goto out_node;
- skb_put(skb, plen - len);
- }
-
if (ipc->us.sq_port == QRTR_PORT_CTRL) {
if (len < 4) {
rc = -EINVAL;
@@ -747,12 +766,11 @@ static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
}
/* control messages already require the type as 'command' */
- skb_copy_bits(skb, QRTR_HDR_SIZE, &hdr->type, 4);
- } else {
- hdr->type = cpu_to_le32(QRTR_TYPE_DATA);
+ skb_copy_bits(skb, 0, &type, 4);
+ type = le32_to_cpu(type);
}
- rc = enqueue_fn(node, skb);
+ rc = enqueue_fn(node, skb, type, &ipc->us, addr);
if (rc >= 0)
rc = len;
--
2.12.0
^ permalink raw reply related
* [PATCH 3/7] net: qrtr: Add control packet definition to uapi
From: Bjorn Andersson @ 2017-09-07 6:03 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, linux-kernel, linux-arm-msm, Chris Lew
In-Reply-To: <20170907060329.32402-1-bjorn.andersson@linaro.org>
The QMUX protocol specification defines structure of the special control
packet messages being sent between handlers of the control port.
Add these to the uapi header, as this structure and the associated types
are shared between the kernel and all userspace handlers of control
messages.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
include/uapi/linux/qrtr.h | 32 ++++++++++++++++++++++++++++++++
net/qrtr/qrtr.c | 12 ------------
2 files changed, 32 insertions(+), 12 deletions(-)
diff --git a/include/uapi/linux/qrtr.h b/include/uapi/linux/qrtr.h
index 63e8803e4d90..179af64846e0 100644
--- a/include/uapi/linux/qrtr.h
+++ b/include/uapi/linux/qrtr.h
@@ -13,4 +13,36 @@ struct sockaddr_qrtr {
__u32 sq_port;
};
+enum qrtr_pkt_type {
+ QRTR_TYPE_DATA = 1,
+ QRTR_TYPE_HELLO = 2,
+ QRTR_TYPE_BYE = 3,
+ QRTR_TYPE_NEW_SERVER = 4,
+ QRTR_TYPE_DEL_SERVER = 5,
+ QRTR_TYPE_DEL_CLIENT = 6,
+ QRTR_TYPE_RESUME_TX = 7,
+ QRTR_TYPE_EXIT = 8,
+ QRTR_TYPE_PING = 9,
+ QRTR_TYPE_NEW_LOOKUP = 10,
+ QRTR_TYPE_DEL_LOOKUP = 11,
+};
+
+struct qrtr_ctrl_pkt {
+ __le32 cmd;
+
+ union {
+ struct {
+ __le32 service;
+ __le32 instance;
+ __le32 node;
+ __le32 port;
+ } server;
+
+ struct {
+ __le32 node;
+ __le32 port;
+ } client;
+ };
+} __packed;
+
#endif /* _LINUX_QRTR_H */
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index 0d7d3968414e..fac7cd6ea445 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -26,18 +26,6 @@
#define QRTR_MIN_EPH_SOCKET 0x4000
#define QRTR_MAX_EPH_SOCKET 0x7fff
-enum qrtr_pkt_type {
- QRTR_TYPE_DATA = 1,
- QRTR_TYPE_HELLO = 2,
- QRTR_TYPE_BYE = 3,
- QRTR_TYPE_NEW_SERVER = 4,
- QRTR_TYPE_DEL_SERVER = 5,
- QRTR_TYPE_DEL_CLIENT = 6,
- QRTR_TYPE_RESUME_TX = 7,
- QRTR_TYPE_EXIT = 8,
- QRTR_TYPE_PING = 9,
-};
-
/**
* struct qrtr_hdr - (I|R)PCrouter packet header
* @version: protocol version
--
2.12.0
^ permalink raw reply related
* [PATCH 0/7] net: qrtr: Fixes and support receiving version 2 packets
From: Bjorn Andersson @ 2017-09-07 6:03 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, linux-kernel, linux-arm-msm, Chris Lew
On the latest Qualcomm platforms remote processors are sending packets with
version 2 of the message header. This series starts off with some fixes and
then refactors the qrtr code to support receiving messages of both version 1
and version 2.
As all remotes are backwards compatible transmitted packets continues to be
send as version 1, but some groundwork has been done to make this a per-link
property.
Bjorn Andersson (7):
net: qrtr: Invoke sk_error_report() after setting sk_err
net: qrtr: Move constants to header file
net: qrtr: Add control packet definition to uapi
net: qrtr: Pass source and destination to enqueue functions
net: qrtr: Clean up control packet handling
net: qrtr: Use sk_buff->cb in receive path
net: qrtr: Support decoding incoming v2 packets
include/uapi/linux/qrtr.h | 35 +++++
net/qrtr/qrtr.c | 377 +++++++++++++++++++++++++---------------------
2 files changed, 241 insertions(+), 171 deletions(-)
--
2.12.0
^ permalink raw reply
* Re: [GIT] Networking
From: Linus Torvalds @ 2017-09-07 5:46 UTC (permalink / raw)
To: Luca Coelho
Cc: linux-kernel@vger.kernel.org, linuxwifi, Berg, Johannes,
akpm@linux-foundation.org, kvalo@codeaurora.org,
netdev@vger.kernel.org, davem@davemloft.net,
linux-wireless@vger.kernel.org, Grumbach, Emmanuel
In-Reply-To: <1504762851.5400.93.camel@coelho.fi>
On Wed, Sep 6, 2017 at 10:40 PM, Luca Coelho <luca@coelho.fi> wrote:
>
> This patch is not very important (unless you really like blinking lights
> -- maybe I'll change my mind when the holidays approach :P). so it is
> fine if you just want to revert it for now.
>
> In any case, I'll send a patch fixing this problem soon.
No need to revert if we can get this fixed quickly enough.
I'll leave the fw-31 on my laptop, so that I can continue to use it for now.
Thanks,
Linus
^ permalink raw reply
* Re: [GIT] Networking
From: Luca Coelho @ 2017-09-07 5:40 UTC (permalink / raw)
To: torvalds@linux-foundation.org
Cc: linux-kernel@vger.kernel.org, linuxwifi, Berg, Johannes,
akpm@linux-foundation.org, kvalo@codeaurora.org,
netdev@vger.kernel.org, davem@davemloft.net,
linux-wireless@vger.kernel.org, Grumbach, Emmanuel
In-Reply-To: <1504760688.5400.91.camel@intel.com>
On Thu, 2017-09-07 at 05:04 +0000, Coelho, Luciano wrote:
> On Wed, 2017-09-06 at 21:57 -0700, Linus Torvalds wrote:
> > On Wed, Sep 6, 2017 at 9:11 PM, Coelho, Luciano
> > <luciano.coelho@intel.com> wrote:
> > >
> > > This seems to be a problem with backwards-compatibility with FW version
> > > 27. We are now in version 31[1] and upgrading will probably fix that.
> >
> > I can confirm that fw version 31 works.
>
> Great, so I know for sure that this is a backwards-compatibility issue
> with the FW API.
>
>
> > > But obviously the driver should not fail miserably like this with
> > > version 27, because it claims to support it still.
> >
> > Not just "claims to support it", but if it's what is shipped with a
> > fairly recent distro like an up-to-date version of F26, I would really
> > hope that the driver can still work with it.
>
> I totally agree, we support a bunch of older versions for that exact
> reason. We just don't really test all the supported versions very
> often. We should probably change that.
>
> I'll make sure it still works with version 27.
Okay, I found the offending patch:
commit 7089ae634c50544b29b31faf1a751e8765c8de3b
Author: Johannes Berg <johannes.berg@intel.com>
AuthorDate: Wed Jun 28 16:19:49 2017 +0200
Commit: Luca Coelho <luciano.coelho@intel.com>
CommitDate: Wed Aug 9 09:15:32 2017 +0300
iwlwifi: mvm: use firmware LED command where applicable
On devices starting from 8000 series, the host can no longer toggle
the LED through the CSR_LED_REG register, but must do it via the
firmware instead. Add support for this. Note that this means that
the LED cannot be turned on while the firmware is off, so using an
arbitrary LED trigger may not work as expected.
Fixes: 503ab8c56ca0 ("iwlwifi: Add 8000 HW family support")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Reverting it solves the problem. We introduced a new command to control
the LED lights and assumed it was available in older FW versions as
well, which turned out not to be the case.
This patch is not very important (unless you really like blinking lights
-- maybe I'll change my mind when the holidays approach :P). so it is
fine if you just want to revert it for now.
In any case, I'll send a patch fixing this problem soon.
--
Cheers,
Luca.
^ permalink raw reply
* Re: [RFC net-next 0/5] TSN: Add qdisc-based config interfaces for traffic shapers
From: Henrik Austad @ 2017-09-07 5:34 UTC (permalink / raw)
To: Vinicius Costa Gomes
Cc: netdev, jhs, xiyou.wangcong, jiri, intel-wired-lan, andre.guedes,
ivan.briano, jesus.sanchez-palencia, boon.leong.ong,
richardcochran
In-Reply-To: <20170901012625.14838-1-vinicius.gomes@intel.com>
[-- Attachment #1: Type: text/plain, Size: 12931 bytes --]
On Thu, Aug 31, 2017 at 06:26:20PM -0700, Vinicius Costa Gomes wrote:
> Hi,
>
> This patchset is an RFC on a proposal of how the Traffic Control subsystem can
> be used to offload the configuration of traffic shapers into network devices
> that provide support for them in HW. Our goal here is to start upstreaming
> support for features related to the Time-Sensitive Networking (TSN) set of
> standards into the kernel.
Nice to see that others are working on this as well! :)
A short disclaimer; I'm pretty much anchored in the view "linux is the
end-station in a TSN domain", is this your approach as well, or are you
looking at this driver to be used in bridges as well? (because that will
affect the comments on time-aware shaper and frame preemption)
Yet another disclaimer; I am not a linux networking subsystem expert. Not
by a long shot! There are black magic happening in the internals of the
networking subsystem that I am not even aware of. So if something I say or
ask does not make sense _at_all_, that's probably why..
I do know a tiny bit about TSN though, and I have been messing around
with it for a little while, hence my comments below
> As part of this work, we've assessed previous public discussions related to TSN
> enabling: patches from Henrik Austad (Cisco), the presentation from Eric Mann
> at Linux Plumbers 2012, patches from Gangfeng Huang (National Instruments) and
> the current state of the OpenAVNU project (https://github.com/AVnu/OpenAvnu/).
/me eyes Cc ;p
> Overview
> ========
>
> Time-sensitive Networking (TSN) is a set of standards that aim to address
> resources availability for providing bandwidth reservation and bounded latency
> on Ethernet based LANs. The proposal described here aims to cover mainly what is
> needed to enable the following standards: 802.1Qat, 802.1Qav, 802.1Qbv and
> 802.1Qbu.
>
> The initial target of this work is the Intel i210 NIC, but other controllers'
> datasheet were also taken into account, like the Renesas RZ/A1H RZ/A1M group and
> the Synopsis DesignWare Ethernet QoS controller.
NXP has a TSN aware chip on the i.MX7 sabre board as well </fyi>
> Proposal
> ========
>
> Feature-wise, what is covered here are configuration interfaces for HW
> implementations of the Credit-Based shaper (CBS, 802.1Qav), Time-Aware shaper
> (802.1Qbv) and Frame Preemption (802.1Qbu). CBS is a per-queue shaper, while
> Qbv and Qbu must be configured per port, with the configuration covering all
> queues. Given that these features are related to traffic shaping, and that the
> traffic control subsystem already provides a queueing discipline that offloads
> config into the device driver (i.e. mqprio), designing new qdiscs for the
> specific purpose of offloading the config for each shaper seemed like a good
> fit.
just to be clear, you register sch_cbs as a subclass to mqprio, not as a
root class?
> For steering traffic into the correct queues, we use the socket option
> SO_PRIORITY and then a mechanism to map priority to traffic classes / Tx queues.
> The qdisc mqprio is currently used in our tests.
Right, fair enough, I'd prefer the TSN qdisc to be the root-device and
rather have mqprio for high priority traffic and another for 'everything
else'', but this would work too. This is not that relevant at this stage I
guess :)
> As for the shapers config interface:
>
> * CBS (802.1Qav)
>
> This patchset is proposing a new qdisc called 'cbs'. Its 'tc' cmd line is:
> $ tc qdisc add dev IFACE parent ID cbs locredit N hicredit M sendslope S \
> idleslope I
So this confuses me a bit, why specify sendSlope?
sendSlope = portTransmitRate - idleSlope
and portTransmitRate is the speed of the MAC (which you get from the
driver). Adding sendSlope here is just redundant I think.
Also, does this mean that when you create the qdisc, you have locked the
bandwidth for the scheduler? Meaning, if I later want to add another
stream that requires more bandwidth, I have to close all active streams,
reconfigure the qdisc and then restart?
> Note that the parameters for this qdisc are the ones defined by the
> 802.1Q-2014 spec, so no hardware specific functionality is exposed here.
You do need to know if the link is brought up as 100 or 1000 though - which
the driver already knows.
> * Time-aware shaper (802.1Qbv):
>
> The idea we are currently exploring is to add a "time-aware", priority based
> qdisc, that also exposes the Tx queues available and provides a mechanism for
> mapping priority <-> traffic class <-> Tx queues in a similar fashion as
> mqprio. We are calling this qdisc 'taprio', and its 'tc' cmd line would be:
As far as I know, this is not supported by i210, and if time-aware shaping
is enabled in the network - you'll be queued on a bridge until the window
opens as time-aware shaping is enforced on the tx-port and not on rx. Is
this required in this driver?
> $ $ tc qdisc add dev ens4 parent root handle 100 taprio num_tc 4 \
> map 2 2 1 0 3 3 3 3 3 3 3 3 3 3 3 3 \
> queues 0 1 2 3 \
> sched-file gates.sched [base-time <interval>] \
> [cycle-time <interval>] [extension-time <interval>]
That was a lot of priorities! 802.1Q lists 8 priorities, where does these
16 come from?
You map pri 0,1 to queue 2, pri 2 to queue 1 (Class B), pri 3 to queue 0
(class A) and everythign else to queue 3. This is what I would expect,
except for the additional 8 priorities.
> <file> is multi-line, with each line being of the following format:
> <cmd> <gate mask> <interval in nanoseconds>
>
> Qbv only defines one <cmd>: "S" for 'SetGates'
>
> For example:
>
> S 0x01 300
> S 0x03 500
>
> This means that there are two intervals, the first will have the gate
> for traffic class 0 open for 300 nanoseconds, the second will have
> both traffic classes open for 500 nanoseconds.
Are you aware of any hw except dedicated switching stuff that supports
this? (meant as "I'm curious and would like to know")
> Additionally, an option to set just one entry of the gate control list will
> also be provided by 'taprio':
>
> $ tc qdisc (...) \
> sched-row <row number> <cmd> <gate mask> <interval> \
> [base-time <interval>] [cycle-time <interval>] \
> [extension-time <interval>]
>
>
> * Frame Preemption (802.1Qbu):
So Frame preemption is nice, but my understanding of Qbu is that the real
benefit is at the bridges and not in the endpoints. As jumbo-frames is
explicitly disallowed in Qav, the maximum latency incurred by a frame in
flight is 12us on a 1Gbps link. I am not sure if these 12us is what will be
the main delay in your application.
Or have I missed some crucial point here?
> To control even further the latency, it may prove useful to signal which
> traffic classes are marked as preemptable. For that, 'taprio' provides the
> preemption command so you set each traffic class as preemptable or not:
>
> $ tc qdisc (...) \
> preemption 0 1 1 1
>
> * Time-aware shaper + Preemption:
>
> As an example of how Qbv and Qbu can be used together, we may specify
> both the schedule and the preempt-mask, and this way we may also
> specify the Set-Gates-and-Hold and Set-Gates-and-Release commands as
> specified in the Qbu spec:
>
> $ tc qdisc add dev ens4 parent root handle 100 taprio num_tc 4 \
> map 2 2 1 0 3 3 3 3 3 3 3 3 3 3 3 3 \
> queues 0 1 2 3 \
> preemption 0 1 1 1 \
> sched-file preempt_gates.sched
>
> <file> is multi-line, with each line being of the following format:
> <cmd> <gate mask> <interval in nanoseconds>
>
> For this case, two new commands are introduced:
>
> "H" for 'set gates and hold'
> "R" for 'set gates and release'
>
> H 0x01 300
> R 0x03 500
So my understanding of all of this is that you configure the *total*
bandwith for each class when you load the qdisc and then let userspace
handle the rest. Is this correct?
In my view, it would be nice if the qdisc had some notion about streams so
that you could create a stream, feed frames to it and let the driver pace
them out. (The fewer you queue, the shorter the delay). This will also
allow you to enforce per-stream bandwidth restrictions. I don't see how you
can do this here unless you want to do this in userspace.
Do you have any plans for adding support for multiplexing streams? If you
have multiple streams, how do you enforce that one stream does not eat into
the bandwidth of another stream? AFAIK, this is something the network must
enforce, but I see no option of doing som here.
> Testing this RFC
> ================
>
> For testing the patches of this RFC only, you can refer to the samples and
> helper script being added to samples/tsn/ and the use the 'mqprio' qdisc to
> setup the priorities to Tx queues mapping, together with the 'cbs' qdisc to
> configure the HW shaper of the i210 controller:
I will test it, feedback will be provided soon! :)
Thanks!
-Henrik
> 1) Setup priorities to traffic classes to hardware queues mapping
> $ tc qdisc replace dev enp3s0 parent root mqprio num_tc 3 \
> map 2 2 1 0 2 2 2 2 2 2 2 2 2 2 2 2 queues 1@0 1@1 2@2 hw 0
>
> 2) Check scheme. You want to get the inner qdiscs ID from the bottom up
> $ tc -g class show dev enp3s0
>
> Ex.:
> +---(802a:3) mqprio
> | +---(802a:6) mqprio
> | +---(802a:7) mqprio
> |
> +---(802a:2) mqprio
> | +---(802a:5) mqprio
> |
> +---(802a:1) mqprio
> +---(802a:4) mqprio
>
> * Here '802a:4' is Tx Queue #0 and '802a:5' is Tx Queue #1.
>
> 3) Calculate CBS parameters for classes A and B. i.e. BW for A is 20Mbps and
> for B is 10Mbps:
> $ ./samples/tsn/calculate_cbs_params.py -A 20000 -a 1500 -B 10000 -b 1500
>
> 4) Configure CBS for traffic class A (priority 3) as provided by the script:
> $ tc qdisc replace dev enp3s0 parent 802a:4 cbs locredit -1470 \
> hicredit 30 sendslope -980000 idleslope 20000
>
> 5) Configure CBS for traffic class B (priority 2):
> $ tc qdisc replace dev enp3s0 parent 802a:5 cbs \
> locredit -1485 hicredit 31 sendslope -990000 idleslope 10000
>
> 6) Run Listener, compiled from samples/tsn/listener.c
> $ ./listener -i enp3s0
>
> 7) Run Talker for class A (prio 3 here), compiled from samples/tsn/talker.c
> $ ./talker -i enp3s0 -p 3
>
> * The bandwidth displayed on the listener output at this stage should be very
> close to the one configured for class A.
>
> 8) You can also run a Talker for class B (prio 2 here)
> $ ./talker -i enp3s0 -p 2
>
> * The bandwidth displayed on the listener output now should increase to very
> close to the one configured for class A + class B.
Because you grab both class A *and* B, or because B will eat what A does
not use?
-H
> Authors
> =======
> - Andre Guedes <andre.guedes@intel.com>
> - Ivan Briano <ivan.briano@intel.com>
> - Jesus Sanchez-Palencia <jesus.sanchez-palencia@intel.com>
> - Vinicius Gomes <vinicius.gomes@intel.com>
>
>
> Andre Guedes (2):
> igb: Add support for CBS offload
> samples/tsn: Add script for calculating CBS config
>
> Jesus Sanchez-Palencia (1):
> sample: Add TSN Talker and Listener examples
>
> Vinicius Costa Gomes (2):
> net/sched: Introduce the user API for the CBS shaper
> net/sched: Introduce Credit Based Shaper (CBS) qdisc
>
> drivers/net/ethernet/intel/igb/e1000_defines.h | 23 ++
> drivers/net/ethernet/intel/igb/e1000_regs.h | 8 +
> drivers/net/ethernet/intel/igb/igb.h | 6 +
> drivers/net/ethernet/intel/igb/igb_main.c | 349 +++++++++++++++++++++++++
> include/linux/netdevice.h | 1 +
> include/uapi/linux/pkt_sched.h | 29 ++
> net/sched/Kconfig | 11 +
> net/sched/Makefile | 1 +
> net/sched/sch_cbs.c | 286 ++++++++++++++++++++
> samples/tsn/calculate_cbs_params.py | 112 ++++++++
> samples/tsn/listener.c | 254 ++++++++++++++++++
> samples/tsn/talker.c | 136 ++++++++++
> 12 files changed, 1216 insertions(+)
> create mode 100644 net/sched/sch_cbs.c
> create mode 100755 samples/tsn/calculate_cbs_params.py
> create mode 100644 samples/tsn/listener.c
> create mode 100644 samples/tsn/talker.c
>
> --
> 2.14.1
--
Henrik Austad
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 181 bytes --]
^ permalink raw reply
* [LPC] 2nd RDMA Mini-Summit Schedule
From: Leon Romanovsky @ 2017-09-07 5:18 UTC (permalink / raw)
To: RDMA mailing list
Cc: linux-netdev, NVME mailing list, Jason Gunthorpe, Bart Van Assche,
Knut Omang, Christoph Lameter, Don Dutile, Liran Liss, Tzahi Oved,
Matan Barak, Dennis Dalessandro, Yuval Shaia, Marcel Apfelbaum,
lwn-T1hC0tSOHrs
[-- Attachment #1: Type: text/plain, Size: 2686 bytes --]
Hi,
We're happy to announce schedule of the 2nd RDMA mini-summit, which will be
held as part of coming Linux Plumbers Conference 2017.
During the conference, we will have two sessions: main track session and
round table session.
First session will be held on Thursday, September 14, 2017 from 9:30am – 12:30pm
with the topics relevant for the wider audience.
In the second session, we will focus on more face to face discussions in round
table format and it will be scheduled a little bit later once we will get meeting
room.
---------------------------------------------------------------------------------------
FIRST SESSION:
---------------------------------------------------------------------------------------
* Backporting issues with multi-subsystem device (RDMA + netdev + more) by Don Dutile
- More and more devices in RDMA are dependent on netdev as well as other
subsystems -- target, NFS, scsi, block, cgroups, SELinux.... Can we make
backporting task for distro people easier?
* kABI Update by Matan Barak
- Going forward with a flexible and secure RDMA kABI
* System Boot and RDMA by Jason Gunthrope
- Discuss boot-time issues with the RDMA subsystem
* Paravirtual RDMA device by Marcel Apfelbaum and Yuval Shaia
- QEMU's limited RDMA support leaves it behind other modern hypervisors.
Marcel and Yuval will present the implementation of an emulated RDMA device,
analyze its performance and usability, and finally talk about future plans
for a possible virtio-rdma device.
* TX Flow Steering for IPsec by Liran Liss (pending time slot)
- The IPsec protocol provides both encryption and authentication for IP
protocol packets. Users of the raw ethernet QP that send/receive IPsec packets
could benefit from the IPsec crypto offloads capabilities that are
available in recent NICs.
* OpenFabrics Alliance - Status and New Directions by Jason Gunthrope
* BOF - Open Discussion
- Open discussion with the community lead by Leon Romanovsky, Jason Gunthorpe,
Christoph Lameter and Dennis Dalessandro
---------------------------------------------------------------------------------------
ROUND TABLE SESSION:
---------------------------------------------------------------------------------------
Possible list, bring your own topics:
* RDMA and ULPs
* Verbs testing suite
* RDMA netlink and RDMAtool future plans
* RDMA and the Linux IP stack
* Infrastructure issues with Travis CI
* Infrastructure gaps with rdma-core
* Packaging as part of CI for rdma-core.
* ....
See you next week at Linux Plumber Conference 2017.
Thanks
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: ipset losing entries on its own
From: Akshat Kakkar @ 2017-09-07 5:17 UTC (permalink / raw)
To: Denys Fedoryshchenko; +Cc: netdev, netdev-owner
In-Reply-To: <CAA5aLPgUcrUpqJJ8stu1543LBy0qekgQDuJyokqLPP0TirySgg@mail.gmail.com>
What I observed is rehashing of set is not happening.
When I add multiple IPs to the ipset manually on ipset v6.32,
rehashing is not happening and my hashsize remains same as 1024
but when I add to ipset 4.5 (pretty old, I know!), rehashing is
happening and my hashsize changes from 1024 to 1536 to 2304 to 3456!
^ permalink raw reply
* WARNING: at net/netfilter/core.c:218 __nf_hook_entries_try_shrink+0xf7/0x110
From: Mike Galbraith @ 2017-09-07 5:11 UTC (permalink / raw)
To: netdev
[-- Attachment #1: Type: text/plain, Size: 9981 bytes --]
[ 21.219604] ip6_tables: (C) 2000-2006 Netfilter Core Team
[ 21.433091] nf_conntrack version 0.5.0 (65536 buckets, 262144 max)
[ 21.495849] ip_tables: (C) 2000-2006 Netfilter Core Team
[ 22.404040] ------------[ cut here ]------------
[ 22.404267] WARNING: CPU: 2 PID: 1379 at net/netfilter/core.c:218 __nf_hook_entries_try_shrink+0xf7/0x110
[ 22.404484] Modules linked in: xt_tcpudp(E) iptable_filter(E) ip6table_mangle(E) nf_conntrack_netbios_ns(E) nf_conntrack_broadcast(E) nf_conntrack_ipv4(E) nf_defrag_ipv4(E) ip_tables(E) xt_conntrack(E) nf_conntrack(E) ip6table_filter(E) ip6_tables(E) x_tables(E) nls_iso8859_1(E) nls_cp437(E) intel_rapl(E) x86_pkg_temp_thermal(E) intel_powerclamp(E) coretemp(E) snd_hda_codec_hdmi(E) kvm_intel(E) kvm(E) snd_hda_codec_realtek(E) snd_hda_codec_generic(E) snd_hda_intel(E) irqbypass(E) joydev(E) snd_hda_codec(E) snd_hwdep(E) snd_hda_core(E) snd_pcm(E) crct10dif_pclmul(E) snd_timer(E) crc32_pclmul(E) crc32c_intel(E) ghash_clmulni_intel(E) snd(E) pcbc(E) aesni_intel(E) iTCO_wdt(E) aes_x86_64(E) r8169(E) iTCO_vendor_support(E) crypto_simd(E) glue_helper(E) lpc_ich(E) mii(E) mei_me(E) mei(E) mfd_
core(E) soundcore(E)
[ 22.405405] cryptd(E) i2c_i801(E) shpchp(E) intel_smartconnect(E) thermal(E) fan(E) battery(E) tpm_infineon(E) pcspkr(E) nfsd(E) auth_rpcgss(E) nfs_acl(E) lockd(E) grace(E) sunrpc(E) sr_mod(E) cdrom(E) hid_logitech_hidpp(E) hid_logitech_dj(E) uas(E) usb_storage(E) hid_generic(E) usbhid(E) nouveau(E) wmi(E) i2c_algo_bit(E) drm_kms_helper(E) syscopyarea(E) sysfillrect(E) sysimgblt(E) ehci_pci(E) fb_sys_fops(E) ahci(E) xhci_pci(E) ttm(E) libahci(E) ehci_hcd(E) xhci_hcd(E) libata(E) drm(E) usbcore(E) video(E) button(E) sd_mod(E) vfat(E) fat(E) virtio_rng(E) virtio_blk(E) virtio_mmio(E) virtio_pci(E) virtio_ring(E) virtio(E) ext4(E) crc16(E) mbcache(E) jbd2(E) fscrypto(E) loop(E) sg(E) dm_multipath(E) dm_mod(E) scsi_dh_rdac(E) scsi_dh_emc(E) scsi_dh_alua(E) scsi_mod(E) efivarfs(E) autofs4(E
)
[ 22.406419] CPU: 2 PID: 1379 Comm: iptables-batch Tainted: G E 4.13.0.g1c9fe44-master #10
[ 22.406662] Hardware name: MEDION MS-7848/MS-7848, BIOS M7848W08.20C 09/23/2013
[ 22.406911] task: ffff88041e822940 task.stack: ffffc900003f4000
[ 22.407161] RIP: 0010:__nf_hook_entries_try_shrink+0xf7/0x110
[ 22.407411] RSP: 0018:ffffc900003f7c18 EFLAGS: 00010246
[ 22.407668] RAX: 0000000000000010 RBX: ffff8803cce14e40 RCX: 0000000000000000
[ 22.407918] RDX: 0000000000000001 RSI: 0000000000000000 RDI: 0000000000000001
[ 22.408162] RBP: ffffc900003f7c38 R08: 0000000000000001 R09: 0000000000000000
[ 22.408410] R10: 0000000000000000 R11: 0000000000040001 R12: ffff8803cce14e58
[ 22.408663] R13: ffffffff81aac2c8 R14: ffffffffa09290a0 R15: ffffffff81aab9c0
[ 22.408928] FS: 00007f6c31c1a700(0000) GS:ffff88041ec80000(0000) knlGS:0000000000000000
[ 22.409186] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 22.409447] CR2: 00007f708537af14 CR3: 00000003fa4e5004 CR4: 00000000001606e0
[ 22.409710] Call Trace:
[ 22.409978] nf_unregister_net_hooks+0xf2/0x1a0
[ 22.410246] ? mutex_lock+0xe/0x30
[ 22.410518] ? mutex_lock+0xe/0x30
[ 22.410786] ? cleanup_match+0x40/0x50 [ip_tables]
[ 22.411052] ipv4_hooks_unregister+0x58/0x70 [nf_conntrack_ipv4]
[ 22.411322] nf_ct_netns_put+0x3c/0x80 [nf_conntrack]
[ 22.411584] cleanup_match+0x32/0x50 [ip_tables]
[ 22.411845] cleanup_entry+0x2e/0x90 [ip_tables]
[ 22.412110] translate_table+0x454/0x570 [ip_tables]
[ 22.412371] do_ipt_set_ctl+0xed/0x193 [ip_tables]
[ 22.412641] nf_setsockopt+0x3e/0x60
[ 22.412909] ip_setsockopt+0x6f/0x90
[ 22.413178] SyS_setsockopt+0x5e/0xb0
[ 22.413450] entry_SYSCALL_64_fastpath+0x1a/0xa5
[ 22.413706] RIP: 0033:0x7f6c3137cbca
[ 22.413969] RSP: 002b:00007ffc32d9d558 EFLAGS: 00000202 ORIG_RAX: 0000000000000036
[ 22.414224] RAX: ffffffffffffffda RBX: 00007f6c3162f678 RCX: 00007f6c3137cbca
[ 22.414490] RDX: 0000000000000040 RSI: 0000000000000000 RDI: 0000000000000007
[ 22.414758] RBP: 00007f6c3162f620 R08: 0000000000000ac8 R09: fefefefeff626d74
[ 22.415016] R10: 0000000001ed8920 R11: 0000000000000202 R12: 0000000000000af0
[ 22.415293] R13: 0000000000000ac8 R14: 0000000000002709 R15: 0000000000000ad1
[ 22.415564] Code: 39 d1 77 ba 4c 89 f7 e8 98 fe ff ff 4d 89 75 00 48 89 d8 5b 41 5c 41 5d 41 5e 5d c3 45 31 f6 eb eb 31 c0 eb ee 0f ff 31 c0 eb e8 <0f> ff 31 c0 0f 1f 44 00 00 eb dd 0f 1f 40 00 66 2e 0f 1f 84 00
[ 22.415881] ---[ end trace d15c01c3a7360856 ]---
Met 10 of those during this boot. The first time I booted, the
warnings were followed by the explosion below, but that kernel was not
entirely virgin, so add a pinch of salt.
[ 48.592298] Ebtables v2.0 registered
[ 48.730755] BUG: unable to handle kernel NULL pointer dereference at 000000000000003c
[ 48.732723] IP: _raw_read_lock_bh+0x15/0x30
[ 48.734526] PGD 0 P4D 0
[ 48.736482] Oops: 0002 [#1] SMP
[ 48.738317] Dumping ftrace buffer:
[ 48.740260] (ftrace buffer empty)
[ 48.742226] Modules linked in: ebtable_filter(E+) ebtables(E) af_packet(E) bridge(E) stp(E) llc(E) iscsi_ibft(E) iscsi_boot_sysfs(E) nf_conntrack_ipv6(E) nf_defrag_ipv6(E) ipt_REJECT(E) xt_tcpudp(E) iptable_filter(E) ip6table_mangle(E) nf_conntrack_netbios_ns(E) nf_conntrack_broadcast(E) nf_conntrack_ipv4(E) nf_defrag_ipv4(E) ip_tables(E) xt_conntrack(E) nf_conntrack(E) ip6table_filter(E) ip6_tables(E) x_tables(E) nls_iso8859_1(E) nls_cp437(E) intel_rapl(E) x86_pkg_temp_thermal(E) intel_powerclamp(E) coretemp(E) kvm_intel(E) kvm(E) snd_hda_codec_hdmi(E) irqbypass(E) snd_hda_codec_realtek(E) snd_hda_codec_generic(E) snd_hda_intel(E) snd_hda_codec(E) snd_hwdep(E) crct10dif_pclmul(E) snd_hda_core(E) crc32_pclmul(E) snd_pcm(E) joydev(E) snd_timer(E) r8169(E) crc32c_intel(E) ghash_clmulni_in
tel(E) snd(E)
[ 48.751616] mii(E) pcbc(E) aesni_intel(E) aes_x86_64(E) iTCO_wdt(E) shpchp(E) iTCO_vendor_support(E) crypto_simd(E) soundcore(E) glue_helper(E) mei_me(E) lpc_ich(E) mfd_core(E) mei(E) i2c_i801(E) cryptd(E) pcspkr(E) intel_smartconnect(E) battery(E) tpm_infineon(E) thermal(E) fan(E) nfsd(E) auth_rpcgss(E) nfs_acl(E) lockd(E) grace(E) sunrpc(E) sr_mod(E) cdrom(E) hid_logitech_hidpp(E) hid_logitech_dj(E) uas(E) usb_storage(E) hid_generic(E) usbhid(E) nouveau(E) wmi(E) i2c_algo_bit(E) drm_kms_helper(E) syscopyarea(E) sysfillrect(E) sysimgblt(E) fb_sys_fops(E) ttm(E) ahci(E) libahci(E) ehci_pci(E) xhci_pci(E) ehci_hcd(E) xhci_hcd(E) libata(E) drm(E) usbcore(E) video(E) button(E) sd_mod(E) vfat(E) fat(E) virtio_rng(E) virtio_blk(E) virtio_mmio(E) virtio_pci(E) virtio_ring(E) virtio(E) ext4(E
) crc16(E)
[ 48.763168] mbcache(E) jbd2(E) fscrypto(E) loop(E) sg(E) dm_multipath(E) dm_mod(E) scsi_dh_rdac(E) scsi_dh_emc(E) scsi_dh_alua(E) scsi_mod(E) efivarfs(E) autofs4(E)
[ 48.766157] CPU: 2 PID: 0 Comm: swapper/2 Tainted: G W E 4.13.0.g1c9fe44-master #9
[ 48.769108] Hardware name: MEDION MS-7848/MS-7848, BIOS M7848W08.20C 09/23/2013
[ 48.772251] task: ffff88018fe42940 task.stack: ffffc90000088000
[ 48.775370] RIP: 0010:_raw_read_lock_bh+0x15/0x30
[ 48.776496] RSP: 0018:ffff88041ec83bd0 EFLAGS: 00010286
[ 48.777414] RAX: 0000000000000100 RBX: 0000000000000001 RCX: 0000000000000000
[ 48.778302] RDX: 0000000000000000 RSI: ffff88041ec83ca8 RDI: 000000000000003c
[ 48.779189] RBP: 0000000000000000 R08: 0000000000000001 R09: 00000000088a0c8d
[ 48.780072] R10: 0000000000000000 R11: 0000000000007b00 R12: ffff8803cdcc1300
[ 48.780950] R13: ffff8803cdcc1300 R14: 0000000000000000 R15: ffff8803f1b8b000
[ 48.781845] FS: 0000000000000000(0000) GS:ffff88041ec80000(0000) knlGS:0000000000000000
[ 48.782727] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 48.783533] CR2: 000000000000003c CR3: 00000003f19fa001 CR4: 00000000001606e0
[ 48.784348] Call Trace:
[ 48.785160] <IRQ>
[ 48.786004] ebt_do_table+0x3b/0x6ca [ebtables]
[ 48.786900] ? dequeue_rt_stack+0x4c/0x290
[ 48.787792] ? enqueue_task_rt+0x1da/0x300
[ 48.789001] nf_hook_slow+0x37/0xb0
[ 48.790662] br_pass_frame_up+0xbe/0xd0 [bridge]
[ 48.792328] ? __br_handle_local_finish+0x40/0x40 [bridge]
[ 48.794011] br_handle_frame_finish+0x21f/0x4b0 [bridge]
[ 48.795688] ? __udp4_lib_lookup+0x187/0x360
[ 48.797368] br_handle_frame+0x149/0x2b0 [bridge]
[ 48.799054] ? udp4_lib_lookup_skb+0x78/0x90
[ 48.800737] ? br_handle_local_finish+0x40/0x40 [bridge]
[ 48.802424] __netif_receive_skb_core+0x244/0xa40
[ 48.804107] ? inet_gro_receive+0x20c/0x2a0
[ 48.805870] netif_receive_skb_internal+0x8a/0xb0
[ 48.807627] napi_gro_receive+0xbc/0xe0
[ 48.809381] rtl8169_poll+0x189/0x660 [r8169]
[ 48.811139] net_rx_action+0x26e/0x3a0
[ 48.812869] __do_softirq+0xc8/0x26b
[ 48.814704] irq_exit+0xc7/0xd0
[ 48.816633] do_IRQ+0x4c/0xd0
[ 48.818554] common_interrupt+0x96/0x96
[ 48.820471] </IRQ>
[ 48.822381] RIP: 0010:cpuidle_enter_state+0xe8/0x270
[ 48.824296] RSP: 0018:ffffc9000008bec8 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff6d
[ 48.826243] RAX: ffff88041ec99800 RBX: ffff88041eca0800 RCX: 000000000000001f
[ 48.828195] RDX: 0000000000000000 RSI: fffffffdbfeaa3d2 RDI: 0000000000000000
[ 48.830156] RBP: 0000000000000001 R08: 0000000000000006 R09: 0000000000000001
[ 48.832096] R10: 0000000000000002 R11: 0000000000000006 R12: 0000000000000002
[ 48.834018] R13: 0000000000000000 R14: 0000000b585e3b60 R15: 0000000b5893f5ee
[ 48.835946] ? cpuidle_enter_state+0xc3/0x270
[ 48.837869] do_idle+0x170/0x1d0
[ 48.839779] cpu_startup_entry+0x19/0x20
[ 48.841697] start_secondary+0x103/0x130
[ 48.843611] secondary_startup_64+0xa5/0xa5
[ 48.845524] Code: f0 0f c1 07 8d b0 00 01 00 00 40 84 f6 75 02 f3 c3 e9 f0 14 b0 ff 0f 1f 44 00 00 65 81 05 e8 b8 a6 7e 00 02 00 00 b8 00 01 00 00 <f0> 0f c1 07 8d b0 00 01 00 00 40 84 f6 75 02 f3 c3 e9 c5 14 b0
[ 48.847593] RIP: _raw_read_lock_bh+0x15/0x30 RSP: ffff88041ec83bd0
[ 48.849636] CR2: 000000000000003c
[-- Attachment #2: config.xz --]
[-- Type: application/x-xz, Size: 28044 bytes --]
^ permalink raw reply
* Re: [GIT] Networking
From: Coelho, Luciano @ 2017-09-07 5:04 UTC (permalink / raw)
To: torvalds@linux-foundation.org
Cc: linux-kernel@vger.kernel.org, linuxwifi, Berg, Johannes,
akpm@linux-foundation.org, kvalo@codeaurora.org,
netdev@vger.kernel.org, davem@davemloft.net,
linux-wireless@vger.kernel.org, Grumbach, Emmanuel
In-Reply-To: <CA+55aFzECjnpFWo_ZfbV+vE-5zRst7JfDC0hxnoitCGN0rmE3Q@mail.gmail.com>
On Wed, 2017-09-06 at 21:57 -0700, Linus Torvalds wrote:
> On Wed, Sep 6, 2017 at 9:11 PM, Coelho, Luciano
> <luciano.coelho@intel.com> wrote:
> >
> > This seems to be a problem with backwards-compatibility with FW version
> > 27. We are now in version 31[1] and upgrading will probably fix that.
>
> I can confirm that fw version 31 works.
Great, so I know for sure that this is a backwards-compatibility issue
with the FW API.
> > But obviously the driver should not fail miserably like this with
> > version 27, because it claims to support it still.
>
> Not just "claims to support it", but if it's what is shipped with a
> fairly recent distro like an up-to-date version of F26, I would really
> hope that the driver can still work with it.
I totally agree, we support a bunch of older versions for that exact
reason. We just don't really test all the supported versions very
often. We should probably change that.
I'll make sure it still works with version 27.
--
Cheers,
Luca.
^ permalink raw reply
* Re: [GIT] Networking
From: Linus Torvalds @ 2017-09-07 4:57 UTC (permalink / raw)
To: Coelho, Luciano
Cc: davem@davemloft.net, kvalo@codeaurora.org, Berg, Johannes,
Grumbach, Emmanuel, linuxwifi, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-wireless@vger.kernel.org,
akpm@linux-foundation.org
In-Reply-To: <1504757495.5400.89.camel@intel.com>
On Wed, Sep 6, 2017 at 9:11 PM, Coelho, Luciano
<luciano.coelho@intel.com> wrote:
>
> This seems to be a problem with backwards-compatibility with FW version
> 27. We are now in version 31[1] and upgrading will probably fix that.
I can confirm that fw version 31 works.
> But obviously the driver should not fail miserably like this with
> version 27, because it claims to support it still.
Not just "claims to support it", but if it's what is shipped with a
fairly recent distro like an up-to-date version of F26, I would really
hope that the driver can still work with it.
> I'm looking into this now and will provide a fix asap.
Thanks,
Linus
^ permalink raw reply
* Re: ipset losing entries on its own
From: Akshat Kakkar @ 2017-09-07 4:48 UTC (permalink / raw)
To: Denys Fedoryshchenko; +Cc: netdev, netdev-owner
In-Reply-To: <c7abf292ac5e6202993a10a66537141e@nuclearcat.com>
I understand that without reproducible scenarios, its hard to debug ...
But the point is, this issue is fully random and of very low frequency.
For the setup, it is CentOS 7.3 upgraded to kernel 4.4.
Whenever a system comes up on the network, he provides his credentials
and after successful authentication, his IP is added in an IPSET which
is having access to certain resources.
^ permalink raw reply
* [Patch net v2 2/2] net_sched: fix all the madness of tc filter chain
From: Cong Wang @ 2017-09-07 4:26 UTC (permalink / raw)
To: netdev; +Cc: jakub.kicinski, Cong Wang, Jiri Pirko
In-Reply-To: <20170907042607.24413-1-xiyou.wangcong@gmail.com>
This patch fixes the following madness of tc filter chain:
1) tcf_chain_destroy() is called by both tcf_block_put() and
tcf_chain_put(). tcf_chain_put() is correctly refcnt'ed and paired
with tcf_chain_get(), but tcf_block_put() is not, it should be paired
with tcf_block_get() which means we still need to decrease the refcnt.
Think it in another way: if we call tcf_bock_put() immediately after
tcf_block_get(), could we get effectively a nop? This causes a memory
leak as reported by Jakub.
2) tp proto should hold a refcnt to the chain too. This significantly
simplifies the logic:
2a) Chain 0 is no longer special, it is created and refcnted by tp
like any other chains. All the ugliness in tcf_chain_put() can be
gone!
2b) No need to handle the flushing oddly, because block still holds
chain 0, it can not be released, this guarantees block is the last
user.
2c) The race condition with RCU callbacks is easier to handle with just
a rcu_barrier()! Much easier to understand, nothing to hide! Thanks
to the previous patch. Please see also the comments in code.
2d) Make the code understandable by humans, much less error-prone.
Fixes: 744a4cf63e52 ("net: sched: fix use after free when tcf_chain_destroy is called multiple times")
Fixes: 5bc1701881e3 ("net: sched: introduce multichain support for filters")
Reported-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Cc: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
net/sched/cls_api.c | 38 ++++++++++++++++++++++----------------
1 file changed, 22 insertions(+), 16 deletions(-)
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 6c5ea84d2682..e9060dc36519 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -209,21 +209,20 @@ static void tcf_chain_flush(struct tcf_chain *chain)
RCU_INIT_POINTER(*chain->p_filter_chain, NULL);
while ((tp = rtnl_dereference(chain->filter_chain)) != NULL) {
RCU_INIT_POINTER(chain->filter_chain, tp->next);
+ tcf_chain_put(chain);
tcf_proto_destroy(tp);
}
}
static void tcf_chain_destroy(struct tcf_chain *chain)
{
- /* May be already removed from the list by the previous call. */
- if (!list_empty(&chain->list))
- list_del_init(&chain->list);
+ list_del(&chain->list);
+ kfree(chain);
+}
- /* There might still be a reference held when we got here from
- * tcf_block_put. Wait for the user to drop reference before free.
- */
- if (!chain->refcnt)
- kfree(chain);
+static void tcf_chain_hold(struct tcf_chain *chain)
+{
+ ++chain->refcnt;
}
struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index,
@@ -233,7 +232,7 @@ struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index,
list_for_each_entry(chain, &block->chain_list, list) {
if (chain->index == chain_index) {
- chain->refcnt++;
+ tcf_chain_hold(chain);
return chain;
}
}
@@ -246,10 +245,7 @@ EXPORT_SYMBOL(tcf_chain_get);
void tcf_chain_put(struct tcf_chain *chain)
{
- /* Destroy unused chain, with exception of chain 0, which is the
- * default one and has to be always present.
- */
- if (--chain->refcnt == 0 && !chain->filter_chain && chain->index != 0)
+ if (--chain->refcnt == 0)
tcf_chain_destroy(chain);
}
EXPORT_SYMBOL(tcf_chain_put);
@@ -294,10 +290,18 @@ void tcf_block_put(struct tcf_block *block)
if (!block)
return;
- list_for_each_entry_safe(chain, tmp, &block->chain_list, list) {
+ /* Standalone actions are not allowed to jump to any chain, and
+ * bound actions should be all removed after flushing. However,
+ * filters are destroyed in RCU callbacks, we have to flush and wait
+ * for them before releasing this refcnt, otherwise we race with RCU
+ * callbacks!!!
+ */
+ list_for_each_entry(chain, &block->chain_list, list)
tcf_chain_flush(chain);
- tcf_chain_destroy(chain);
- }
+ rcu_barrier();
+
+ list_for_each_entry_safe(chain, tmp, &block->chain_list, list)
+ tcf_chain_put(chain);
kfree(block);
}
EXPORT_SYMBOL(tcf_block_put);
@@ -375,6 +379,7 @@ static void tcf_chain_tp_insert(struct tcf_chain *chain,
rcu_assign_pointer(*chain->p_filter_chain, tp);
RCU_INIT_POINTER(tp->next, tcf_chain_tp_prev(chain_info));
rcu_assign_pointer(*chain_info->pprev, tp);
+ tcf_chain_hold(chain);
}
static void tcf_chain_tp_remove(struct tcf_chain *chain,
@@ -386,6 +391,7 @@ static void tcf_chain_tp_remove(struct tcf_chain *chain,
if (chain->p_filter_chain && tp == chain->filter_chain)
RCU_INIT_POINTER(*chain->p_filter_chain, next);
RCU_INIT_POINTER(*chain_info->pprev, next);
+ tcf_chain_put(chain);
}
static struct tcf_proto *tcf_chain_tp_find(struct tcf_chain *chain,
--
2.13.0
^ permalink raw reply related
* [Patch net v2 1/2] net_sched: get rid of tcfa_rcu
From: Cong Wang @ 2017-09-07 4:26 UTC (permalink / raw)
To: netdev; +Cc: jakub.kicinski, Cong Wang, Jiri Pirko, Eric Dumazet
gen estimator has been rewritten in commit 1c0d32fde5bd
("net_sched: gen_estimator: complete rewrite of rate estimators"),
the caller is no longer needed to wait for a grace period.
So this patch gets rid of it.
This also completely closes a race condition between action free
path and filter chain add/remove path for the following patch.
Because otherwise the nested RCU callback can't be caught by
rcu_barrier().
Cc: Jiri Pirko <jiri@mellanox.com>
Cc: Eric Dumazet <edumazet@google.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
include/net/act_api.h | 2 --
net/sched/act_api.c | 12 +++---------
2 files changed, 3 insertions(+), 11 deletions(-)
diff --git a/include/net/act_api.h b/include/net/act_api.h
index 26ffd8333f50..68218a5f8e72 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -38,7 +38,6 @@ struct tc_action {
struct gnet_stats_queue tcfa_qstats;
struct net_rate_estimator __rcu *tcfa_rate_est;
spinlock_t tcfa_lock;
- struct rcu_head tcfa_rcu;
struct gnet_stats_basic_cpu __percpu *cpu_bstats;
struct gnet_stats_queue __percpu *cpu_qstats;
struct tc_cookie *act_cookie;
@@ -55,7 +54,6 @@ struct tc_action {
#define tcf_qstats common.tcfa_qstats
#define tcf_rate_est common.tcfa_rate_est
#define tcf_lock common.tcfa_lock
-#define tcf_rcu common.tcfa_rcu
static inline unsigned int tcf_hash(u32 index, unsigned int hmask)
{
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index f2e9ed34a963..fc17d286a6a2 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -53,10 +53,8 @@ static void tcf_action_goto_chain_exec(const struct tc_action *a,
res->goto_tp = rcu_dereference_bh(chain->filter_chain);
}
-static void free_tcf(struct rcu_head *head)
+static void free_tcf(struct tc_action *p)
{
- struct tc_action *p = container_of(head, struct tc_action, tcfa_rcu);
-
free_percpu(p->cpu_bstats);
free_percpu(p->cpu_qstats);
@@ -76,11 +74,7 @@ static void tcf_hash_destroy(struct tcf_hashinfo *hinfo, struct tc_action *p)
hlist_del(&p->tcfa_head);
spin_unlock_bh(&hinfo->lock);
gen_kill_estimator(&p->tcfa_rate_est);
- /*
- * gen_estimator est_timer() might access p->tcfa_lock
- * or bstats, wait a RCU grace period before freeing p
- */
- call_rcu(&p->tcfa_rcu, free_tcf);
+ free_tcf(p);
}
int __tcf_hash_release(struct tc_action *p, bool bind, bool strict)
@@ -271,7 +265,7 @@ void tcf_hash_cleanup(struct tc_action *a, struct nlattr *est)
{
if (est)
gen_kill_estimator(&a->tcfa_rate_est);
- call_rcu(&a->tcfa_rcu, free_tcf);
+ free_tcf(a);
}
EXPORT_SYMBOL(tcf_hash_cleanup);
--
2.13.0
^ permalink raw reply related
* Re: [PATCH] tipc: remove unnecessary call to dev_net()
From: David Miller @ 2017-09-07 4:26 UTC (permalink / raw)
To: kleber.souza; +Cc: netdev, jon.maloy, ying.xue
In-Reply-To: <20170906090806.20931-1-kleber.souza@canonical.com>
From: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Date: Wed, 6 Sep 2017 11:08:06 +0200
> The net device is already stored in the 'net' variable, so no need to call
> dev_net() again.
>
> Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH net] netlink: access nlk groups safely in netlink bind and getname
From: David Miller @ 2017-09-07 4:24 UTC (permalink / raw)
To: lucien.xin; +Cc: netdev, fw
In-Reply-To: <cfb5c05d158b278beb2f1441c67a068a8bb27d44.1504670009.git.lucien.xin@gmail.com>
From: Xin Long <lucien.xin@gmail.com>
Date: Wed, 6 Sep 2017 11:53:29 +0800
> Now there is no lock protecting nlk ngroups/groups' accessing in
> netlink bind and getname. It's safe from nlk groups' setting in
> netlink_release, but not from netlink_realloc_groups called by
> netlink_setsockopt.
>
> netlink_lock_table is needed in both netlink bind and getname when
> accessing nlk groups.
>
> Acked-by: Florian Westphal <fw@strlen.de>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
Applied.
^ permalink raw reply
* Re: [PATCH net] netlink: fix an use-after-free issue for nlk groups
From: David Miller @ 2017-09-07 4:24 UTC (permalink / raw)
To: lucien.xin; +Cc: netdev, fw, chunwang, syzkaller
In-Reply-To: <1217baf9faf9d034ba8224cb6362b822c51a0eae.1504669632.git.lucien.xin@gmail.com>
From: Xin Long <lucien.xin@gmail.com>
Date: Wed, 6 Sep 2017 11:47:12 +0800
> ChunYu found a netlink use-after-free issue by syzkaller:
>
> [28448.842981] BUG: KASAN: use-after-free in __nla_put+0x37/0x40 at addr ffff8807185e2378
> [28448.969918] Call Trace:
> [...]
> [28449.117207] __nla_put+0x37/0x40
> [28449.132027] nla_put+0xf5/0x130
> [28449.146261] sk_diag_fill.isra.4.constprop.5+0x5a0/0x750 [netlink_diag]
> [28449.176608] __netlink_diag_dump+0x25a/0x700 [netlink_diag]
> [28449.202215] netlink_diag_dump+0x176/0x240 [netlink_diag]
> [28449.226834] netlink_dump+0x488/0xbb0
> [28449.298014] __netlink_dump_start+0x4e8/0x760
> [28449.317924] netlink_diag_handler_dump+0x261/0x340 [netlink_diag]
> [28449.413414] sock_diag_rcv_msg+0x207/0x390
> [28449.432409] netlink_rcv_skb+0x149/0x380
> [28449.467647] sock_diag_rcv+0x2d/0x40
> [28449.484362] netlink_unicast+0x562/0x7b0
> [28449.564790] netlink_sendmsg+0xaa8/0xe60
> [28449.661510] sock_sendmsg+0xcf/0x110
> [28449.865631] __sys_sendmsg+0xf3/0x240
> [28450.000964] SyS_sendmsg+0x32/0x50
> [28450.016969] do_syscall_64+0x25c/0x6c0
> [28450.154439] entry_SYSCALL64_slow_path+0x25/0x25
>
> It was caused by no protection between nlk groups' free in netlink_release
> and nlk groups' accessing in sk_diag_dump_groups. The similar issue also
> exists in netlink_seq_show().
>
> This patch is to defer nlk groups' free in deferred_put_nlk_sk.
>
> Reported-by: ChunYu Wang <chunwang@redhat.com>
> Acked-by: Florian Westphal <fw@strlen.de>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
Applied.
^ permalink raw reply
* Re: [PATCH] dt-binding: phy: don't confuse with Ethernet phy properties
From: David Miller @ 2017-09-07 4:14 UTC (permalink / raw)
To: baruch; +Cc: kishon, linux-kernel, netdev
In-Reply-To: <0a90f4b3cc903af6f82002e502deba67f374c602.1504449136.git.baruch@tkos.co.il>
From: Baruch Siach <baruch@tkos.co.il>
Date: Sun, 3 Sep 2017 17:32:16 +0300
> The generic PHY 'phys' property sometime appears in the same node with
> the Ethernet PHY 'phy' or 'phy-handle' properties. Add a warning in
> phy-bindings.txt to reduce confusion.
>
> Signed-off-by: Baruch Siach <baruch@tkos.co.il>
Applied.
^ permalink raw reply
* Re: [GIT] Networking
From: Coelho, Luciano @ 2017-09-07 4:11 UTC (permalink / raw)
To: torvalds@linux-foundation.org, davem@davemloft.net,
kvalo@codeaurora.org, Berg, Johannes, Grumbach, Emmanuel
Cc: linuxwifi, netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-wireless@vger.kernel.org, akpm@linux-foundation.org
In-Reply-To: <CA+55aFw0KNTKFrRHk5hthDGTGgL9BGt9G=x_m9Tz7m_-pN+NoA@mail.gmail.com>
On Wed, 2017-09-06 at 16:27 -0700, Linus Torvalds wrote:
> This pull request completely breaks Intel wireless for me.
>
> This is my trusty old XPS 13 (9350), using Intel Wireless 8260 (rev 3a).
>
> That remains a very standard Intel machine with absolutely zero odd
> things going on.
>
> The firmware is iwlwifi-8000C-28.ucode from
> iwl7260-firmware-25.30.13.0-75.fc26.noarch, and the kernel reports
>
> iwlwifi 0000:3a:00.0: loaded firmware version 27.455470.0 op_mode iwlmvm
>
> the thing starts acting badly with this:
>
> iwlwifi 0000:3a:00.0: FW Error notification: type 0x00000000 cmd_id 0x04
> iwlwifi 0000:3a:00.0: FW Error notification: seq 0x0000 service 0x00000004
> iwlwifi 0000:3a:00.0: FW Error notification: timestamp 0x 5D84
> iwlwifi 0000:3a:00.0: Microcode SW error detected. Restarting 0x2000000.
> iwlwifi 0000:3a:00.0: Start IWL Error Log Dump:
> iwlwifi 0000:3a:00.0: Status: 0x00000100, count: 6
> iwlwifi 0000:3a:00.0: Loaded firmware version: 27.455470.0
> iwlwifi 0000:3a:00.0: 0x00000038 | BAD_COMMAND
> iwlwifi 0000:3a:00.0: 0x00A002F0 | trm_hw_status0
> ...
> iwlwifi 0000:3a:00.0: 0x00000000 | isr status reg
> ieee80211 phy0: Hardware restart was requested
> iwlwifi 0000:3a:00.0: FW error in SYNC CMD MAC_CONTEXT_CMD
This seems to be a problem with backwards-compatibility with FW version
27. We are now in version 31[1] and upgrading will probably fix that.
But obviously the driver should not fail miserably like this with
version 27, because it claims to support it still.
I'm looking into this now and will provide a fix asap.
[1] https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/iwlwifi-8000C-31.ucode
--
Cheers,
Luca.
^ permalink raw reply
* [PATCH] ipv4: Namespaceify tcp_max_orphans knob
From: Haishuang Yan @ 2017-09-07 3:10 UTC (permalink / raw)
To: David S. Miller, Alexey Kuznetsov, Hideaki YOSHIFUJI,
Eric Dumazet
Cc: netdev, linux-kernel, Haishuang Yan
Different namespace application might require different maximal number
of TCP sockets independently of the host.
Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
---
include/net/netns/ipv4.h | 1 +
include/net/tcp.h | 5 +++--
net/ipv4/sysctl_net_ipv4.c | 14 +++++++-------
net/ipv4/tcp.c | 3 ---
net/ipv4/tcp_input.c | 1 -
net/ipv4/tcp_ipv4.c | 1 +
6 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index 20d061c..305e031 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -127,6 +127,7 @@ struct netns_ipv4 {
int sysctl_tcp_timestamps;
struct inet_timewait_death_row tcp_death_row;
int sysctl_max_syn_backlog;
+ int sysctl_tcp_max_orphans;
#ifdef CONFIG_NET_L3_MASTER_DEV
int sysctl_udp_l3mdev_accept;
diff --git a/include/net/tcp.h b/include/net/tcp.h
index b510f28..ac2d998 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -320,10 +320,11 @@ static inline bool tcp_too_many_orphans(struct sock *sk, int shift)
{
struct percpu_counter *ocp = sk->sk_prot->orphan_count;
int orphans = percpu_counter_read_positive(ocp);
+ int tcp_max_orphans = sock_net(sk)->ipv4.sysctl_tcp_max_orphans;
- if (orphans << shift > sysctl_tcp_max_orphans) {
+ if (orphans << shift > tcp_max_orphans) {
orphans = percpu_counter_sum_positive(ocp);
- if (orphans << shift > sysctl_tcp_max_orphans)
+ if (orphans << shift > tcp_max_orphans)
return true;
}
return false;
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 0d3c038..4f26c8d3 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -394,13 +394,6 @@ static int proc_tcp_available_ulp(struct ctl_table *ctl,
.proc_handler = proc_dointvec
},
{
- .procname = "tcp_max_orphans",
- .data = &sysctl_tcp_max_orphans,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = proc_dointvec
- },
- {
.procname = "tcp_fastopen",
.data = &sysctl_tcp_fastopen,
.maxlen = sizeof(int),
@@ -1085,6 +1078,13 @@ static int proc_tcp_available_ulp(struct ctl_table *ctl,
.mode = 0644,
.proc_handler = proc_dointvec
},
+ {
+ .procname = "tcp_max_orphans",
+ .data = &init_net.ipv4.sysctl_tcp_max_orphans,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec
+ },
#ifdef CONFIG_IP_ROUTE_MULTIPATH
{
.procname = "fib_multipath_use_neigh",
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 5091402..39187ac 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3522,9 +3522,6 @@ void __init tcp_init(void)
}
- cnt = tcp_hashinfo.ehash_mask + 1;
- sysctl_tcp_max_orphans = cnt / 2;
-
tcp_init_mem();
/* Set per-socket limits to no more than 1/128 the pressure threshold */
limit = nr_free_buffer_pages() << (PAGE_SHIFT - 7);
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index c5d7656..0230509 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -88,7 +88,6 @@
int sysctl_tcp_stdurg __read_mostly;
int sysctl_tcp_rfc1337 __read_mostly;
-int sysctl_tcp_max_orphans __read_mostly = NR_FILE;
int sysctl_tcp_frto __read_mostly = 2;
int sysctl_tcp_min_rtt_wlen __read_mostly = 300;
int sysctl_tcp_moderate_rcvbuf __read_mostly = 1;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index a63486a..4b17a91 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2468,6 +2468,7 @@ static int __net_init tcp_sk_init(struct net *net)
net->ipv4.tcp_death_row.hashinfo = &tcp_hashinfo;
net->ipv4.sysctl_max_syn_backlog = max(128, cnt / 256);
+ net->ipv4.sysctl_tcp_max_orphans = cnt / 2;
net->ipv4.sysctl_tcp_sack = 1;
net->ipv4.sysctl_tcp_window_scaling = 1;
net->ipv4.sysctl_tcp_timestamps = 1;
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH net] Revert "net: phy: Correctly process PHY_HALTED in phy_stop_machine()"
From: Florian Fainelli @ 2017-09-07 1:41 UTC (permalink / raw)
To: David Daney, David Daney, Mason
Cc: Marc Gonzalez, netdev, Geert Uytterhoeven, David Miller,
Andrew Lunn, Mans Rullgard
In-Reply-To: <64800ff2-201b-eb26-304e-1c4c6e0a6d5e@caviumnetworks.com>
On 09/06/2017 05:10 PM, David Daney wrote:
> On 09/06/2017 04:14 PM, Florian Fainelli wrote:
>> On 09/06/2017 03:51 PM, David Daney wrote:
> [...]
>>>
>>> Consider instead the case of a Marvell phy with no interrupts connected
>>> on a v4.9.43 kernel, single CPU:
>>>
>>>
>>> 0) | phy_disconnect() {
>>> 0) | phy_stop_machine() {
>>> 0) | cancel_delayed_work_sync() {
>>> 0) + 23.986 us | } /*
>>> cancel_delayed_work_sync */
>>> 0) | phy_state_machine() {
>>> 0) | phy_start_aneg_priv() {
>>
>> Thanks for providing the trace, I think I have an idea of what's going
>> on, see below.
>>
>>> 0) | marvell_config_aneg() {
>>> 0) ! 240.538 us | } /*
>>> marvell_config_aneg */
>>> 0) ! 244.971 us | } /* phy_start_aneg_priv */
>>> 0) | queue_delayed_work_on() {
>>> 0) + 18.016 us | } /*
>>> queue_delayed_work_on */
>>> 0) ! 268.184 us | } /* phy_state_machine */
>>> 0) ! 297.394 us | } /* phy_stop_machine */
>>> 0) | phy_detach() {
>>> 0) | phy_suspend() {
>>> 0) | phy_ethtool_get_wol() {
>>> 0) 0.677 us | } /* phy_ethtool_get_wol */
>>> 0) | genphy_suspend() {
>>> 0) + 71.250 us | } /* genphy_suspend */
>>> 0) + 74.197 us | } /* phy_suspend */
>>> 0) + 80.302 us | } /* phy_detach */
>>> 0) ! 380.072 us | } /* phy_disconnect */
>>> .
>>> .
>>> .
>>> 0) | process_one_work() {
>>> 0) | find_worker_executing_work() {
>>> 0) 0.688 us | } /* find_worker_executing_work */
>>> 0) | set_work_pool_and_clear_pending() {
>>> 0) 0.734 us | } /* set_work_pool_and_clear_pending */
>>> 0) | phy_state_machine() {
>>> 0) | genphy_read_status() {
>>> 0) ! 205.721 us | } /* genphy_read_status */
>>> 0) | netif_carrier_off() {
>>> 0) | do_page_fault() {
>>>
>>>
>>> The do_page_fault() at the end indicates the NULL pointer dereference.
>>>
>>> That added call to phy_state_machine() turns the polling back on
>>> unconditionally for a phy that should be disconnected. How is that
>>> correct?
>>
>> It is not fundamentally correct and I don't think there was any
>> objection to that to begin with. In fact there is a bug/inefficiency
>> here in that if we have entered the PHY state machine with PHY_HALTED we
>> should not re-schedule it period, only applicable to PHY_POLL cases
>> *and* properly calling phy_stop() followed by phy_disconnect().
>>
>> What I now think is happening in your case is the following:
>>
>> phy_stop() was not called, so nothing does set phydev->state to
>> PHY_HALTED in the first place so we have:
>>
>> phy_disconnect()
>> -> phy_stop_machine()
>> -> cancel_delayed_work_sync() OK
>> phydev->state is probably RUNNING so we have:
>> -> phydev->state = PHY_UP
>> phy_state_machine() is called synchronously
>> -> PHY_UP -> needs_aneg = true
>> -> phy_restart_aneg()
>> -> queue_delayed_work_sync()
>> -> phydev->adjust_link = NULL
>> -> phy_deatch() -> boom
>>
>> Can you confirm whether the driver you are using does call phy_stop()
>> prior to phy_disconnect()?
>
> There is no call to phy_stop().
OK this all makes sense now.
>
> I can add this to the ethernet drivers, but I wonder if it should be
> called by the code code when doing phy_disconnect(), if it was not
> already stopped.
Fixing the driver should be reasonably quick and easy and can be done
independently from fixing PHYLIB, but I agree that PHYLIB should be
safeguarded against such a case.
Of course, now that I looked again at the code, there is really a ton of
unnecessary workqueue scheduling going on, similarly to phy_stop()
making us go from PHY_HALTED to PHY_HALTED, phy_start_machine() does the
same thing with PHY_READY -> PHY_READY, I suppose back when this was
done the assumption was that there is not going to be a tremendous
amount of time being spent between a call to
phy_connect()/phy_start_machine() and phy_start() and respectively
phy_stop() followed by a phy_disconnect(), oh well.
Now that the revert is in 4.13 we can work on a solution that satisfies
everybody on this thread.
Thanks!
--
Florian
^ permalink raw reply
* LOAN AVAILABLE @3 %
From: Mr @ 2017-09-07 1:37 UTC (permalink / raw)
To: Recipients
LOAN AVAILABLE @3 % Rely mohammedanisa01@gmail.com
^ permalink raw reply
* Re: [PATCH net 1/2] i40e: Fix comment about locking for __i40e_read_nvm_word()
From: Jeff Kirsher @ 2017-09-07 1:16 UTC (permalink / raw)
To: Stefano Brivio, netdev, intel-wired-lan
Cc: David S . Miller, Anjali Singhai Jain
In-Reply-To: <4d27bbb33031ac1489fe6d969edd74d44155136c.1504684488.git.sbrivio@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 663 bytes --]
On Wed, 2017-09-06 at 10:11 +0200, Stefano Brivio wrote:
> Caller needs to acquire the lock. Called functions will not.
>
> Fixes: 09f79fd49d94 ("i40e: avoid NVM acquire deadlock during NVM
> update")
> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
> ---
> drivers/net/ethernet/intel/i40e/i40e_nvm.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Yes, this fixes the function header comment, not sure if it requires
the "Fixes:" tag. If that were the case, wonder why all the other code
comment changes do not have this. :-) I do agree it reads better with
this change, so I do not have an issue queue this up for Dave's net
tree.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ 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