Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 291759a5 authored by Eugene Crosser's avatar Eugene Crosser Committed by David S. Miller
Browse files

af_iucv: remove fragment_skb() to use paged SKBs



Before introducing paged skbs in the receive path, get rid of the
function `iucv_fragment_skb()` that replaces one large linear skb
with several smaller linear skbs.

Signed-off-by: default avatarEugene Crosser <Eugene.Crosser@ru.ibm.com>
Signed-off-by: default avatarUrsula Braun <ubraun@linux.vnet.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e5374399
Loading
Loading
Loading
Loading
+3 −56
Original line number Diff line number Diff line
@@ -1231,44 +1231,6 @@ static int iucv_sock_sendmsg(struct socket *sock, struct msghdr *msg,
	return err;
}

/* iucv_fragment_skb() - Fragment a single IUCV message into multiple skb's
 *
 * Locking: must be called with message_q.lock held
 */
static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len)
{
	int dataleft, size, copied = 0;
	struct sk_buff *nskb;

	dataleft = len;
	while (dataleft) {
		if (dataleft >= sk->sk_rcvbuf / 4)
			size = sk->sk_rcvbuf / 4;
		else
			size = dataleft;

		nskb = alloc_skb(size, GFP_ATOMIC | GFP_DMA);
		if (!nskb)
			return -ENOMEM;

		/* copy target class to control buffer of new skb */
		IUCV_SKB_CB(nskb)->class = IUCV_SKB_CB(skb)->class;

		/* copy data fragment */
		memcpy(nskb->data, skb->data + copied, size);
		copied += size;
		dataleft -= size;

		skb_reset_transport_header(nskb);
		skb_reset_network_header(nskb);
		nskb->len = size;

		skb_queue_tail(&iucv_sk(sk)->backlog_skb_q, nskb);
	}

	return 0;
}

/* iucv_process_message() - Receive a single outstanding IUCV message
 *
 * Locking: must be called with message_q.lock held
@@ -1300,25 +1262,10 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb,
			kfree_skb(skb);
			return;
		}
		/* we need to fragment iucv messages for SOCK_STREAM only;
		 * for SOCK_SEQPACKET, it is only relevant if we support
		 * record segmentation using MSG_EOR (see also recvmsg()) */
		if (sk->sk_type == SOCK_STREAM &&
		    skb->truesize >= sk->sk_rcvbuf / 4) {
			rc = iucv_fragment_skb(sk, skb, len);
			kfree_skb(skb);
			skb = NULL;
			if (rc) {
				pr_iucv->path_sever(path, NULL);
				return;
			}
			skb = skb_dequeue(&iucv_sk(sk)->backlog_skb_q);
		} else {
		skb_reset_transport_header(skb);
		skb_reset_network_header(skb);
		skb->len = len;
	}
	}

	IUCV_SKB_CB(skb)->offset = 0;
	if (sock_queue_rcv_skb(sk, skb))