mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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
					
				
					 1 changed files with 14 additions and 11 deletions
				
			
		| 
						 | 
				
			
			@ -1044,7 +1044,8 @@ static int iucv_sock_sendmsg(struct socket *sock, struct msghdr *msg,
 | 
			
		|||
{
 | 
			
		||||
	struct sock *sk = sock->sk;
 | 
			
		||||
	struct iucv_sock *iucv = iucv_sk(sk);
 | 
			
		||||
	size_t headroom, linear;
 | 
			
		||||
	size_t headroom = 0;
 | 
			
		||||
	size_t linear;
 | 
			
		||||
	struct sk_buff *skb;
 | 
			
		||||
	struct iucv_message txmsg = {0};
 | 
			
		||||
	struct cmsghdr *cmsg;
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
	 * segmented records using the MSG_EOR flag), but
 | 
			
		||||
	 * for SOCK_STREAM we might want to improve it in future */
 | 
			
		||||
	headroom = (iucv->transport == AF_IUCV_TRANS_HIPER)
 | 
			
		||||
		   ? sizeof(struct af_iucv_trans_hdr) + ETH_HLEN : 0;
 | 
			
		||||
	if (headroom + len < PAGE_SIZE) {
 | 
			
		||||
	if (iucv->transport == AF_IUCV_TRANS_HIPER) {
 | 
			
		||||
		headroom = sizeof(struct af_iucv_trans_hdr) + ETH_HLEN;
 | 
			
		||||
		linear = len;
 | 
			
		||||
	} else {
 | 
			
		||||
		if (len < PAGE_SIZE) {
 | 
			
		||||
			linear = len;
 | 
			
		||||
		} else {
 | 
			
		||||
			/* In nonlinear "classic" iucv skb,
 | 
			
		||||
			 * 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);
 | 
			
		||||
			linear = PAGE_SIZE - headroom;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	skb = sock_alloc_send_pskb(sk, headroom + linear, len - linear,
 | 
			
		||||
				   noblock, &err, 0);
 | 
			
		||||
	if (!skb)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue