aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulian Wiedmann <jwi@linux.vnet.ibm.com>2017-01-10 11:10:34 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-01-19 14:18:04 -0500
commit9297e0c189f59f42e5d39aee901d54a4493a60e2 (patch)
tree6b08c3f3717b3cc6ccd2bfc52e387699cd731bb7
parent00cf64fbaa1e99d0420f2934f301c671ba298342 (diff)
net/af_iucv: don't use paged skbs for TX on HiperSockets
commit dc5367bcc556e97555fc94a32cd1aadbebdff47e upstream. With commit e53743994e21 ("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: Julian Wiedmann <jwi@linux.vnet.ibm.com> Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com> Fixes: e53743994e21 ("af_iucv: use paged SKBs for big outbound messages") Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--net/iucv/af_iucv.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index 02b45a8e8b35..91cbbf1c3f82 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -1036,7 +1036,8 @@ static int iucv_sock_sendmsg(struct socket *sock, struct msghdr *msg,
1036{ 1036{
1037 struct sock *sk = sock->sk; 1037 struct sock *sk = sock->sk;
1038 struct iucv_sock *iucv = iucv_sk(sk); 1038 struct iucv_sock *iucv = iucv_sk(sk);
1039 size_t headroom, linear; 1039 size_t headroom = 0;
1040 size_t linear;
1040 struct sk_buff *skb; 1041 struct sk_buff *skb;
1041 struct iucv_message txmsg = {0}; 1042 struct iucv_message txmsg = {0};
1042 struct cmsghdr *cmsg; 1043 struct cmsghdr *cmsg;
@@ -1114,18 +1115,20 @@ static int iucv_sock_sendmsg(struct socket *sock, struct msghdr *msg,
1114 * this is fine for SOCK_SEQPACKET (unless we want to support 1115 * this is fine for SOCK_SEQPACKET (unless we want to support
1115 * segmented records using the MSG_EOR flag), but 1116 * segmented records using the MSG_EOR flag), but
1116 * for SOCK_STREAM we might want to improve it in future */ 1117 * for SOCK_STREAM we might want to improve it in future */
1117 headroom = (iucv->transport == AF_IUCV_TRANS_HIPER) 1118 if (iucv->transport == AF_IUCV_TRANS_HIPER) {
1118 ? sizeof(struct af_iucv_trans_hdr) + ETH_HLEN : 0; 1119 headroom = sizeof(struct af_iucv_trans_hdr) + ETH_HLEN;
1119 if (headroom + len < PAGE_SIZE) {
1120 linear = len; 1120 linear = len;
1121 } else { 1121 } else {
1122 /* In nonlinear "classic" iucv skb, 1122 if (len < PAGE_SIZE) {
1123 * reserve space for iucv_array 1123 linear = len;
1124 */ 1124 } else {
1125 if (iucv->transport != AF_IUCV_TRANS_HIPER) 1125 /* In nonlinear "classic" iucv skb,
1126 headroom += sizeof(struct iucv_array) * 1126 * reserve space for iucv_array
1127 (MAX_SKB_FRAGS + 1); 1127 */
1128 linear = PAGE_SIZE - headroom; 1128 headroom = sizeof(struct iucv_array) *
1129 (MAX_SKB_FRAGS + 1);
1130 linear = PAGE_SIZE - headroom;
1131 }
1129 } 1132 }
1130 skb = sock_alloc_send_pskb(sk, headroom + linear, len - linear, 1133 skb = sock_alloc_send_pskb(sk, headroom + linear, len - linear,
1131 noblock, &err, 0); 1134 noblock, &err, 0);