Commit dc5367bc authored by Julian Wiedmann's avatar Julian Wiedmann Committed by David S. Miller

net/af_iucv: don't use paged skbs for TX on HiperSockets

With commit e5374399
("af_iucv: use paged SKBs for big outbound messages"),
we transmit paged skbs for both of AF_IUCV's transport modes
(IUCV or HiperSockets).
The qeth driver for Layer 3 HiperSockets currently doesn't
support NETIF_F_SG, so these skbs would just be linearized again
by the stack.
Avoid that overhead by using paged skbs only for IUCV transport.

cc stable, since this also circumvents a significant skb leak when
sending large messages (where the skb then needs to be linearized).
Signed-off-by: default avatarJulian Wiedmann <jwi@linux.vnet.ibm.com>
Signed-off-by: default avatarUrsula Braun <ubraun@linux.vnet.ibm.com>
Cc: <stable@vger.kernel.org> # v4.8+
Fixes: e5374399 ("af_iucv: use paged SKBs for big outbound messages")
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5d722b30
...@@ -1044,7 +1044,8 @@ static int iucv_sock_sendmsg(struct socket *sock, struct msghdr *msg, ...@@ -1044,7 +1044,8 @@ static int iucv_sock_sendmsg(struct socket *sock, struct msghdr *msg,
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct iucv_sock *iucv = iucv_sk(sk); struct iucv_sock *iucv = iucv_sk(sk);
size_t headroom, linear; size_t headroom = 0;
size_t linear;
struct sk_buff *skb; struct sk_buff *skb;
struct iucv_message txmsg = {0}; struct iucv_message txmsg = {0};
struct cmsghdr *cmsg; struct cmsghdr *cmsg;
...@@ -1122,19 +1123,21 @@ static int iucv_sock_sendmsg(struct socket *sock, struct msghdr *msg, ...@@ -1122,19 +1123,21 @@ static int iucv_sock_sendmsg(struct socket *sock, struct msghdr *msg,
* this is fine for SOCK_SEQPACKET (unless we want to support * this is fine for SOCK_SEQPACKET (unless we want to support
* segmented records using the MSG_EOR flag), but * segmented records using the MSG_EOR flag), but
* for SOCK_STREAM we might want to improve it in future */ * for SOCK_STREAM we might want to improve it in future */
headroom = (iucv->transport == AF_IUCV_TRANS_HIPER) if (iucv->transport == AF_IUCV_TRANS_HIPER) {
? sizeof(struct af_iucv_trans_hdr) + ETH_HLEN : 0; headroom = sizeof(struct af_iucv_trans_hdr) + ETH_HLEN;
if (headroom + len < PAGE_SIZE) { linear = len;
} else {
if (len < PAGE_SIZE) {
linear = len; linear = len;
} else { } else {
/* In nonlinear "classic" iucv skb, /* In nonlinear "classic" iucv skb,
* reserve space for iucv_array * reserve space for iucv_array
*/ */
if (iucv->transport != AF_IUCV_TRANS_HIPER) headroom = sizeof(struct iucv_array) *
headroom += sizeof(struct iucv_array) *
(MAX_SKB_FRAGS + 1); (MAX_SKB_FRAGS + 1);
linear = PAGE_SIZE - headroom; linear = PAGE_SIZE - headroom;
} }
}
skb = sock_alloc_send_pskb(sk, headroom + linear, len - linear, skb = sock_alloc_send_pskb(sk, headroom + linear, len - linear,
noblock, &err, 0); noblock, &err, 0);
if (!skb) if (!skb)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment