Commit 2b133adf authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'skb_list_walk_safe-refactoring'



Jason A. Donenfeld says:

====================
skb_list_walk_safe refactoring for net/*'s skb_gso_segment usage

This patchset adjusts all return values of skb_gso_segment in net/* to
use the new skb_list_walk_safe helper.

First we fix a minor bug in the helper macro that didn't come up in the
last patchset's uses. Then we adjust several cases throughout net/. The
xfrm changes were a bit hairy, but doable. Reading and thinking about
the code in mac80211 indicates a memory leak, which the commit
addresses. All the other cases were pretty trivial.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ec22ab00 9f3ef3d7
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -1479,9 +1479,9 @@ static inline void skb_mark_not_on_list(struct sk_buff *skb)
}

/* Iterate through singly-linked GSO fragments of an skb. */
#define skb_list_walk_safe(first, skb, next)                                   \
	for ((skb) = (first), (next) = (skb) ? (skb)->next : NULL; (skb);      \
	     (skb) = (next), (next) = (skb) ? (skb)->next : NULL)
#define skb_list_walk_safe(first, skb, next_skb)                               \
	for ((skb) = (first), (next_skb) = (skb) ? (skb)->next : NULL; (skb);  \
	     (skb) = (next_skb), (next_skb) = (skb) ? (skb)->next : NULL)

static inline void skb_list_del_init(struct sk_buff *skb)
{
+3 −5
Original line number Diff line number Diff line
@@ -240,8 +240,8 @@ static int ip_finish_output2(struct net *net, struct sock *sk, struct sk_buff *s
static int ip_finish_output_gso(struct net *net, struct sock *sk,
				struct sk_buff *skb, unsigned int mtu)
{
	struct sk_buff *segs, *nskb;
	netdev_features_t features;
	struct sk_buff *segs;
	int ret = 0;

	/* common case: seglen is <= mtu
@@ -272,8 +272,7 @@ static int ip_finish_output_gso(struct net *net, struct sock *sk,

	consume_skb(skb);

	do {
		struct sk_buff *nskb = segs->next;
	skb_list_walk_safe(segs, segs, nskb) {
		int err;

		skb_mark_not_on_list(segs);
@@ -281,8 +280,7 @@ static int ip_finish_output_gso(struct net *net, struct sock *sk,

		if (err && ret == 0)
			ret = err;
		segs = nskb;
	} while (segs);
	}

	return ret;
}
+1 −2
Original line number Diff line number Diff line
@@ -2104,8 +2104,7 @@ static int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
	BUILD_BUG_ON(sizeof(struct udp_skb_cb) > SKB_SGO_CB_OFFSET);
	__skb_push(skb, -skb_mac_offset(skb));
	segs = udp_rcv_segment(sk, skb, true);
	for (skb = segs; skb; skb = next) {
		next = skb->next;
	skb_list_walk_safe(segs, skb, next) {
		__skb_pull(skb, skb_transport_offset(skb));
		ret = udp_queue_rcv_one_skb(sk, skb);
		if (ret > 0)
+1 −2
Original line number Diff line number Diff line
@@ -690,8 +690,7 @@ static int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)

	__skb_push(skb, -skb_mac_offset(skb));
	segs = udp_rcv_segment(sk, skb, false);
	for (skb = segs; skb; skb = next) {
		next = skb->next;
	skb_list_walk_safe(segs, skb, next) {
		__skb_pull(skb, skb_transport_offset(skb));

		ret = udpv6_queue_rcv_one_skb(sk, skb);
+5 −8
Original line number Diff line number Diff line
@@ -3949,18 +3949,15 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
		}
	}

	next = skb;
	while (next) {
		skb = next;
		next = skb->next;

		skb->prev = NULL;
		skb->next = NULL;
	skb_list_walk_safe(skb, skb, next) {
		skb_mark_not_on_list(skb);

		skb = ieee80211_build_hdr(sdata, skb, info_flags,
					  sta, ctrl_flags);
		if (IS_ERR(skb))
		if (IS_ERR(skb)) {
			kfree_skb_list(next);
			goto out;
		}

		ieee80211_tx_stats(dev, skb->len);

Loading