* [PATCH 04/17] new helper: memcpy_to_msg()
From: Al Viro @ 2014-11-22 4:31 UTC (permalink / raw)
To: David Miller; +Cc: torvalds, netdev, linux-kernel, target-devel, nab, hch
In-Reply-To: <20141122042856.GZ7996@ZenIV.linux.org.uk>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
crypto/algif_hash.c | 2 +-
include/linux/skbuff.h | 5 +++++
net/caif/caif_socket.c | 2 +-
net/can/bcm.c | 2 +-
net/can/raw.c | 2 +-
net/decnet/af_decnet.c | 2 +-
net/ipv4/tcp.c | 2 +-
net/irda/af_irda.c | 2 +-
net/packet/af_packet.c | 3 +--
9 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c
index 8502462..35c93ff 100644
--- a/crypto/algif_hash.c
+++ b/crypto/algif_hash.c
@@ -174,7 +174,7 @@ static int hash_recvmsg(struct kiocb *unused, struct socket *sock,
goto unlock;
}
- err = memcpy_toiovec(msg->msg_iov, ctx->result, len);
+ err = memcpy_to_msg(msg, ctx->result, len);
unlock:
release_sock(sk);
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index cb7fa2b..18ce42e 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2689,6 +2689,11 @@ static inline int memcpy_from_msg(void *data, struct msghdr *msg, int len)
return memcpy_fromiovec(data, msg->msg_iov, len);
}
+static inline int memcpy_to_msg(struct msghdr *msg, void *data, int len)
+{
+ return memcpy_toiovec(msg->msg_iov, data, len);
+}
+
struct skb_checksum_ops {
__wsum (*update)(const void *mem, int len, __wsum wsum);
__wsum (*combine)(__wsum csum, __wsum csum2, int offset, int len);
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
index 230f140..ac618b0 100644
--- a/net/caif/caif_socket.c
+++ b/net/caif/caif_socket.c
@@ -418,7 +418,7 @@ unlock:
}
release_sock(sk);
chunk = min_t(unsigned int, skb->len, size);
- if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
+ if (memcpy_to_msg(msg, skb->data, chunk)) {
skb_queue_head(&sk->sk_receive_queue, skb);
if (copied == 0)
copied = -EFAULT;
diff --git a/net/can/bcm.c b/net/can/bcm.c
index b9a1f71..0167118 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -1555,7 +1555,7 @@ static int bcm_recvmsg(struct kiocb *iocb, struct socket *sock,
if (skb->len < size)
size = skb->len;
- err = memcpy_toiovec(msg->msg_iov, skb->data, size);
+ err = memcpy_to_msg(msg, skb->data, size);
if (err < 0) {
skb_free_datagram(sk, skb);
return err;
diff --git a/net/can/raw.c b/net/can/raw.c
index 0e4004f..dfdcffb 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -750,7 +750,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock,
else
size = skb->len;
- err = memcpy_toiovec(msg->msg_iov, skb->data, size);
+ err = memcpy_to_msg(msg, skb->data, size);
if (err < 0) {
skb_free_datagram(sk, skb);
return err;
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index e2e2e3c..8102286 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -1760,7 +1760,7 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock,
if ((chunk + copied) > size)
chunk = size - copied;
- if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
+ if (memcpy_to_msg(msg, skb->data, chunk)) {
rv = -EFAULT;
break;
}
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index c239f47..435443b 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1349,7 +1349,7 @@ static int tcp_recv_urg(struct sock *sk, struct msghdr *msg, int len, int flags)
if (len > 0) {
if (!(flags & MSG_TRUNC))
- err = memcpy_toiovec(msg->msg_iov, &c, 1);
+ err = memcpy_to_msg(msg, &c, 1);
len = 1;
} else
msg->msg_flags |= MSG_TRUNC;
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index 9052462..568edc7 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -1466,7 +1466,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
}
chunk = min_t(unsigned int, skb->len, size);
- if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
+ if (memcpy_to_msg(msg, skb->data, chunk)) {
skb_queue_head(&sk->sk_receive_queue, skb);
if (copied == 0)
copied = -EFAULT;
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index be79208..692f049 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2936,8 +2936,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
vnet_hdr.flags = VIRTIO_NET_HDR_F_DATA_VALID;
} /* else everything is zero */
- err = memcpy_toiovec(msg->msg_iov, (void *)&vnet_hdr,
- vnet_hdr_len);
+ err = memcpy_to_msg(msg, (void *)&vnet_hdr, vnet_hdr_len);
if (err < 0)
goto out_free;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH 03/17] switch ipxrtr_route_packet() from iovec to msghdr
From: Al Viro @ 2014-11-22 4:30 UTC (permalink / raw)
To: David Miller; +Cc: torvalds, netdev, linux-kernel, target-devel, nab, hch
In-Reply-To: <20141122042856.GZ7996@ZenIV.linux.org.uk>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
include/net/ipx.h | 2 +-
net/ipx/af_ipx.c | 3 +--
net/ipx/ipx_route.c | 4 ++--
3 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/include/net/ipx.h b/include/net/ipx.h
index 320f47b..e5cff68 100644
--- a/include/net/ipx.h
+++ b/include/net/ipx.h
@@ -150,7 +150,7 @@ int ipxrtr_add_route(__be32 network, struct ipx_interface *intrfc,
unsigned char *node);
void ipxrtr_del_routes(struct ipx_interface *intrfc);
int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx,
- struct iovec *iov, size_t len, int noblock);
+ struct msghdr *msg, size_t len, int noblock);
int ipxrtr_route_skb(struct sk_buff *skb);
struct ipx_route *ipxrtr_lookup(__be32 net);
int ipxrtr_ioctl(unsigned int cmd, void __user *arg);
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index a0c7536..36f7990 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -1745,8 +1745,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock,
memcpy(usipx->sipx_node, ipxs->dest_addr.node, IPX_NODE_LEN);
}
- rc = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len,
- flags & MSG_DONTWAIT);
+ rc = ipxrtr_route_packet(sk, usipx, msg, len, flags & MSG_DONTWAIT);
if (rc >= 0)
rc = len;
out:
diff --git a/net/ipx/ipx_route.c b/net/ipx/ipx_route.c
index 67e7ad3..3e2a32a 100644
--- a/net/ipx/ipx_route.c
+++ b/net/ipx/ipx_route.c
@@ -165,7 +165,7 @@ int ipxrtr_route_skb(struct sk_buff *skb)
* Route an outgoing frame from a socket.
*/
int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx,
- struct iovec *iov, size_t len, int noblock)
+ struct msghdr *msg, size_t len, int noblock)
{
struct sk_buff *skb;
struct ipx_sock *ipxs = ipx_sk(sk);
@@ -229,7 +229,7 @@ int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx,
memcpy(ipx->ipx_dest.node, usipx->sipx_node, IPX_NODE_LEN);
ipx->ipx_dest.sock = usipx->sipx_port;
- rc = memcpy_fromiovec(skb_put(skb, len), iov, len);
+ rc = memcpy_from_msg(skb_put(skb, len), msg, len);
if (rc) {
kfree_skb(skb);
goto out_put;
--
1.7.10.4
^ permalink raw reply related
* [PATCH 02/17] new helper: memcpy_from_msg()
From: Al Viro @ 2014-11-22 4:30 UTC (permalink / raw)
To: David Miller; +Cc: torvalds, netdev, linux-kernel, target-devel, nab, hch
In-Reply-To: <20141122042856.GZ7996@ZenIV.linux.org.uk>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
crypto/algif_skcipher.c | 10 +++++-----
drivers/isdn/mISDN/socket.c | 2 +-
drivers/net/ppp/pppoe.c | 2 +-
include/linux/skbuff.h | 5 +++++
include/net/sctp/sm.h | 2 +-
net/appletalk/ddp.c | 2 +-
net/ax25/af_ax25.c | 2 +-
net/bluetooth/hci_sock.c | 2 +-
net/bluetooth/mgmt.c | 2 +-
net/bluetooth/rfcomm/sock.c | 2 +-
net/bluetooth/sco.c | 2 +-
net/caif/caif_socket.c | 4 ++--
net/can/bcm.c | 19 ++++++++-----------
net/can/raw.c | 2 +-
net/dccp/proto.c | 2 +-
net/decnet/af_decnet.c | 2 +-
net/ieee802154/dgram.c | 2 +-
net/ieee802154/raw.c | 2 +-
net/ipv4/ping.c | 2 +-
net/ipv4/tcp_input.c | 2 +-
net/irda/af_irda.c | 6 +++---
net/iucv/af_iucv.c | 2 +-
net/key/af_key.c | 2 +-
net/l2tp/l2tp_ip.c | 2 +-
net/l2tp/l2tp_ppp.c | 3 +--
net/llc/af_llc.c | 2 +-
net/netlink/af_netlink.c | 2 +-
net/netrom/af_netrom.c | 2 +-
net/nfc/llcp_commands.c | 4 ++--
net/nfc/rawsock.c | 2 +-
net/packet/af_packet.c | 5 ++---
net/phonet/datagram.c | 2 +-
net/phonet/pep.c | 2 +-
net/rose/af_rose.c | 2 +-
net/sctp/sm_make_chunk.c | 4 ++--
net/x25/af_x25.c | 2 +-
36 files changed, 57 insertions(+), 57 deletions(-)
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index 83187f4..c3b482b 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -298,9 +298,9 @@ static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock,
len = min_t(unsigned long, len,
PAGE_SIZE - sg->offset - sg->length);
- err = memcpy_fromiovec(page_address(sg_page(sg)) +
- sg->offset + sg->length,
- msg->msg_iov, len);
+ err = memcpy_from_msg(page_address(sg_page(sg)) +
+ sg->offset + sg->length,
+ msg, len);
if (err)
goto unlock;
@@ -337,8 +337,8 @@ static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock,
if (!sg_page(sg + i))
goto unlock;
- err = memcpy_fromiovec(page_address(sg_page(sg + i)),
- msg->msg_iov, plen);
+ err = memcpy_from_msg(page_address(sg_page(sg + i)),
+ msg, plen);
if (err) {
__free_page(sg_page(sg + i));
sg_assign_page(sg + i, NULL);
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
index dcbd858..84b3592 100644
--- a/drivers/isdn/mISDN/socket.c
+++ b/drivers/isdn/mISDN/socket.c
@@ -203,7 +203,7 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
if (!skb)
goto done;
- if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
+ if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
err = -EFAULT;
goto done;
}
diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
index 443cbbf..d2408a5 100644
--- a/drivers/net/ppp/pppoe.c
+++ b/drivers/net/ppp/pppoe.c
@@ -869,7 +869,7 @@ static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock,
ph = (struct pppoe_hdr *)skb_put(skb, total_len + sizeof(struct pppoe_hdr));
start = (char *)&ph->tag[0];
- error = memcpy_fromiovec(start, m->msg_iov, total_len);
+ error = memcpy_from_msg(start, m, total_len);
if (error < 0) {
kfree_skb(skb);
goto end;
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 4fc4024..cb7fa2b 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2684,6 +2684,11 @@ unsigned int skb_gso_transport_seglen(const struct sk_buff *skb);
struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features);
struct sk_buff *skb_vlan_untag(struct sk_buff *skb);
+static inline int memcpy_from_msg(void *data, struct msghdr *msg, int len)
+{
+ return memcpy_fromiovec(data, msg->msg_iov, len);
+}
+
struct skb_checksum_ops {
__wsum (*update)(const void *mem, int len, __wsum wsum);
__wsum (*combine)(__wsum csum, __wsum csum2, int offset, int len);
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 72a31db..487ef34 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -219,7 +219,7 @@ struct sctp_chunk *sctp_make_abort_no_data(const struct sctp_association *,
const struct sctp_chunk *,
__u32 tsn);
struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *,
- const struct msghdr *, size_t msg_len);
+ struct msghdr *, size_t msg_len);
struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *,
const struct sctp_chunk *,
const __u8 *,
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 425942d..0d0766e 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1659,7 +1659,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
SOCK_DEBUG(sk, "SK %p: Copy user data (%Zd bytes).\n", sk, len);
- err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
+ err = memcpy_from_msg(skb_put(skb, len), msg, len);
if (err) {
kfree_skb(skb);
err = -EFAULT;
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index f4f835e19..ca049a7 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1549,7 +1549,7 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock,
skb_reserve(skb, size - len);
/* User data follows immediately after the AX.25 data */
- if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
+ if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
err = -EFAULT;
kfree_skb(skb);
goto out;
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 5e2cd25..2c245fd 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -947,7 +947,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
if (!skb)
goto done;
- if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
+ if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
err = -EFAULT;
goto drop;
}
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 9c4daf7..824eef7 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -5726,7 +5726,7 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
if (!buf)
return -ENOMEM;
- if (memcpy_fromiovec(buf, msg->msg_iov, msglen)) {
+ if (memcpy_from_msg(buf, msg, msglen)) {
err = -EFAULT;
goto done;
}
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 8bbbb5e..2348176 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -588,7 +588,7 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
}
skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
- err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
+ err = memcpy_from_msg(skb_put(skb, size), msg, size);
if (err) {
kfree_skb(skb);
if (sent == 0)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 7ee9e4a..30e5ea3 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -285,7 +285,7 @@ static int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
if (!skb)
return err;
- if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
+ if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
kfree_skb(skb);
return -EFAULT;
}
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
index fbcd156..230f140 100644
--- a/net/caif/caif_socket.c
+++ b/net/caif/caif_socket.c
@@ -566,7 +566,7 @@ static int caif_seqpkt_sendmsg(struct kiocb *kiocb, struct socket *sock,
skb_reserve(skb, cf_sk->headroom);
- ret = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
+ ret = memcpy_from_msg(skb_put(skb, len), msg, len);
if (ret)
goto err;
@@ -641,7 +641,7 @@ static int caif_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
*/
size = min_t(int, size, skb_tailroom(skb));
- err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
+ err = memcpy_from_msg(skb_put(skb, size), msg, size);
if (err) {
kfree_skb(skb);
goto out_err;
diff --git a/net/can/bcm.c b/net/can/bcm.c
index dcb75c0..b9a1f71 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -858,8 +858,7 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
/* update can_frames content */
for (i = 0; i < msg_head->nframes; i++) {
- err = memcpy_fromiovec((u8 *)&op->frames[i],
- msg->msg_iov, CFSIZ);
+ err = memcpy_from_msg((u8 *)&op->frames[i], msg, CFSIZ);
if (op->frames[i].can_dlc > 8)
err = -EINVAL;
@@ -894,8 +893,7 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
op->frames = &op->sframe;
for (i = 0; i < msg_head->nframes; i++) {
- err = memcpy_fromiovec((u8 *)&op->frames[i],
- msg->msg_iov, CFSIZ);
+ err = memcpy_from_msg((u8 *)&op->frames[i], msg, CFSIZ);
if (op->frames[i].can_dlc > 8)
err = -EINVAL;
@@ -1024,9 +1022,8 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
if (msg_head->nframes) {
/* update can_frames content */
- err = memcpy_fromiovec((u8 *)op->frames,
- msg->msg_iov,
- msg_head->nframes * CFSIZ);
+ err = memcpy_from_msg((u8 *)op->frames, msg,
+ msg_head->nframes * CFSIZ);
if (err < 0)
return err;
@@ -1072,8 +1069,8 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
}
if (msg_head->nframes) {
- err = memcpy_fromiovec((u8 *)op->frames, msg->msg_iov,
- msg_head->nframes * CFSIZ);
+ err = memcpy_from_msg((u8 *)op->frames, msg,
+ msg_head->nframes * CFSIZ);
if (err < 0) {
if (op->frames != &op->sframe)
kfree(op->frames);
@@ -1209,7 +1206,7 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk)
can_skb_reserve(skb);
- err = memcpy_fromiovec(skb_put(skb, CFSIZ), msg->msg_iov, CFSIZ);
+ err = memcpy_from_msg(skb_put(skb, CFSIZ), msg, CFSIZ);
if (err < 0) {
kfree_skb(skb);
return err;
@@ -1285,7 +1282,7 @@ static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock,
/* read message head information */
- ret = memcpy_fromiovec((u8 *)&msg_head, msg->msg_iov, MHSIZ);
+ ret = memcpy_from_msg((u8 *)&msg_head, msg, MHSIZ);
if (ret < 0)
return ret;
diff --git a/net/can/raw.c b/net/can/raw.c
index 081e81f..0e4004f 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -703,7 +703,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock,
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = dev->ifindex;
- err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
+ err = memcpy_from_msg(skb_put(skb, size), msg, size);
if (err < 0)
goto free_skb;
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 8e6ae94..19f0387 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -781,7 +781,7 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
goto out_release;
skb_reserve(skb, sk->sk_prot->max_header);
- rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
+ rc = memcpy_from_msg(skb_put(skb, len), msg, len);
if (rc != 0)
goto out_discard;
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 25733d5..e2e2e3c 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -2032,7 +2032,7 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
skb_reserve(skb, 64 + DN_MAX_NSP_DATA_HEADER);
- if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
+ if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
err = -EFAULT;
goto out;
}
diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c
index b8555ec..2c7a93e 100644
--- a/net/ieee802154/dgram.c
+++ b/net/ieee802154/dgram.c
@@ -276,7 +276,7 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk,
if (err < 0)
goto out_skb;
- err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
+ err = memcpy_from_msg(skb_put(skb, size), msg, size);
if (err < 0)
goto out_skb;
diff --git a/net/ieee802154/raw.c b/net/ieee802154/raw.c
index 21c3894..61e9d29 100644
--- a/net/ieee802154/raw.c
+++ b/net/ieee802154/raw.c
@@ -150,7 +150,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk,
skb_reset_mac_header(skb);
skb_reset_network_header(skb);
- err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
+ err = memcpy_from_msg(skb_put(skb, size), msg, size);
if (err < 0)
goto out_skb;
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index ce2920f..ef8f6ee 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -660,7 +660,7 @@ int ping_common_sendmsg(int family, struct msghdr *msg, size_t len,
* Fetch the ICMP header provided by the userland.
* iovec is modified! The ICMP header is consumed.
*/
- if (memcpy_fromiovec(user_icmph, msg->msg_iov, icmph_len))
+ if (memcpy_from_msg(user_icmph, msg, icmph_len))
return -EFAULT;
if (family == AF_INET) {
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index d91436b..2e5a1e07 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4368,7 +4368,7 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size)
if (tcp_try_rmem_schedule(sk, skb, skb->truesize))
goto err_free;
- if (memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size))
+ if (memcpy_from_msg(skb_put(skb, size), msg, size))
goto err_free;
TCP_SKB_CB(skb)->seq = tcp_sk(sk)->rcv_nxt;
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index e8c4090..9052462 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -1319,7 +1319,7 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock,
skb_reserve(skb, self->max_header_size + 16);
skb_reset_transport_header(skb);
skb_put(skb, len);
- err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len);
+ err = memcpy_from_msg(skb_transport_header(skb), msg, len);
if (err) {
kfree_skb(skb);
goto out_err;
@@ -1569,7 +1569,7 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock,
pr_debug("%s(), appending user data\n", __func__);
skb_put(skb, len);
- err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len);
+ err = memcpy_from_msg(skb_transport_header(skb), msg, len);
if (err) {
kfree_skb(skb);
goto out;
@@ -1678,7 +1678,7 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
pr_debug("%s(), appending user data\n", __func__);
skb_put(skb, len);
- err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len);
+ err = memcpy_from_msg(skb_transport_header(skb), msg, len);
if (err) {
kfree_skb(skb);
goto out;
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index 057b564..1cd3f81 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -1122,7 +1122,7 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
}
if (iucv->transport == AF_IUCV_TRANS_HIPER)
skb_reserve(skb, sizeof(struct af_iucv_trans_hdr) + ETH_HLEN);
- if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
+ if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
err = -EFAULT;
goto fail;
}
diff --git a/net/key/af_key.c b/net/key/af_key.c
index e588309..f8ac939 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -3611,7 +3611,7 @@ static int pfkey_sendmsg(struct kiocb *kiocb,
goto out;
err = -EFAULT;
- if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len))
+ if (memcpy_from_msg(skb_put(skb,len), msg, len))
goto out;
hdr = pfkey_get_base_msg(skb, &err);
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
index a6cc1fe..05dfc8a 100644
--- a/net/l2tp/l2tp_ip.c
+++ b/net/l2tp/l2tp_ip.c
@@ -441,7 +441,7 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
*((__be32 *) skb_put(skb, 4)) = 0;
/* Copy user data into skb */
- rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
+ rc = memcpy_from_msg(skb_put(skb, len), msg, len);
if (rc < 0) {
kfree_skb(skb);
goto error;
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index c559bcd..cc7a828 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -346,8 +346,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
skb_put(skb, 2);
/* Copy user data into skb */
- error = memcpy_fromiovec(skb_put(skb, total_len), m->msg_iov,
- total_len);
+ error = memcpy_from_msg(skb_put(skb, total_len), m, total_len);
if (error < 0) {
kfree_skb(skb);
goto error_put_sess_tun;
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index af662669..2c0b83c 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -921,7 +921,7 @@ static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock,
skb->dev = llc->dev;
skb->protocol = llc_proto_type(addr->sllc_arphrd);
skb_reserve(skb, hdrlen);
- rc = memcpy_fromiovec(skb_put(skb, copied), msg->msg_iov, copied);
+ rc = memcpy_from_msg(skb_put(skb, copied), msg, copied);
if (rc)
goto out;
if (sk->sk_type == SOCK_DGRAM || addr->sllc_ua) {
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index e1aad6e..63aa5c8 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -2325,7 +2325,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
NETLINK_CB(skb).flags = netlink_skb_flags;
err = -EFAULT;
- if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
+ if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
kfree_skb(skb);
goto out;
}
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 7e13f6a..69f1d5e 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -1113,7 +1113,7 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock,
skb_put(skb, len);
/* User data follows immediately after the NET/ROM transport header */
- if (memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len)) {
+ if (memcpy_from_msg(skb_transport_header(skb), msg, len)) {
kfree_skb(skb);
err = -EFAULT;
goto out;
diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c
index a3ad69a..c4da0c2 100644
--- a/net/nfc/llcp_commands.c
+++ b/net/nfc/llcp_commands.c
@@ -665,7 +665,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
if (msg_data == NULL)
return -ENOMEM;
- if (memcpy_fromiovec(msg_data, msg->msg_iov, len)) {
+ if (memcpy_from_msg(msg_data, msg, len)) {
kfree(msg_data);
return -EFAULT;
}
@@ -731,7 +731,7 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap,
if (msg_data == NULL)
return -ENOMEM;
- if (memcpy_fromiovec(msg_data, msg->msg_iov, len)) {
+ if (memcpy_from_msg(msg_data, msg, len)) {
kfree(msg_data);
return -EFAULT;
}
diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c
index 9d7d2b7..373e138 100644
--- a/net/nfc/rawsock.c
+++ b/net/nfc/rawsock.c
@@ -231,7 +231,7 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock,
if (skb == NULL)
return rc;
- rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
+ rc = memcpy_from_msg(skb_put(skb, len), msg, len);
if (rc < 0) {
kfree_skb(skb);
return rc;
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 4cd13d8..be79208 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1676,7 +1676,7 @@ retry:
if (len < hhlen)
skb_reset_network_header(skb);
}
- err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
+ err = memcpy_from_msg(skb_put(skb, len), msg, len);
if (err)
goto out_free;
goto retry;
@@ -2438,8 +2438,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
len -= vnet_hdr_len;
- err = memcpy_fromiovec((void *)&vnet_hdr, msg->msg_iov,
- vnet_hdr_len);
+ err = memcpy_from_msg((void *)&vnet_hdr, msg, vnet_hdr_len);
if (err < 0)
goto out_unlock;
diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c
index 0918bc2..26054b4 100644
--- a/net/phonet/datagram.c
+++ b/net/phonet/datagram.c
@@ -109,7 +109,7 @@ static int pn_sendmsg(struct kiocb *iocb, struct sock *sk,
return err;
skb_reserve(skb, MAX_PHONET_HEADER);
- err = memcpy_fromiovec((void *)skb_put(skb, len), msg->msg_iov, len);
+ err = memcpy_from_msg((void *)skb_put(skb, len), msg, len);
if (err < 0) {
kfree_skb(skb);
return err;
diff --git a/net/phonet/pep.c b/net/phonet/pep.c
index 9cd069d..5d3f2b7 100644
--- a/net/phonet/pep.c
+++ b/net/phonet/pep.c
@@ -1141,7 +1141,7 @@ static int pep_sendmsg(struct kiocb *iocb, struct sock *sk,
return err;
skb_reserve(skb, MAX_PHONET_HEADER + 3 + pn->aligned);
- err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
+ err = memcpy_from_msg(skb_put(skb, len), msg, len);
if (err < 0)
goto outfree;
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 9b600c2..43bac7c 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -1121,7 +1121,7 @@ static int rose_sendmsg(struct kiocb *iocb, struct socket *sock,
skb_reset_transport_header(skb);
skb_put(skb, len);
- err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len);
+ err = memcpy_from_msg(skb_transport_header(skb), msg, len);
if (err) {
kfree_skb(skb);
return err;
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 9f32741..e49bcce 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1001,7 +1001,7 @@ no_mem:
/* Helper to create ABORT with a SCTP_ERROR_USER_ABORT error. */
struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc,
- const struct msghdr *msg,
+ struct msghdr *msg,
size_t paylen)
{
struct sctp_chunk *retval;
@@ -1018,7 +1018,7 @@ struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc,
if (!payload)
goto err_payload;
- err = memcpy_fromiovec(payload, msg->msg_iov, paylen);
+ err = memcpy_from_msg(payload, msg, paylen);
if (err < 0)
goto err_copy;
}
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 59e785b..d9149b6 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -1170,7 +1170,7 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock,
skb_reset_transport_header(skb);
skb_put(skb, len);
- rc = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len);
+ rc = memcpy_from_msg(skb_transport_header(skb), msg, len);
if (rc)
goto out_kfree_skb;
--
1.7.10.4
^ permalink raw reply related
* [PATCH 01/17] new helper: skb_copy_and_csum_datagram_msg()
From: Al Viro @ 2014-11-22 4:29 UTC (permalink / raw)
To: David Miller; +Cc: torvalds, netdev, linux-kernel, target-devel, nab, hch
In-Reply-To: <20141122042856.GZ7996@ZenIV.linux.org.uk>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
include/linux/skbuff.h | 5 +++++
net/ipv4/udp.c | 5 ++---
net/ipv6/raw.c | 2 +-
net/ipv6/udp.c | 2 +-
4 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 73c370e..4fc4024 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2651,6 +2651,11 @@ static inline int skb_copy_datagram_msg(const struct sk_buff *from, int offset,
}
int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb, int hlen,
struct iovec *iov);
+static inline int skb_copy_and_csum_datagram_msg(struct sk_buff *skb, int hlen,
+ struct msghdr *msg)
+{
+ return skb_copy_and_csum_datagram_iovec(skb, hlen, msg->msg_iov);
+}
int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
const struct iovec *from, int from_offset,
int len);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 4a16b91..b2d6068 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1284,9 +1284,8 @@ try_again:
err = skb_copy_datagram_msg(skb, sizeof(struct udphdr),
msg, copied);
else {
- err = skb_copy_and_csum_datagram_iovec(skb,
- sizeof(struct udphdr),
- msg->msg_iov);
+ err = skb_copy_and_csum_datagram_msg(skb, sizeof(struct udphdr),
+ msg);
if (err == -EINVAL)
goto csum_copy_err;
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 0cbcf98..8baa53e 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -492,7 +492,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
goto csum_copy_err;
err = skb_copy_datagram_msg(skb, 0, msg, copied);
} else {
- err = skb_copy_and_csum_datagram_iovec(skb, 0, msg->msg_iov);
+ err = skb_copy_and_csum_datagram_msg(skb, 0, msg);
if (err == -EINVAL)
goto csum_copy_err;
}
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 0ba3de4..961565a 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -427,7 +427,7 @@ try_again:
err = skb_copy_datagram_msg(skb, sizeof(struct udphdr),
msg, copied);
else {
- err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
+ err = skb_copy_and_csum_datagram_msg(skb, sizeof(struct udphdr), msg);
if (err == -EINVAL)
goto csum_copy_err;
}
--
1.7.10.4
^ permalink raw reply related
* Re: [RFC] situation with csum_and_copy_... API
From: Al Viro @ 2014-11-22 4:28 UTC (permalink / raw)
To: David Miller; +Cc: torvalds, netdev, linux-kernel, target-devel, nab, hch
In-Reply-To: <20141121.122615.1091044030302005883.davem@davemloft.net>
OK, here's the next bunch. Sorry about the delay, iov_iter.c stuff
took most of the day (and it's not included in this pile). Please, review.
Al Viro (17):
new helper: skb_copy_and_csum_datagram_msg()
new helper: memcpy_from_msg()
switch ipxrtr_route_packet() from iovec to msghdr
new helper: memcpy_to_msg()
switch drivers/net/tun.c to ->read_iter()
switch macvtap to ->read_iter()
new helpers: skb_copy_datagram_from_iter() and zerocopy_sg_from_iter()
{macvtap,tun}_get_user(): switch to iov_iter
kill zerocopy_sg_from_iovec()
switch AF_PACKET and AF_UNIX to skb_copy_datagram_from_iter()
switch sctp_user_addto_chunk() and sctp_datamsg_from_user() to passing iov_iter
tipc_sendmsg(): pass msghdr instead of its ->msg_iov
tipc_msg_build(): pass msghdr instead of its ->msg_iov
vmci_transport: switch ->enqeue_dgram, ->enqueue_stream and ->dequeue_stream to msghdr
[atm] switch vcc_sendmsg() to copy_from_iter()
rds: switch ->inc_copy_to_user() to passing iov_iter
rds: switch rds_message_copy_from_user() to iov_iter
Patches themselves are in followups...
^ permalink raw reply
* Potential bugs found in ne2k-pci+8390
From: Jia-Ju Bai @ 2014-11-22 3:51 UTC (permalink / raw)
To: netdev
Dear Sir,
I'm very sorry to trouble you.
Recently I test 15 linux device drivers and find some potential bugs both in
Linux 3.8.6 and Linux 3.17.2.
The target file is drivers/net/ethernet/8390/ne2k-pci.c, which is used to
build ne2k-pci.ko. I hope you can help me check my findings:
[1] The function request_region is called by ne2k_pci_init_one when
initializing the ethernet card driver. But when request_region is failed,
which means that it returns the error value, ne2k_pci_init_one returns
immediately to halt the process. However, because pci_enable_device has been
called before request_region in ne2k_pci_init_one, pci_disable_device should
be called before exiting. When the driver works normally, pci_enable_device
and pci_disable_device are called in pairs in ne2k_pci_init_one and
ne2k_pci_remove_one. Moreover, other ethernet card drivers call
pci_enable_device and pci_disable_device in pairs in error handling paths,
such as r8169 and sky2.
[2] The similar problem to [1] occurs when alloc_ei_netdev is failed in
ne2k_pci_init_one.
[3] The similar problem to [1] occurs when register_netdev is failed in
ne2k_pci_init_one.
Could you help me check these findings? Thank you very much, and I'm looking
forward to your reply.
--
Best wishes!
Jia-Ju Bai
E-mail: baijiaju1990@163.com
Department of Computer Science and Technology, Tsinghua University
Address: Room 1-417, West Main, Tsinghua University, Haidian District,
Beijing, 100084, China.
^ permalink raw reply
* [net PATCH] ipv6: Do not treat a GSO_TCPV4 request from UDP tunnel over IPv6 as invalid
From: Alexander Duyck @ 2014-11-22 3:37 UTC (permalink / raw)
To: netdev; +Cc: davem
This patch adds SKB_GSO_TCPV4 to the list of supported GSO types handled by
the IPv6 GSO offloads. Without this change VXLAN tunnels running over IPv6
do not currently handle IPv4 TCP TSO requests correctly and end up handing
the non-segmented frame off to the device.
Below is the before and after for a simple netperf TCP_STREAM test between
two endpoints tunneling IPv4 over a VXLAN tunnel running on IPv6 on top of
a 1Gb/s network adapter.
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec
87380 16384 16384 10.29 0.88 Before
87380 16384 16384 10.03 895.69 After
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
---
net/ipv6/ip6_offload.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c
index a071563..01e12d0 100644
--- a/net/ipv6/ip6_offload.c
+++ b/net/ipv6/ip6_offload.c
@@ -69,7 +69,8 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
int nhoff;
if (unlikely(skb_shinfo(skb)->gso_type &
- ~(SKB_GSO_UDP |
+ ~(SKB_GSO_TCPV4 |
+ SKB_GSO_UDP |
SKB_GSO_DODGY |
SKB_GSO_TCP_ECN |
SKB_GSO_GRE |
^ permalink raw reply related
* Re: [RFC] situation with csum_and_copy_... API
From: Al Viro @ 2014-11-22 3:36 UTC (permalink / raw)
To: Linus Torvalds
Cc: David Miller, netdev, linux-kernel, target-devel,
Nicholas A. Bellinger, Christoph Hellwig, Eric Dumazet
In-Reply-To: <20141122032718.GA24457@ZenIV.linux.org.uk>
On Sat, Nov 22, 2014 at 03:27:18AM +0000, Al Viro wrote:
> @@ -566,38 +445,15 @@ static size_t copy_to_iter_bvec(void *from, size_t bytes, struct iov_iter *i)
[snip]
> + iterate_bvec(i, bytes, page, off, len, true,
> + memcpy_from_page((from += len) - len, page, off, len))
should be
+ memcpy_to_page(page, off, (from += len) - len, len))
and
> @@ -605,35 +461,9 @@ static size_t copy_from_iter_bvec(void *to, size_t bytes, struct iov_iter *i)
[snip]
> + iterate_bvec(i, bytes, page, off, len, true,
> + memcpy_to_page(page, off, (to += len) - len, len))
should be
+ memcpy_from_page((to += len) - len, page, off, len))
Sorry, wrong delta.
^ permalink raw reply
* Re: linux-next: build failure after merge of the net-next tree
From: David Miller @ 2014-11-22 3:30 UTC (permalink / raw)
To: sfr; +Cc: netdev, linux-next, linux-kernel, jrajahalme, pshelar
In-Reply-To: <20141117133404.525229b4@canb.auug.org.au>
From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Mon, 17 Nov 2014 13:34:04 +1100
> I applied the following merge fix patch:
>
> From: Stephen Rothwell <sfr@canb.auug.org.au>
> Date: Mon, 17 Nov 2014 13:31:33 +1100
> Subject: [PATCH] openvswitch: fix up for OVS_NLERR API change
>
> Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Thanks Stephen, I integrated this into the merge commit when
I merge net into net-next just now.
Thanks again.
^ permalink raw reply
* Re: [RFC] situation with csum_and_copy_... API
From: Al Viro @ 2014-11-22 3:27 UTC (permalink / raw)
To: Linus Torvalds
Cc: David Miller, netdev, linux-kernel, target-devel,
Nicholas A. Bellinger, Christoph Hellwig, Eric Dumazet
In-Reply-To: <20141121084956.GT7996@ZenIV.linux.org.uk>
On Fri, Nov 21, 2014 at 08:49:56AM +0000, Al Viro wrote:
> Overall, I think I have the whole series plotted in enough details to be
> reasonably certain we can pull it off. Right now I'm dealing with
> mm/iov_iter.c stuff; the amount of boilerplate source is already high enough
> and with those extra primitives it'll get really unpleasant.
>
> What we need there is something templates-like, as much as I hate C++, and
> I'm still not happy with what I have at the moment... Hopefully I'll get
> that in more or less tolerable form today.
Folks, I would really like comments on the patch below. It's an attempt
to reduce the amount of boilerplate code in mm/iov_iter.c; no new primitives
added, just trying to reduce the amount of duplication in there. I'm not
too fond of the way it currently looks, to put it mildly. It seems to
work, it's reasonably straightforward and it even generates slightly better
code than before, but I would _very_ welcome any tricks that would allow to
make it not so tasteless. I like the effect on line count (+124-358), but...
It defines two iterators (for iovec-backed and bvec-backed ones) and converts
a bunch of primitives to those. The last argument is an expression evaluated
for a bunch of ranges; for bvec one it's void, for iovec - size_t; if it
evaluates to non-0, we treat it as read/write/whatever short by that many
bytes and do not proceed any further.
Any suggestions are welcome.
diff --git a/mm/iov_iter.c b/mm/iov_iter.c
index eafcf60..611af2bd 100644
--- a/mm/iov_iter.c
+++ b/mm/iov_iter.c
@@ -4,11 +4,75 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
+#define iterate_iovec(i, n, buf, len, move, STEP) { \
+ const struct iovec *iov = i->iov; \
+ size_t skip = i->iov_offset; \
+ size_t left; \
+ size_t wanted = n; \
+ buf = iov->iov_base + skip; \
+ len = min(n, iov->iov_len - skip); \
+ left = STEP; \
+ len -= left; \
+ skip += len; \
+ n -= len; \
+ while (unlikely(!left && n)) { \
+ iov++; \
+ buf = iov->iov_base; \
+ len = min(n, iov->iov_len); \
+ left = STEP; \
+ len -= left; \
+ skip = len; \
+ n -= len; \
+ } \
+ n = wanted - n; \
+ if (move) { \
+ if (skip == iov->iov_len) { \
+ iov++; \
+ skip = 0; \
+ } \
+ i->count -= n; \
+ i->nr_segs -= iov - i->iov; \
+ i->iov = iov; \
+ i->iov_offset = skip; \
+ } \
+}
+
+#define iterate_bvec(i, n, page, off, len, move, STEP) {\
+ const struct bio_vec *bvec = i->bvec; \
+ size_t skip = i->iov_offset; \
+ size_t wanted = n; \
+ page = bvec->bv_page; \
+ off = bvec->bv_offset + skip; \
+ len = min_t(size_t, n, bvec->bv_len - skip); \
+ STEP; \
+ skip += len; \
+ n -= len; \
+ while (unlikely(n)) { \
+ bvec++; \
+ page = bvec->bv_page; \
+ off = bvec->bv_offset; \
+ len = min_t(size_t, n, bvec->bv_len); \
+ STEP; \
+ skip = len; \
+ n -= len; \
+ } \
+ n = wanted; \
+ if (move) { \
+ if (skip == bvec->bv_len) { \
+ bvec++; \
+ skip = 0; \
+ } \
+ i->count -= n; \
+ i->nr_segs -= bvec - i->bvec; \
+ i->bvec = bvec; \
+ i->iov_offset = skip; \
+ } \
+}
+
static size_t copy_to_iter_iovec(void *from, size_t bytes, struct iov_iter *i)
{
- size_t skip, copy, left, wanted;
- const struct iovec *iov;
char __user *buf;
+ size_t len;
if (unlikely(bytes > i->count))
bytes = i->count;
@@ -16,44 +80,15 @@ static size_t copy_to_iter_iovec(void *from, size_t bytes, struct iov_iter *i)
if (unlikely(!bytes))
return 0;
- wanted = bytes;
- iov = i->iov;
- skip = i->iov_offset;
- buf = iov->iov_base + skip;
- copy = min(bytes, iov->iov_len - skip);
-
- left = __copy_to_user(buf, from, copy);
- copy -= left;
- skip += copy;
- from += copy;
- bytes -= copy;
- while (unlikely(!left && bytes)) {
- iov++;
- buf = iov->iov_base;
- copy = min(bytes, iov->iov_len);
- left = __copy_to_user(buf, from, copy);
- copy -= left;
- skip = copy;
- from += copy;
- bytes -= copy;
- }
-
- if (skip == iov->iov_len) {
- iov++;
- skip = 0;
- }
- i->count -= wanted - bytes;
- i->nr_segs -= iov - i->iov;
- i->iov = iov;
- i->iov_offset = skip;
- return wanted - bytes;
+ iterate_iovec(i, bytes, buf, len, true,
+ __copy_to_user(buf, (from += len) - len, len))
+ return bytes;
}
static size_t copy_from_iter_iovec(void *to, size_t bytes, struct iov_iter *i)
{
- size_t skip, copy, left, wanted;
- const struct iovec *iov;
char __user *buf;
+ size_t len;
if (unlikely(bytes > i->count))
bytes = i->count;
@@ -61,37 +96,9 @@ static size_t copy_from_iter_iovec(void *to, size_t bytes, struct iov_iter *i)
if (unlikely(!bytes))
return 0;
- wanted = bytes;
- iov = i->iov;
- skip = i->iov_offset;
- buf = iov->iov_base + skip;
- copy = min(bytes, iov->iov_len - skip);
-
- left = __copy_from_user(to, buf, copy);
- copy -= left;
- skip += copy;
- to += copy;
- bytes -= copy;
- while (unlikely(!left && bytes)) {
- iov++;
- buf = iov->iov_base;
- copy = min(bytes, iov->iov_len);
- left = __copy_from_user(to, buf, copy);
- copy -= left;
- skip = copy;
- to += copy;
- bytes -= copy;
- }
-
- if (skip == iov->iov_len) {
- iov++;
- skip = 0;
- }
- i->count -= wanted - bytes;
- i->nr_segs -= iov - i->iov;
- i->iov = iov;
- i->iov_offset = skip;
- return wanted - bytes;
+ iterate_iovec(i, bytes, buf, len, true,
+ __copy_from_user((to += len) - len, buf, len))
+ return bytes;
}
static size_t copy_page_to_iter_iovec(struct page *page, size_t offset, size_t bytes,
@@ -256,134 +263,6 @@ done:
return wanted - bytes;
}
-static size_t zero_iovec(size_t bytes, struct iov_iter *i)
-{
- size_t skip, copy, left, wanted;
- const struct iovec *iov;
- char __user *buf;
-
- if (unlikely(bytes > i->count))
- bytes = i->count;
-
- if (unlikely(!bytes))
- return 0;
-
- wanted = bytes;
- iov = i->iov;
- skip = i->iov_offset;
- buf = iov->iov_base + skip;
- copy = min(bytes, iov->iov_len - skip);
-
- left = __clear_user(buf, copy);
- copy -= left;
- skip += copy;
- bytes -= copy;
-
- while (unlikely(!left && bytes)) {
- iov++;
- buf = iov->iov_base;
- copy = min(bytes, iov->iov_len);
- left = __clear_user(buf, copy);
- copy -= left;
- skip = copy;
- bytes -= copy;
- }
-
- if (skip == iov->iov_len) {
- iov++;
- skip = 0;
- }
- i->count -= wanted - bytes;
- i->nr_segs -= iov - i->iov;
- i->iov = iov;
- i->iov_offset = skip;
- return wanted - bytes;
-}
-
-static size_t __iovec_copy_from_user_inatomic(char *vaddr,
- const struct iovec *iov, size_t base, size_t bytes)
-{
- size_t copied = 0, left = 0;
-
- while (bytes) {
- char __user *buf = iov->iov_base + base;
- int copy = min(bytes, iov->iov_len - base);
-
- base = 0;
- left = __copy_from_user_inatomic(vaddr, buf, copy);
- copied += copy;
- bytes -= copy;
- vaddr += copy;
- iov++;
-
- if (unlikely(left))
- break;
- }
- return copied - left;
-}
-
-/*
- * Copy as much as we can into the page and return the number of bytes which
- * were successfully copied. If a fault is encountered then return the number of
- * bytes which were copied.
- */
-static size_t copy_from_user_atomic_iovec(struct page *page,
- struct iov_iter *i, unsigned long offset, size_t bytes)
-{
- char *kaddr;
- size_t copied;
-
- kaddr = kmap_atomic(page);
- if (likely(i->nr_segs == 1)) {
- int left;
- char __user *buf = i->iov->iov_base + i->iov_offset;
- left = __copy_from_user_inatomic(kaddr + offset, buf, bytes);
- copied = bytes - left;
- } else {
- copied = __iovec_copy_from_user_inatomic(kaddr + offset,
- i->iov, i->iov_offset, bytes);
- }
- kunmap_atomic(kaddr);
-
- return copied;
-}
-
-static void advance_iovec(struct iov_iter *i, size_t bytes)
-{
- BUG_ON(i->count < bytes);
-
- if (likely(i->nr_segs == 1)) {
- i->iov_offset += bytes;
- i->count -= bytes;
- } else {
- const struct iovec *iov = i->iov;
- size_t base = i->iov_offset;
- unsigned long nr_segs = i->nr_segs;
-
- /*
- * The !iov->iov_len check ensures we skip over unlikely
- * zero-length segments (without overruning the iovec).
- */
- while (bytes || unlikely(i->count && !iov->iov_len)) {
- int copy;
-
- copy = min(bytes, iov->iov_len - base);
- BUG_ON(!i->count || i->count < copy);
- i->count -= copy;
- bytes -= copy;
- base += copy;
- if (iov->iov_len == base) {
- iov++;
- nr_segs--;
- base = 0;
- }
- }
- i->iov = iov;
- i->iov_offset = base;
- i->nr_segs = nr_segs;
- }
-}
-
/*
* Fault in the first iovec of the given iov_iter, to a maximum length
* of bytes. Returns 0 on success, or non-zero if the memory could not be
@@ -557,8 +436,8 @@ static void memzero_page(struct page *page, size_t offset, size_t len)
static size_t copy_to_iter_bvec(void *from, size_t bytes, struct iov_iter *i)
{
- size_t skip, copy, wanted;
- const struct bio_vec *bvec;
+ struct page *page;
+ size_t off, len;
if (unlikely(bytes > i->count))
bytes = i->count;
@@ -566,38 +445,15 @@ static size_t copy_to_iter_bvec(void *from, size_t bytes, struct iov_iter *i)
if (unlikely(!bytes))
return 0;
- wanted = bytes;
- bvec = i->bvec;
- skip = i->iov_offset;
- copy = min_t(size_t, bytes, bvec->bv_len - skip);
-
- memcpy_to_page(bvec->bv_page, skip + bvec->bv_offset, from, copy);
- skip += copy;
- from += copy;
- bytes -= copy;
- while (bytes) {
- bvec++;
- copy = min(bytes, (size_t)bvec->bv_len);
- memcpy_to_page(bvec->bv_page, bvec->bv_offset, from, copy);
- skip = copy;
- from += copy;
- bytes -= copy;
- }
- if (skip == bvec->bv_len) {
- bvec++;
- skip = 0;
- }
- i->count -= wanted - bytes;
- i->nr_segs -= bvec - i->bvec;
- i->bvec = bvec;
- i->iov_offset = skip;
- return wanted - bytes;
+ iterate_bvec(i, bytes, page, off, len, true,
+ memcpy_from_page((from += len) - len, page, off, len))
+ return bytes;
}
static size_t copy_from_iter_bvec(void *to, size_t bytes, struct iov_iter *i)
{
- size_t skip, copy, wanted;
- const struct bio_vec *bvec;
+ struct page *page;
+ size_t off, len;
if (unlikely(bytes > i->count))
bytes = i->count;
@@ -605,35 +461,9 @@ static size_t copy_from_iter_bvec(void *to, size_t bytes, struct iov_iter *i)
if (unlikely(!bytes))
return 0;
- wanted = bytes;
- bvec = i->bvec;
- skip = i->iov_offset;
-
- copy = min(bytes, bvec->bv_len - skip);
-
- memcpy_from_page(to, bvec->bv_page, bvec->bv_offset + skip, copy);
-
- to += copy;
- skip += copy;
- bytes -= copy;
-
- while (bytes) {
- bvec++;
- copy = min(bytes, (size_t)bvec->bv_len);
- memcpy_from_page(to, bvec->bv_page, bvec->bv_offset, copy);
- skip = copy;
- to += copy;
- bytes -= copy;
- }
- if (skip == bvec->bv_len) {
- bvec++;
- skip = 0;
- }
- i->count -= wanted;
- i->nr_segs -= bvec - i->bvec;
- i->bvec = bvec;
- i->iov_offset = skip;
- return wanted;
+ iterate_bvec(i, bytes, page, off, len, true,
+ memcpy_to_page(page, off, (to += len) - len, len))
+ return bytes;
}
static size_t copy_page_to_iter_bvec(struct page *page, size_t offset,
@@ -654,101 +484,6 @@ static size_t copy_page_from_iter_bvec(struct page *page, size_t offset,
return wanted;
}
-static size_t zero_bvec(size_t bytes, struct iov_iter *i)
-{
- size_t skip, copy, wanted;
- const struct bio_vec *bvec;
-
- if (unlikely(bytes > i->count))
- bytes = i->count;
-
- if (unlikely(!bytes))
- return 0;
-
- wanted = bytes;
- bvec = i->bvec;
- skip = i->iov_offset;
- copy = min_t(size_t, bytes, bvec->bv_len - skip);
-
- memzero_page(bvec->bv_page, skip + bvec->bv_offset, copy);
- skip += copy;
- bytes -= copy;
- while (bytes) {
- bvec++;
- copy = min(bytes, (size_t)bvec->bv_len);
- memzero_page(bvec->bv_page, bvec->bv_offset, copy);
- skip = copy;
- bytes -= copy;
- }
- if (skip == bvec->bv_len) {
- bvec++;
- skip = 0;
- }
- i->count -= wanted - bytes;
- i->nr_segs -= bvec - i->bvec;
- i->bvec = bvec;
- i->iov_offset = skip;
- return wanted - bytes;
-}
-
-static size_t copy_from_user_bvec(struct page *page,
- struct iov_iter *i, unsigned long offset, size_t bytes)
-{
- char *kaddr;
- size_t left;
- const struct bio_vec *bvec;
- size_t base = i->iov_offset;
-
- kaddr = kmap_atomic(page);
- for (left = bytes, bvec = i->bvec; left; bvec++, base = 0) {
- size_t copy = min(left, bvec->bv_len - base);
- if (!bvec->bv_len)
- continue;
- memcpy_from_page(kaddr + offset, bvec->bv_page,
- bvec->bv_offset + base, copy);
- offset += copy;
- left -= copy;
- }
- kunmap_atomic(kaddr);
- return bytes;
-}
-
-static void advance_bvec(struct iov_iter *i, size_t bytes)
-{
- BUG_ON(i->count < bytes);
-
- if (likely(i->nr_segs == 1)) {
- i->iov_offset += bytes;
- i->count -= bytes;
- } else {
- const struct bio_vec *bvec = i->bvec;
- size_t base = i->iov_offset;
- unsigned long nr_segs = i->nr_segs;
-
- /*
- * The !iov->iov_len check ensures we skip over unlikely
- * zero-length segments (without overruning the iovec).
- */
- while (bytes || unlikely(i->count && !bvec->bv_len)) {
- int copy;
-
- copy = min(bytes, bvec->bv_len - base);
- BUG_ON(!i->count || i->count < copy);
- i->count -= copy;
- bytes -= copy;
- base += copy;
- if (bvec->bv_len == base) {
- bvec++;
- nr_segs--;
- base = 0;
- }
- }
- i->bvec = bvec;
- i->iov_offset = base;
- i->nr_segs = nr_segs;
- }
-}
-
static unsigned long alignment_bvec(const struct iov_iter *i)
{
const struct bio_vec *bvec = i->bvec;
@@ -876,30 +611,61 @@ EXPORT_SYMBOL(copy_from_iter);
size_t iov_iter_zero(size_t bytes, struct iov_iter *i)
{
+ if (unlikely(bytes > i->count))
+ bytes = i->count;
+
+ if (unlikely(!bytes))
+ return 0;
+
if (i->type & ITER_BVEC) {
- return zero_bvec(bytes, i);
+ struct page *page;
+ size_t off, len;
+ iterate_bvec(i, bytes, page, off, len, true,
+ memzero_page(page, off, len))
} else {
- return zero_iovec(bytes, i);
+ char __user *buf;
+ size_t len;
+ iterate_iovec(i, bytes, buf, len, true,
+ __clear_user(buf, len))
}
+ return bytes;
}
EXPORT_SYMBOL(iov_iter_zero);
size_t iov_iter_copy_from_user_atomic(struct page *page,
struct iov_iter *i, unsigned long offset, size_t bytes)
{
- if (i->type & ITER_BVEC)
- return copy_from_user_bvec(page, i, offset, bytes);
- else
- return copy_from_user_atomic_iovec(page, i, offset, bytes);
+ char *kaddr = kmap_atomic(page), *p = kaddr + offset;
+ if (i->type & ITER_BVEC) {
+ struct page *page;
+ size_t off, len;
+ iterate_bvec(i, bytes, page, off, len, false,
+ memcpy_from_page((p += len) - len, page, off, len))
+ } else {
+ char __user *buf;
+ size_t len;
+ iterate_iovec(i, bytes, buf, len, false,
+ __copy_from_user_inatomic((p += len) - len,
+ buf, len))
+ }
+ kunmap_atomic(kaddr);
+ return bytes;
}
EXPORT_SYMBOL(iov_iter_copy_from_user_atomic);
void iov_iter_advance(struct iov_iter *i, size_t size)
{
- if (i->type & ITER_BVEC)
- advance_bvec(i, size);
- else
- advance_iovec(i, size);
+ if (i->type & ITER_BVEC) {
+ struct page *page;
+ size_t off, len;
+ iterate_bvec(i, size, page, off, len, true,
+ (void)0)
+ } else {
+ char __user *buf;
+ size_t len;
+ iterate_iovec(i, size, buf, len, true,
+ 0)
+ }
}
EXPORT_SYMBOL(iov_iter_advance);
^ permalink raw reply related
* Re: [PATCH v2 9/9] netfilter: Replace smp_read_barrier_depends() with lockless_dereference()
From: Pranith Kumar @ 2014-11-22 1:23 UTC (permalink / raw)
To: Eric Dumazet
Cc: Pablo Neira Ayuso, Patrick McHardy, Jozsef Kadlecsik,
David S. Miller, Alexey Kuznetsov, James Morris,
Hideaki YOSHIFUJI, netfilter-devel, coreteam,
open list:NETWORKING [IPv4/..., open list, Paul McKenney
In-Reply-To: <1416614703.20938.0.camel@edumazet-glaptop2.roam.corp.google.com>
On Fri, Nov 21, 2014 at 7:05 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
> On Fri, 2014-11-21 at 16:57 -0500, Pranith Kumar wrote:
>
>> Hi Eric,
>>
>> Thanks for looking at this patch.
>>
>> I've been scratching my head since morning trying to find out what was
>> so obviously wrong with this patch. Alas, I don't see what you do.
>>
>> Could you point it out and show me how incompetent I am, please?
>>
>> Thanks!
>
> Well, even it the code is _not_ broken, I don't see any value with this
> patch.
Phew. Not being broken itself is a win :)
>
> If I use git blame on current code, line containing
> smp_read_barrier_depends() exactly points to the relevant commit [1]
And that is an opinion I will respect. I don't want to muck the git
history where it is significant.
This effort is to eventually replace the uses of
smp_read_barrier_depends() and to use either rcu or
lockless_dereference() as documented in memory-barriers.txt.
>
> After your change, it will point to some cleanup, which makes little
> sense to me, considering you did not change the smp_wmb() in
> xt_replace_table().
That does not need to change as it is fine as it is. It still pairs
with the smp_read_barrier_depends() in lockless_dereference().
>
> I, as a netfilter contributor would like to keep current code as is,
> because it is how I feel safe with it.
>
> We have a proliferation of interfaces, but this does not help to
> understand the issues and code maintenance.
>
> smp_read_barrier_depends() better documents the read barrier than
> lockless_dereference().
I think this is a matter of opinion. But in the current effort I've
seen cases where it is not clear what the barrier is actually
guaranteeing. I am glad that the current code is not one of those and
it has reasonable comments.
lockless_dereference() on the other hand makes the dependency explicit.
>
> The point of having a lock or not is irrelevant here.
>
> [1]
> http://git.kernel.org/cgit/linux/kernel/git/davem/net.git/commit/?id=b416c144f46af1a30ddfa4e4319a8f077381ad63
>
>
>
>
Thanks!
--
Pranith
^ permalink raw reply
* Re: [RFC PATCH 4/4] bridge: make hw offload conditional on bridge and bridge port offload flags
From: Roopa Prabhu @ 2014-11-22 0:33 UTC (permalink / raw)
To: Thomas Graf
Cc: jiri, sfeldma, jhs, bcrl, john.fastabend, stephen, linville,
nhorman, nicolas.dichtel, vyasevic, f.fainelli, buytenh, aviadr,
netdev, davem, Shrijeet Mukherjee, gospo
In-Reply-To: <20141121233054.GB20810@casper.infradead.org>
On 11/21/14, 3:30 PM, Thomas Graf wrote:
> On 11/21/14 at 02:49pm, roopa@cumulusnetworks.com wrote:
>> + nla_put_u8(skb, IFLA_BRPORT_GUARD,
>> + br_get_port_flag(p, IFLA_BRPORT_GUARD, BR_BPDU_GUARD)) ||
> A helper taking nla_put_br_flag(port, skb, attrtype, brflag) would simplify
> this code a lot.
sure
>
>> @@ -305,7 +312,9 @@ static int br_set_port_state(struct net_bridge_port *p, u8 state)
>>
>> br_set_state(p, state);
>> br_log_state(p);
>> - netdev_sw_port_stp_update(p->dev, p->state);
>> +
>> + if (BR_HW_OFFLOAD(p->br))
>> + netdev_sw_port_set_attr(p->dev, IFLA_BRPORT_STATE, &p->state);
> I assume the yet unfinished netdev_sw_port_set_attr() will call
> netdev_sw_port_stp_update()?
netdev_sw_port_set_attr will just call the switch driver ndo for bridge port attributes. (ndo_sw_bridge_port_set_attr()).
On that note it would be nice to rename the whole thing (the other thread on "sw" vs "offload"), this could be
renamed to netdev_offload_bridge_port_set_attr() or something along those lines.
>
>> @@ -316,13 +325,34 @@ static void br_set_port_flag(struct net_bridge_port *p, struct nlattr *tb[],
>> {
>> if (tb[attrtype]) {
>> u8 flag = nla_get_u8(tb[attrtype]);
>> - if (flag)
>> - p->flags |= mask;
>> - else
>> + if (flag) {
>> + flag_upper = flag & 0xf0
>> + if (!flag_upper || (flag_upper & BRPORT_KERNEL))
>> + p->flags |= mask;
>> + if ((flag_upper & BRPORT_HW_OFFLOAD) ||
>> + (BR_HW_OFFLOAD(p->br)))
>> + /* Also set the port flag in hw */
>> + netdev_sw_port_set_attr(p->dev, attrtype, 1);
> I'm not sure I understand the || here. HW_OFFLOAD enabled on the
> net_device is a conditional for all netdev_sw_port_set_attr() calls
> and at the same time implies BRPORT_HW_OFFLOAD on all attributes.
Just realized this needs another condition, I will fix it.
The idea is, the port attribute flags BRPORT_KERNEL and BRPORT_HW_OFFLOAD
can be used to override the HW_OFFLOAD flag on the bridge netdev.
You will only call the swdev api to offload the bridge port flag,
if the bridge netdev has the HW_OFFLOAD flag set and also the per port
attribute flag
does not override it.
> As I read this code now, I don't see how you would offload individual
> features to hardware.
This is for offloading individual bridge port flags like learning and
flooding.
You want to be able to HW_OFFLOAD the bridge device, but be able to
control offloading of some of the port flags
like learning and flooding. For example some of the realtek devices
might want to turn learning in hw off by default
but learn in software.
>
>> diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
>> index 8f3f081..3ebd196 100644
>> --- a/net/bridge/br_private.h
>> +++ b/net/bridge/br_private.h
>> @@ -41,6 +41,8 @@
>> /* Path to usermode spanning tree program */
>> #define BR_STP_PROG "/sbin/bridge-stp"
>>
>> +#define BR_HW_OFFLOAD(br) !!(br->dev->features & NETIF_F_HW_OFFLOAD)
> Let's not add more non type safe macros. A static inline seems like
> a better fit here.
sure, ack.
Thanks for the review.
^ permalink raw reply
* Re: [PATCH v2 9/9] netfilter: Replace smp_read_barrier_depends() with lockless_dereference()
From: Andres Freund @ 2014-11-22 0:24 UTC (permalink / raw)
To: Pranith Kumar
Cc: Eric Dumazet, Pablo Neira Ayuso, Patrick McHardy,
Jozsef Kadlecsik, David S. Miller, Alexey Kuznetsov, James Morris,
Hideaki YOSHIFUJI, netfilter-devel, coreteam,
open list:NETWORKING [IPv4/..., open list
In-Reply-To: <CAJhHMCCCSU7PbWdgPouefbLJBcoxR8nmsS8dg_=BcuqVJZbDew@mail.gmail.com>
Hi,
On 2014-11-21 16:57:00 -0500, Pranith Kumar wrote:
> On Fri, Nov 21, 2014 at 11:12 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> > On Fri, 2014-11-21 at 10:06 -0500, Pranith Kumar wrote:
> >> Recently lockless_dereference() was added which can be used in place of
> >> hard-coding smp_read_barrier_depends(). The following PATCH makes the change.
> >>
> >> Signed-off-by: Pranith Kumar <bobby.prani@gmail.com>
> >> ---
> >> net/ipv4/netfilter/arp_tables.c | 3 +--
> >> net/ipv4/netfilter/ip_tables.c | 3 +--
> >> net/ipv6/netfilter/ip6_tables.c | 3 +--
> >> 3 files changed, 3 insertions(+), 6 deletions(-)
> >>
> >> diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
> >> index f95b6f9..fc7533d 100644
> >> --- a/net/ipv4/netfilter/arp_tables.c
> >> +++ b/net/ipv4/netfilter/arp_tables.c
> >> @@ -270,12 +270,11 @@ unsigned int arpt_do_table(struct sk_buff *skb,
> >>
> >> local_bh_disable();
> >> addend = xt_write_recseq_begin();
> >> - private = table->private;
> >> /*
> >> * Ensure we load private-> members after we've fetched the base
> >> * pointer.
> >> */
> >> - smp_read_barrier_depends();
> >> + private = lockless_dereference(table->private);
> >> table_base = private->entries[smp_processor_id()];
> >>
> >
> >
> > Please carefully read the code, before and after your change, then
> > you'll see this change broke the code.
> >
> > Problem is that a bug like that can be really hard to diagnose and fix
> > later, so really you have to be very careful doing these mechanical
> > changes.
> >
> > IMO, current code+comment is better than with this
> > lockless_dereference() which in this particular case obfuscates the
> > code. more than anything.
> >
> > In this case we do have a lock (sort of), so lockless_dereference() is
> > quite misleading.
> >
>
> Hi Eric,
>
> Thanks for looking at this patch.
>
> I've been scratching my head since morning trying to find out what was
> so obviously wrong with this patch. Alas, I don't see what you do.
Afaics the read_barrier_depends protected the load from private->entries[x]
earlier, not the load of table->private itself.
Greetings,
Andres Freund
^ permalink raw reply
* Re: [RFC PATCH 1/4] rtnetlink: new flag NLM_F_HW_OFFLOAD to indicate kernel object offload to hardware
From: Roopa Prabhu @ 2014-11-22 0:10 UTC (permalink / raw)
To: Thomas Graf
Cc: jiri, sfeldma, jhs, bcrl, john.fastabend, stephen, linville,
nhorman, nicolas.dichtel, vyasevic, f.fainelli, buytenh, aviadr,
netdev, davem, Shrijeet Mukherjee, gospo
In-Reply-To: <20141121231234.GA20810@casper.infradead.org>
On 11/21/14, 3:12 PM, Thomas Graf wrote:
> On 11/21/14 at 02:49pm, roopa@cumulusnetworks.com wrote:
>> diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h
>> index 1a85940..f78522d 100644
>> --- a/include/uapi/linux/netlink.h
>> +++ b/include/uapi/linux/netlink.h
>> @@ -54,6 +54,8 @@ struct nlmsghdr {
>> #define NLM_F_ACK 4 /* Reply with ack, with zero or error code */
>> #define NLM_F_ECHO 8 /* Echo this request */
>> #define NLM_F_DUMP_INTR 16 /* Dump was inconsistent due to sequence change */
>> ++#define NLM_F_KERNEL 32 /* This msg is only for the kernel */
>> +#define NLM_F_HW_OFFLOAD 64 /* offload this msg to hw */
>>
>> /* Modifiers to GET request */
>> #define NLM_F_ROOT 0x100 /* specify tree root */
> The NLM_F_ flag space applies to all Netlink messages including non
> networking bits and is reserved for flags vital to the functioning
> of the Netlink protocol itself. I suggest you move this to a
> RTNETLINK specific flags space.
I did try to add it at a layer lower than the netlink header. But,
nothing else fits so well as this :).
I did not find a place where i could make it a global flag for just
networking objects. As I mention in my patch description,
If not here it will be a per subsystem flag/attribute. I can post a
patch showing that approach as well.
Thanks!.
^ permalink raw reply
* Re: [PATCH v2 9/9] netfilter: Replace smp_read_barrier_depends() with lockless_dereference()
From: Eric Dumazet @ 2014-11-22 0:05 UTC (permalink / raw)
To: Pranith Kumar
Cc: Pablo Neira Ayuso, Patrick McHardy, Jozsef Kadlecsik,
David S. Miller, Alexey Kuznetsov, James Morris,
Hideaki YOSHIFUJI, netfilter-devel, coreteam,
open list:NETWORKING [IPv4/..., open list
In-Reply-To: <CAJhHMCCCSU7PbWdgPouefbLJBcoxR8nmsS8dg_=BcuqVJZbDew@mail.gmail.com>
On Fri, 2014-11-21 at 16:57 -0500, Pranith Kumar wrote:
> Hi Eric,
>
> Thanks for looking at this patch.
>
> I've been scratching my head since morning trying to find out what was
> so obviously wrong with this patch. Alas, I don't see what you do.
>
> Could you point it out and show me how incompetent I am, please?
>
> Thanks!
Well, even it the code is _not_ broken, I don't see any value with this
patch.
If I use git blame on current code, line containing
smp_read_barrier_depends() exactly points to the relevant commit [1]
After your change, it will point to some cleanup, which makes little
sense to me, considering you did not change the smp_wmb() in
xt_replace_table().
I, as a netfilter contributor would like to keep current code as is,
because it is how I feel safe with it.
We have a proliferation of interfaces, but this does not help to
understand the issues and code maintenance.
smp_read_barrier_depends() better documents the read barrier than
lockless_dereference().
The point of having a lock or not is irrelevant here.
[1]
http://git.kernel.org/cgit/linux/kernel/git/davem/net.git/commit/?id=b416c144f46af1a30ddfa4e4319a8f077381ad63
^ permalink raw reply
* Re: [patch net-next v4 0/9] sched: introduce vlan action
From: Jiri Pirko @ 2014-11-21 23:52 UTC (permalink / raw)
To: David Miller
Cc: netdev, jhs, pshelar, therbert, edumazet, willemb, dborkman, mst,
fw, Paul.Durrant, tgraf, cwang
In-Reply-To: <20141121.142107.1704149841896863666.davem@davemloft.net>
Fri, Nov 21, 2014 at 08:21:07PM CET, davem@davemloft.net wrote:
>From: Jiri Pirko <jiri@resnulli.us>
>Date: Wed, 19 Nov 2014 14:04:54 +0100
>
>> Please see the individual patches for info
>
>Series applied, thanks Jiri.
>
>Please work with others to resolve the MPLS header length subtraction
>issue Pravin mentioned.
Sure thing.
>
>Thanks.
^ permalink raw reply
* Re: [RFC PATCH 4/4] bridge: make hw offload conditional on bridge and bridge port offload flags
From: Thomas Graf @ 2014-11-21 23:30 UTC (permalink / raw)
To: roopa
Cc: jiri, sfeldma, jhs, bcrl, john.fastabend, stephen, linville,
nhorman, nicolas.dichtel, vyasevic, f.fainelli, buytenh, aviadr,
netdev, davem, shrijeet, gospo
In-Reply-To: <1416610170-21224-5-git-send-email-roopa@cumulusnetworks.com>
On 11/21/14 at 02:49pm, roopa@cumulusnetworks.com wrote:
> + nla_put_u8(skb, IFLA_BRPORT_GUARD,
> + br_get_port_flag(p, IFLA_BRPORT_GUARD, BR_BPDU_GUARD)) ||
A helper taking nla_put_br_flag(port, skb, attrtype, brflag) would simplify
this code a lot.
> @@ -305,7 +312,9 @@ static int br_set_port_state(struct net_bridge_port *p, u8 state)
>
> br_set_state(p, state);
> br_log_state(p);
> - netdev_sw_port_stp_update(p->dev, p->state);
> +
> + if (BR_HW_OFFLOAD(p->br))
> + netdev_sw_port_set_attr(p->dev, IFLA_BRPORT_STATE, &p->state);
I assume the yet unfinished netdev_sw_port_set_attr() will call
netdev_sw_port_stp_update()?
> @@ -316,13 +325,34 @@ static void br_set_port_flag(struct net_bridge_port *p, struct nlattr *tb[],
> {
> if (tb[attrtype]) {
> u8 flag = nla_get_u8(tb[attrtype]);
> - if (flag)
> - p->flags |= mask;
> - else
> + if (flag) {
> + flag_upper = flag & 0xf0
> + if (!flag_upper || (flag_upper & BRPORT_KERNEL))
> + p->flags |= mask;
> + if ((flag_upper & BRPORT_HW_OFFLOAD) ||
> + (BR_HW_OFFLOAD(p->br)))
> + /* Also set the port flag in hw */
> + netdev_sw_port_set_attr(p->dev, attrtype, 1);
I'm not sure I understand the || here. HW_OFFLOAD enabled on the
net_device is a conditional for all netdev_sw_port_set_attr() calls
and at the same time implies BRPORT_HW_OFFLOAD on all attributes.
As I read this code now, I don't see how you would offload individual
features to hardware.
> diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
> index 8f3f081..3ebd196 100644
> --- a/net/bridge/br_private.h
> +++ b/net/bridge/br_private.h
> @@ -41,6 +41,8 @@
> /* Path to usermode spanning tree program */
> #define BR_STP_PROG "/sbin/bridge-stp"
>
> +#define BR_HW_OFFLOAD(br) !!(br->dev->features & NETIF_F_HW_OFFLOAD)
Let's not add more non type safe macros. A static inline seems like
a better fit here.
^ permalink raw reply
* Re: [RFC PATCH 1/4] rtnetlink: new flag NLM_F_HW_OFFLOAD to indicate kernel object offload to hardware
From: Thomas Graf @ 2014-11-21 23:12 UTC (permalink / raw)
To: roopa
Cc: jiri, sfeldma, jhs, bcrl, john.fastabend, stephen, linville,
nhorman, nicolas.dichtel, vyasevic, f.fainelli, buytenh, aviadr,
netdev, davem, shrijeet, gospo
In-Reply-To: <1416610170-21224-2-git-send-email-roopa@cumulusnetworks.com>
On 11/21/14 at 02:49pm, roopa@cumulusnetworks.com wrote:
> diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h
> index 1a85940..f78522d 100644
> --- a/include/uapi/linux/netlink.h
> +++ b/include/uapi/linux/netlink.h
> @@ -54,6 +54,8 @@ struct nlmsghdr {
> #define NLM_F_ACK 4 /* Reply with ack, with zero or error code */
> #define NLM_F_ECHO 8 /* Echo this request */
> #define NLM_F_DUMP_INTR 16 /* Dump was inconsistent due to sequence change */
> ++#define NLM_F_KERNEL 32 /* This msg is only for the kernel */
> +#define NLM_F_HW_OFFLOAD 64 /* offload this msg to hw */
>
> /* Modifiers to GET request */
> #define NLM_F_ROOT 0x100 /* specify tree root */
The NLM_F_ flag space applies to all Netlink messages including non
networking bits and is reserved for flags vital to the functioning
of the Netlink protocol itself. I suggest you move this to a
RTNETLINK specific flags space.
^ permalink raw reply
* [PATCH] xen-netback: do not report success if xenvif_alloc() fails
From: Alexey Khoroshilov @ 2014-11-21 22:56 UTC (permalink / raw)
To: Ian Campbell, Wei Liu
Cc: Alexey Khoroshilov, xen-devel, netdev, linux-kernel, ldv-project
If xenvif_alloc() failes, netback_probe() reports success as well as
"online" uevent is emitted. It does not make any sense, but it just
misleads users.
The patch implements propagation of error code if xenvif creation fails.
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
---
drivers/net/xen-netback/xenbus.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
index 4e56a27f9689..fab0d4b42f58 100644
--- a/drivers/net/xen-netback/xenbus.c
+++ b/drivers/net/xen-netback/xenbus.c
@@ -39,7 +39,7 @@ struct backend_info {
static int connect_rings(struct backend_info *be, struct xenvif_queue *queue);
static void connect(struct backend_info *be);
static int read_xenbus_vif_flags(struct backend_info *be);
-static void backend_create_xenvif(struct backend_info *be);
+static int backend_create_xenvif(struct backend_info *be);
static void unregister_hotplug_status_watch(struct backend_info *be);
static void set_backend_state(struct backend_info *be,
enum xenbus_state state);
@@ -352,7 +352,9 @@ static int netback_probe(struct xenbus_device *dev,
be->state = XenbusStateInitWait;
/* This kicks hotplug scripts, so do it immediately. */
- backend_create_xenvif(be);
+ err = backend_create_xenvif(be);
+ if (err)
+ goto fail;
return 0;
@@ -397,19 +399,19 @@ static int netback_uevent(struct xenbus_device *xdev,
}
-static void backend_create_xenvif(struct backend_info *be)
+static int backend_create_xenvif(struct backend_info *be)
{
int err;
long handle;
struct xenbus_device *dev = be->dev;
if (be->vif != NULL)
- return;
+ return 0;
err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%li", &handle);
if (err != 1) {
xenbus_dev_fatal(dev, err, "reading handle");
- return;
+ return (err < 0) ? err : -EINVAL;
}
be->vif = xenvif_alloc(&dev->dev, dev->otherend_id, handle);
@@ -417,10 +419,11 @@ static void backend_create_xenvif(struct backend_info *be)
err = PTR_ERR(be->vif);
be->vif = NULL;
xenbus_dev_fatal(dev, err, "creating interface");
- return;
+ return err;
}
kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE);
+ return 0;
}
static void backend_disconnect(struct backend_info *be)
--
1.9.1
^ permalink raw reply related
* [RFC PATCH 4/4] bridge: make hw offload conditional on bridge and bridge port offload flags
From: roopa @ 2014-11-21 22:49 UTC (permalink / raw)
To: jiri, sfeldma, jhs, bcrl, tgraf, john.fastabend, stephen,
linville, nhorman, nicolas.dichtel, vyasevic, f.fainelli, buytenh,
aviadr
Cc: netdev, davem, shrijeet, gospo, Roopa Prabhu
From: Roopa Prabhu <roopa@cumulusnetworks.com>
If bridge has NETIF_F_HW_OFFLOAD feature flag set, offload all bridge and
bridge port attributes to hardware.
Two new flags BRPORT_KERNEL and BRPORT_HW_OFFLOAD to control offloading of
a few bridge port flags to hardware. These can be encoded in the upper bits
of all bridge port flag netlink attributes.
Control/Override bridge port flag (learning, flooding etc) offloading
with BRPORT_KERNEL and BRPORT_HW_OFFLOAD flags:
If the brport offload flags are not present (current default)
- set bridge port flag attribute only in the kernel
else:
if BRPORT_KERNEL and BRPORT_HW_OFFLOAD:
- set bridge port flag both in kernel and hw
elif BRPORT_KERNEL:
- set bridge port flag attribute only in kernel
elif BRPORT_HW_OFFLOAD:
- set bridge port flag attribute only in hw
The 'gets' needs more work. The idea is that the gets can also be controlled
by the KERNEL or HW_OFFLOAD flags.
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
---
net/bridge/br_netlink.c | 50 +++++++++++++++++++++++++++++++++++++----------
net/bridge/br_private.h | 2 ++
net/bridge/br_stp.c | 9 ++++++---
net/bridge/br_stp_if.c | 8 ++++++--
4 files changed, 54 insertions(+), 15 deletions(-)
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 13fecf1..e92e810 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -57,12 +57,19 @@ static int br_port_fill_attrs(struct sk_buff *skb,
nla_put_u16(skb, IFLA_BRPORT_PRIORITY, p->priority) ||
nla_put_u32(skb, IFLA_BRPORT_COST, p->path_cost) ||
nla_put_u8(skb, IFLA_BRPORT_MODE, mode) ||
- nla_put_u8(skb, IFLA_BRPORT_GUARD, !!(p->flags & BR_BPDU_GUARD)) ||
- nla_put_u8(skb, IFLA_BRPORT_PROTECT, !!(p->flags & BR_ROOT_BLOCK)) ||
- nla_put_u8(skb, IFLA_BRPORT_FAST_LEAVE, !!(p->flags & BR_MULTICAST_FAST_LEAVE)) ||
- nla_put_u8(skb, IFLA_BRPORT_LEARNING, !!(p->flags & BR_LEARNING)) ||
- nla_put_u8(skb, IFLA_BRPORT_UNICAST_FLOOD, !!(p->flags & BR_FLOOD)) ||
- nla_put_u8(skb, IFLA_BRPORT_PROXYARP, !!(p->flags & BR_PROXYARP)))
+ nla_put_u8(skb, IFLA_BRPORT_GUARD,
+ br_get_port_flag(p, IFLA_BRPORT_GUARD, BR_BPDU_GUARD)) ||
+ nla_put_u8(skb, IFLA_BRPORT_PROTECT,
+ br_get_port_flag(p, IFLA_BRPORT_PROTECT, BR_ROOT_BLOCK)) ||
+ nla_put_u8(skb, IFLA_BRPORT_FAST_LEAVE,
+ br_get_port_flag(p, IFLA_BRPORT_FAST_LEAVE,
+ BR_MULTICAST_FAST_LEAVE)) ||
+ nla_put_u8(skb, IFLA_BRPORT_LEARNING,
+ br_get_port_flag(p, IFLA_BRPORT_LEARNING, BR_LEARNING)) ||
+ nla_put_u8(skb, IFLA_BRPORT_UNICAST_FLOOD,
+ br_get_port_flag(p, IFLA_UNICAST_FLOOD, BR_FLOOD)) ||
+ nla_put_u8(skb, IFLA_BRPORT_PROXYARP,
+ br_get_port_flag(p, IFLA_UNICAST_FLOOD, BR_PROXYARP)))
return -EMSGSIZE;
return 0;
@@ -305,7 +312,9 @@ static int br_set_port_state(struct net_bridge_port *p, u8 state)
br_set_state(p, state);
br_log_state(p);
- netdev_sw_port_stp_update(p->dev, p->state);
+
+ if (BR_HW_OFFLOAD(p->br))
+ netdev_sw_port_set_attr(p->dev, IFLA_BRPORT_STATE, &p->state);
br_port_state_selection(p->br);
return 0;
}
@@ -316,13 +325,34 @@ static void br_set_port_flag(struct net_bridge_port *p, struct nlattr *tb[],
{
if (tb[attrtype]) {
u8 flag = nla_get_u8(tb[attrtype]);
- if (flag)
- p->flags |= mask;
- else
+ if (flag) {
+ flag_upper = flag & 0xf0
+ if (!flag_upper || (flag_upper & BRPORT_KERNEL))
+ p->flags |= mask;
+ if ((flag_upper & BRPORT_HW_OFFLOAD) ||
+ (BR_HW_OFFLOAD(p->br)))
+ /* Also set the port flag in hw */
+ netdev_sw_port_set_attr(p->dev, attrtype, 1);
+ } else {
p->flags &= ~mask;
+ if (BR_HW_OFFLOAD(p->br))
+ netdev_sw_port_set_attr(p->dev, attrtype, 0);
+ }
}
}
+/* Set/clear or port flags based on attribute */
+static u8 br_get_port_flag(struct net_bridge_port *p,
+ int attrtype, u8 flag)
+{
+ attrvalue = !!(p->flags & flag)
+ if (attrvalue)
+ attrvalue |= BRPORT_KERNEL
+ if (netdev_sw_port_get_flag(p->dev, attrtype))
+ attrvalue |= BRPORT_HW_OFFLOAD
+ return attrvalue;
+}
+
/* Process bridge protocol info on port */
static int br_setport(struct net_bridge_port *p, struct nlattr *tb[])
{
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 8f3f081..3ebd196 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -41,6 +41,8 @@
/* Path to usermode spanning tree program */
#define BR_STP_PROG "/sbin/bridge-stp"
+#define BR_HW_OFFLOAD(br) !!(br->dev->features & NETIF_F_HW_OFFLOAD)
+
typedef struct bridge_id bridge_id;
typedef struct mac_addr mac_addr;
typedef __u16 port_id;
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
index c00139b..bb61dc0 100644
--- a/net/bridge/br_stp.c
+++ b/net/bridge/br_stp.c
@@ -115,7 +115,8 @@ static void br_root_port_block(const struct net_bridge *br,
br_set_state(p, BR_STATE_LISTENING);
br_log_state(p);
- netdev_sw_port_stp_update(p->dev, p->state);
+ if (BR_HW_OFFLOAD(p->br))
+ netdev_sw_port_set_attr(p->dev, IFLA_BRPORT_STATE, &p->state);
br_ifinfo_notify(RTM_NEWLINK, p);
if (br->forward_delay > 0)
@@ -396,7 +397,8 @@ static void br_make_blocking(struct net_bridge_port *p)
br_set_state(p, BR_STATE_BLOCKING);
br_log_state(p);
- netdev_sw_port_stp_update(p->dev, p->state);
+ if (BR__HW_OFFLOAD(p->br))
+ netdev_sw_port_set_attr(p->dev, IFLA_BRPORT_STATE, &p->state);
br_ifinfo_notify(RTM_NEWLINK, p);
del_timer(&p->forward_delay_timer);
@@ -422,7 +424,8 @@ static void br_make_forwarding(struct net_bridge_port *p)
br_multicast_enable_port(p);
br_log_state(p);
- netdev_sw_port_stp_update(p->dev, p->state);
+ if (BR_OFFLOAD(p->br))
+ netdev_sw_port_set_attr(p->dev, IFLA_BRPORT_STATE, &p->state);
br_ifinfo_notify(RTM_NEWLINK, p);
if (br->forward_delay != 0)
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index 91279f8..8435b4d 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -90,7 +90,8 @@ void br_stp_enable_port(struct net_bridge_port *p)
br_init_port(p);
br_port_state_selection(p->br);
br_log_state(p);
- netdev_sw_port_stp_update(p->dev, p->state);
+ if (BR_HW_OFFLOAD(p->br))
+ netdev_sw_port_set_attr(p->dev, IFLA_BRPORT_STATE, &p->state);
br_ifinfo_notify(RTM_NEWLINK, p);
}
@@ -107,7 +108,8 @@ void br_stp_disable_port(struct net_bridge_port *p)
p->config_pending = 0;
br_log_state(p);
- netdev_sw_port_stp_update(p->dev, p->state);
+ if (BR_HW_OFFLOAD(p->br))
+ netdev_sw_port_set_attr(p->dev, IFLA_BRPORT_STATE, &p->state);
br_ifinfo_notify(RTM_NEWLINK, p);
del_timer(&p->message_age_timer);
@@ -290,6 +292,8 @@ int br_stp_set_port_priority(struct net_bridge_port *p, unsigned long newprio)
br_become_designated_port(p);
br_port_state_selection(p->br);
}
+ if (BR_HW_OFFLOAD(p->br))
+ netdev_sw_port_set_attr(p->dev, IFLA_BRPORT_PRIORITY, &newprio)
return 0;
}
--
1.7.10.4
^ permalink raw reply related
* [RFC PATCH 3/4] swdevice: new generic op to set bridge port attr
From: roopa @ 2014-11-21 22:49 UTC (permalink / raw)
To: jiri, sfeldma, jhs, bcrl, tgraf, john.fastabend, stephen,
linville, nhorman, nicolas.dichtel, vyasevic, f.fainelli, buytenh,
aviadr
Cc: netdev, davem, shrijeet, gospo, Roopa Prabhu
From: Roopa Prabhu <roopa@cumulusnetworks.com>
A generic switch device op to offload any type of bridge port attribute.
(This is still TBD)
---
include/net/switchdev.h | 8 +++++++-
net/switchdev/switchdev.c | 17 +++++++++++++++++
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index a9ccfa4..c97994d 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -145,7 +145,8 @@ int netdev_sw_parent_flow_insert(struct net_device *dev,
const struct swdev_flow *flow);
int netdev_sw_parent_flow_remove(struct net_device *dev,
const struct swdev_flow *flow);
-
+int netdev_sw_port_set_attr(struct net_device *dev, int attrtype,
+ void *attrval);
#else
static inline int netdev_sw_parent_id_get(struct net_device *dev,
@@ -202,6 +203,11 @@ static inline int netdev_sw_parent_flow_remove(struct net_device *dev,
return -EOPNOTSUPP;
}
+static int netdev_sw_port_set_attr(struct net_device *dev, int attrtype,
+ void *attrval)
+{
+ return -EOPNOTSUPP;
+}
#endif
#endif /* _LINUX_SWITCHDEV_H_ */
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index dc8e769..48f451b 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -314,3 +314,20 @@ int netdev_sw_parent_flow_remove(struct net_device *dev,
return ops->ndo_sw_parent_flow_remove(dev, flow);
}
EXPORT_SYMBOL(netdev_sw_parent_flow_remove);
+
+/**
+ * netdev_sw_port_set_attr - set a port attr
+ * @dev: port device
+ * @attrttype: netlink attribute
+ * @attrval: attribute value
+ *
+ * Set switch port attribute
+ */
+int netdev_sw_port_set_attr(struct net_device *dev,
+ int attrttype, void *attrval)
+{
+ /* XXX: yet to be implemented */
+
+ return 0;
+}
+EXPORT_SYMBOL(netdev_sw_port_set_attr);
--
1.7.10.4
^ permalink raw reply related
* [RFC PATCH 2/4] netdev: new feature flag NETIF_F_HW_OFFLOAD to indicate netdev object offload to hardware
From: roopa @ 2014-11-21 22:49 UTC (permalink / raw)
To: jiri, sfeldma, jhs, bcrl, tgraf, john.fastabend, stephen,
linville, nhorman, nicolas.dichtel, vyasevic, f.fainelli, buytenh,
aviadr
Cc: netdev, davem, shrijeet, gospo, Roopa Prabhu
From: Roopa Prabhu <roopa@cumulusnetworks.com>
This patch adds a new NETIF_F_HW_OFFLOAD feature flag to offload logical
interfaces to hw.
Useful in cases of bridges, bonds etc where you want to offload the
logical interface attributes to hw.
---
include/linux/netdev_features.h | 1 +
net/core/rtnetlink.c | 7 +++++++
2 files changed, 8 insertions(+)
diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index 8e30685..09da213 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -66,6 +66,7 @@ enum {
NETIF_F_HW_VLAN_STAG_FILTER_BIT,/* Receive filtering on VLAN STAGs */
NETIF_F_HW_L2FW_DOFFLOAD_BIT, /* Allow L2 Forwarding in Hardware */
NETIF_F_BUSY_POLL_BIT, /* Busy poll */
+ NETIF_F_HW_OFFLOAD, /* generic hw offload */
/*
* Add your fresh new feature above and remember to update
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index f839354..97b8f48 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2106,6 +2106,13 @@ replay:
goto out;
}
+ /*
+ * If the newlink request came in with a HW_OFFLOAD
+ * flag, then set hw offload feature flag
+ */
+ if (nlh->nlmsg_flags & NLM_F_HW_OFFLOAD)
+ dev->features |= NETIF_F_HW_OFFLOAD;
+
dev->ifindex = ifm->ifi_index;
if (ops->newlink) {
--
1.7.10.4
^ permalink raw reply related
* [RFC PATCH 1/4] rtnetlink: new flag NLM_F_HW_OFFLOAD to indicate kernel object offload to hardware
From: roopa @ 2014-11-21 22:49 UTC (permalink / raw)
To: jiri, sfeldma, jhs, bcrl, tgraf, john.fastabend, stephen,
linville, nhorman, nicolas.dichtel, vyasevic, f.fainelli, buytenh,
aviadr
Cc: netdev, davem, shrijeet, gospo, Roopa Prabhu
From: Roopa Prabhu <roopa@cumulusnetworks.com>
This patch adds new flags in netlink header nlmsg_flags to signal if the
message is for the kernel, hw or both.
This can be used to indicate hw offload for all kind of objects
routes, fdb entries, neighs, link objects like bonds, bridges, vxlan.
Adding it in the header makes it possible to use it accross all objects and
across all messages (sets/gets/deletes).
Other alternative to this is a per kernel object netlink attribute/flag.
But that leads to duplicating the attribute in different subsystems.
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
---
include/uapi/linux/netlink.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h
index 1a85940..f78522d 100644
--- a/include/uapi/linux/netlink.h
+++ b/include/uapi/linux/netlink.h
@@ -54,6 +54,8 @@ struct nlmsghdr {
#define NLM_F_ACK 4 /* Reply with ack, with zero or error code */
#define NLM_F_ECHO 8 /* Echo this request */
#define NLM_F_DUMP_INTR 16 /* Dump was inconsistent due to sequence change */
++#define NLM_F_KERNEL 32 /* This msg is only for the kernel */
+#define NLM_F_HW_OFFLOAD 64 /* offload this msg to hw */
/* Modifiers to GET request */
#define NLM_F_ROOT 0x100 /* specify tree root */
--
1.7.10.4
^ permalink raw reply related
* [RFC PATCH 0/4] switch device: offload policy attributes
From: roopa @ 2014-11-21 22:49 UTC (permalink / raw)
To: jiri, sfeldma, jhs, bcrl, tgraf, john.fastabend, stephen,
linville, nhorman, nicolas.dichtel, vyasevic, f.fainelli, buytenh,
aviadr
Cc: netdev, davem, shrijeet, gospo, Roopa Prabhu
From: Roopa Prabhu <roopa@cumulusnetworks.com>
This series aims at introducing new policy attibutes/flags to enable
selective offloading of kernel network objects.
This is in the context of supporting switch devices in the linux kernel.
Assumption:
- All kernel network objects (routes, neighs, bridges, bonds, vxlans)
can be offloaded (This is true today with a few exceptions maybe)
policy points:
- By default all objects exist in software (kernel)
- Per object flag to add/del/show in kernel, hardware or both
- System global option to turn on/off offloads for all network objects.
This is for systems who want to turn offloading on for all network objects
by default. us :). Apps dont need to know about offloading in this
model. (TBD)
Patches are based on jiri/sfeldma's rocker work.
Apologize for the incomplete and untested code. This is a sample patch
to get some initial feedback.
Roopa Prabhu (4):
rtnetlink: new flag NLM_F_HW_OFFLOAD to indicate kernel object
offload to hardware
netdev: new feature flag NETIF_F_HW_OFFLOAD to indicate netdev object
offload to hardware
swdevice: new generic op to set bridge port attr
bridge: make hw offload conditional on bridge and bridge port offload
flags
include/linux/netdev_features.h | 1 +
include/net/switchdev.h | 8 ++++++-
include/uapi/linux/netlink.h | 2 ++
net/bridge/br_netlink.c | 50 +++++++++++++++++++++++++++++++--------
net/bridge/br_private.h | 2 ++
net/bridge/br_stp.c | 9 ++++---
net/bridge/br_stp_if.c | 8 +++++--
net/core/rtnetlink.c | 7 ++++++
net/switchdev/switchdev.c | 17 +++++++++++++
9 files changed, 88 insertions(+), 16 deletions(-)
--
1.7.10.4
^ permalink raw reply
* [GIT] Networking
From: David Miller @ 2014-11-21 22:37 UTC (permalink / raw)
To: torvalds; +Cc: akpm, netdev, linux-kernel
1) Fix BUG when decrypting empty packets in mac80211, from Ronald Wahl.
2) nf_nat_range is not fully initialized and this is copied back to
userspace, from Daniel Borkmann.
3) Fix read past end of b uffer in netfilter ipset, also from Dan
Carpenter.
4) Signed integer overflow in ipv4 address mask creation helper
inet_make_mask(), from Vincent BENAYOUN.
5) VXLAN, be2net, mlx4_en, and qlcnic need ->ndo_gso_check() methods
to properly describe the device's capabilities, from Joe
Stringer.
6) Fix memory leaks and checksum miscalculations in openvswitch, from
Pravin B SHelar and Jesse Gross.
7) FIB rules passes back ambiguous error code for unreachable routes,
making behavior confusing for userspace. Fix from Panu Matilainen.
8) ieee802154fake_probe() doesn't release resources properly on error,
from Alexey Khoroshilov.
9) Fix skb_over_panic in add_grhead(), from Daniel Borkmann.
10) Fix access of stale slave pointers in bonding code, from Nikolay
Aleksandrov.
11) Fix stack info leak in PPP pptp code, from Mathias Krause.
12) Cure locking bug in IPX stack, from Jiri Bohac.
13) Revert SKB fclone memory freeing optimization that is racey and can
allow accesses to freed up memory, from Eric Dumazet.
Please pull, thanks a lot!
The following changes since commit b23dc5a7cc6ebc9a0d57351da7a0e8454c9ffea3:
Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost (2014-11-13 18:07:52 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git master
for you to fetch changes up to 0c228e833c88e3aa029250f5db77d5968c5ce5b5:
tcp: Restore RFC5961-compliant behavior for SYN packets (2014-11-21 15:33:50 -0500)
----------------------------------------------------------------
Alexey Khoroshilov (2):
ieee802154: fix error handling in ieee802154fake_probe()
can: esd_usb2: fix memory leak on disconnect
Anish Bhatt (3):
dcbnl : Disable software interrupts before taking dcb_lock
cxgb4i : Don't block unload/cxgb4 unload when remote closes TCP connection
cxgb4 : Fix DCB priority groups being returned in wrong order
Arend van Spriel (1):
brcmfmac: fix conversion of channel width 20MHZ_NOHT
Ben Greear (1):
ath9k: fix regression in bssidmask calculation
Calvin Owens (2):
ipvs: Keep skb->sk when allocating headroom on tunnel xmit
tcp: Restore RFC5961-compliant behavior for SYN packets
Dan Carpenter (1):
netfilter: ipset: small potential read beyond the end of buffer
Daniel Borkmann (2):
netfilter: nft_masq: fix uninitialized range in nft_masq_{ipv4, ipv6}_eval
ipv6: mld: fix add_grhead skb_over_panic for devs with large MTUs
Daniele Di Proietto (1):
openvswitch: Fix NDP flow mask validation
David Cohen (1):
can: m_can: add CONFIG_HAS_IOMEM dependence
David S. Miller (7):
Merge tag 'master-2014-11-11' of git://git.kernel.org/.../linville/wireless
Merge branch 'vxlan_gso_check'
Merge git://git.kernel.org/.../pablo/nf
Merge branch 'net_ovs' of git://git.kernel.org/.../pshelar/openvswitch
Merge tag 'linux-can-fixes-for-3.18-20141118' of git://gitorious.org/linux-can/linux-can
Merge tag 'master-2014-11-20' of git://git.kernel.org/.../linville/wireless
Merge git://git.kernel.org/.../pablo/nf
Dmitry Torokhov (1):
brcmfmac: fix error handling of irq_of_parse_and_map
Dong Aisheng (8):
can: dev: add can_is_canfd_skb() API
can: m_can: add .ndo_change_mtu function
can: m_can: add missing message RAM initialization
can: m_can: fix possible sleep in napi poll
can: m_can: fix not set can_dlc for remote frame
can: m_can: add missing delay after setting CCCR_INIT bit
can: m_can: fix incorrect error messages
can: m_can: update to support CAN FD features
Duan Jiong (1):
ipv6: delete protocol and unregister rtnetlink when cleanup
Emmanuel Grumbach (1):
iwlwifi: mvm: abort scan upon RFKILL
Eric Dumazet (1):
net: Revert "net: avoid one atomic operation in skb_clone()"
Felix Fietkau (1):
mac80211: minstrel_ht: fix a crash in rate sorting
Hannes Frederic Sowa (1):
reciprocal_div: objects with exported symbols should be obj-y rather than lib-y
Hauke Mehrtens (1):
b43: fix NULL pointer dereference in b43_phy_copy()
Jarno Rajahalme (1):
openvswitch: Validate IPv6 flow key and mask values.
Jason Wang (1):
virtio-net: validate features during probe
Jesse Gross (1):
openvswitch: Fix checksum calculation when modifying ICMPv6 packets.
Jiri Bohac (1):
ipx: fix locking regression in ipx_sendmsg and ipx_recvmsg
Joe Stringer (6):
net: Add vxlan_gso_check() helper
be2net: Implement ndo_gso_check()
net/mlx4_en: Implement ndo_gso_check()
qlcnic: Implement ndo_gso_check()
vxlan: Inline vxlan_gso_check().
openvswitch: Don't validate IPv6 label masks.
Johannes Berg (1):
brcmfmac: don't include linux/unaligned/access_ok.h
John Ogness (1):
drivers: net: cpsw: Fix TX_IN_SEL offset
John W. Linville (3):
Merge tag 'mac80211-for-john-2014-11-10' of git://git.kernel.org/.../jberg/mac80211
Merge tag 'iwlwifi-for-john-2014-11-10' of git://git.kernel.org/.../iwlwifi/iwlwifi-fixes
Merge tag 'mac80211-for-john-2014-11-18' of git://git.kernel.org/.../jberg/mac80211
Larry Finger (3):
rtlwifi: Fix setting of tx descriptor for new trx flow
rtlwifi: Fix errors in descriptor manipulation
rtlwifi: rtl8192se: Fix connection problems
Liad Kaufman (1):
iwlwifi: pcie: fix prph dump length
Linus Lüssing (1):
bridge: fix netfilter/NF_BR_LOCAL_OUT for own, locally generated queries
Marc Kleine-Budde (3):
can: xilinx_can: add .ndo_change_mtu function
can: rcar_can: add .ndo_change_mtu function
can: gs_usb: add .ndo_change_mtu function
Martin Hauke (1):
qmi_wwan: Add support for HP lt4112 LTE/HSPA+ Gobi 4G Modem
Mathias Krause (1):
pptp: fix stack info leak in pptp_getname()
Mathy Vanhoef (1):
brcmfmac: kill URB when request timed out
Miaoqing Pan (1):
ath9k: Fix RTC_DERIVED_CLK usage
Nikolay Aleksandrov (1):
bonding: fix curr_active_slave/carrier with loadbalance arp monitoring
Or Gerlitz (1):
net/mlx4_en: Add VXLAN ndo calls to the PF net device ops too
Pablo Neira Ayuso (5):
netfilter: nft_compat: use current net namespace
netfilter: nft_compat: relax chain type validation
netfilter: nft_compat: use the match->table to validate dependencies
netfilter: nf_tables: restore synchronous object release from commit/abort
netfilter: nfnetlink: fix insufficient validation in nfnetlink_bind
Panu Matilainen (1):
ipv4: Fix incorrect error code when adding an unreachable route
Pravin B Shelar (2):
openvswitch: Fix memory leak.
openvswitch: Convert dp rcu read operation to locked operations
Roman Fietze (1):
can: dev: fix typo CIA -> CiA, CAN in Automation
Ronald Wahl (1):
mac80211: Fix regression that triggers a kernel BUG with CCMP
Stanislaw Gruszka (1):
rt2x00: do not align payload on modern H/W
Sudip Mukherjee (2):
can: remove unused variable
can: xilinx_can: fix comparison of unsigned variable
Thomas Körper (1):
can: dev: avoid calling kfree_skb() from interrupt context
Vincent BENAYOUN (1):
inetdevice: fixed signed integer overflow
bill bonaparte (1):
netfilter: conntrack: fix race in __nf_conntrack_confirm against get_next_corpse
drivers/net/bonding/bond_main.c | 3 +-
drivers/net/can/dev.c | 4 +-
drivers/net/can/m_can/Kconfig | 1 +
drivers/net/can/m_can/m_can.c | 219 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
drivers/net/can/rcar_can.c | 1 +
drivers/net/can/sja1000/kvaser_pci.c | 5 +-
drivers/net/can/usb/ems_usb.c | 3 +-
drivers/net/can/usb/esd_usb2.c | 3 +-
drivers/net/can/usb/gs_usb.c | 1 +
drivers/net/can/xilinx_can.c | 4 +-
drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c | 2 +-
drivers/net/ethernet/emulex/benet/be_main.c | 6 ++
drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 13 ++++-
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 6 ++
drivers/net/ethernet/ti/cpsw.c | 6 +-
drivers/net/ieee802154/fakehard.c | 13 +++--
drivers/net/ppp/pptp.c | 4 +-
drivers/net/usb/qmi_wwan.c | 1 +
drivers/net/virtio_net.c | 37 ++++++++++++
drivers/net/vxlan.c | 6 --
drivers/net/wireless/ath/ath9k/ar9003_phy.c | 13 +++++
drivers/net/wireless/ath/ath9k/hw.c | 13 -----
drivers/net/wireless/ath/ath9k/main.c | 9 ++-
drivers/net/wireless/b43/phy_common.c | 4 +-
drivers/net/wireless/brcm80211/brcmfmac/of.c | 4 +-
drivers/net/wireless/brcm80211/brcmfmac/pcie.c | 2 +-
drivers/net/wireless/brcm80211/brcmfmac/usb.c | 6 +-
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 6 ++
drivers/net/wireless/iwlwifi/mvm/scan.c | 20 +++----
drivers/net/wireless/iwlwifi/pcie/trans.c | 3 +-
drivers/net/wireless/rt2x00/rt2x00queue.c | 50 ++++-------------
drivers/net/wireless/rtlwifi/pci.c | 19 ++++---
drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 7 ++-
drivers/net/wireless/rtlwifi/rtl8192se/phy.c | 2 +
drivers/net/wireless/rtlwifi/rtl8192se/sw.c | 16 ++++++
drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 2 +
drivers/scsi/cxgbi/libcxgbi.c | 2 +-
include/linux/can/dev.h | 6 ++
include/linux/inetdevice.h | 2 +-
include/net/netfilter/nf_tables.h | 2 -
include/net/vxlan.h | 18 ++++++
lib/Makefile | 4 +-
net/bridge/br_multicast.c | 3 +-
net/core/skbuff.c | 23 ++------
net/dcb/dcbnl.c | 36 ++++++------
net/ipv4/fib_rules.c | 4 ++
net/ipv4/igmp.c | 11 ++--
net/ipv4/netfilter/nft_masq_ipv4.c | 1 +
net/ipv4/tcp_input.c | 4 +-
net/ipv6/ip6mr.c | 4 ++
net/ipv6/mcast.c | 9 +--
net/ipv6/netfilter/nft_masq_ipv6.c | 1 +
net/ipx/af_ipx.c | 6 +-
net/mac80211/aes_ccm.c | 3 +
net/mac80211/rc80211_minstrel_ht.c | 15 ++---
net/netfilter/ipset/ip_set_core.c | 6 ++
net/netfilter/ipvs/ip_vs_xmit.c | 2 +
net/netfilter/nf_conntrack_core.c | 14 +++--
net/netfilter/nf_tables_api.c | 24 +++-----
net/netfilter/nfnetlink.c | 12 +++-
net/netfilter/nft_compat.c | 40 ++-----------
net/openvswitch/actions.c | 10 ++--
net/openvswitch/datapath.c | 14 ++---
net/openvswitch/flow_netlink.c | 9 ++-
64 files changed, 500 insertions(+), 299 deletions(-)
^ 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