net/af_iucv: don't use paged skbs for TX on HiperSockets
With commite53743994e
("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> Cc: <stable@vger.kernel.org> # v4.8+ Fixes:e53743994e
("af_iucv: use paged SKBs for big outbound messages") Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
5d722b3024
commit
dc5367bcc5
@ -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,18 +1123,20 @@ 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;
|
linear = len;
|
||||||
} else {
|
} else {
|
||||||
/* In nonlinear "classic" iucv skb,
|
if (len < PAGE_SIZE) {
|
||||||
* reserve space for iucv_array
|
linear = len;
|
||||||
*/
|
} else {
|
||||||
if (iucv->transport != AF_IUCV_TRANS_HIPER)
|
/* In nonlinear "classic" iucv skb,
|
||||||
headroom += sizeof(struct iucv_array) *
|
* reserve space for iucv_array
|
||||||
(MAX_SKB_FRAGS + 1);
|
*/
|
||||||
linear = PAGE_SIZE - headroom;
|
headroom = sizeof(struct iucv_array) *
|
||||||
|
(MAX_SKB_FRAGS + 1);
|
||||||
|
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user