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

Commit 62bccb8c authored by Alexander Duyck's avatar Alexander Duyck Committed by David S. Miller
Browse files

net-timestamp: Make the clone operation stand-alone from phy timestamping



The phy timestamping takes a different path than the regular timestamping
does in that it will create a clone first so that the packets needing to be
timestamped can be placed in a queue, or the context block could be used.

In order to support these use cases I am pulling the core of the code out
so it can be used in other drivers beyond just phy devices.

In addition I have added a destructor named sock_efree which is meant to
provide a simple way for dropping the reference to skb exceptions that
aren't part of either the receive or send windows for the socket, and I
have removed some duplication in spots where this destructor could be used
in place of sock_edemux.

Signed-off-by: default avatarAlexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 37846ef0
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -1148,7 +1148,7 @@ static void dp83640_remove(struct phy_device *phydev)
		kfree_skb(skb);

	while ((skb = skb_dequeue(&dp83640->tx_queue)) != NULL)
		skb_complete_tx_timestamp(skb, NULL);
		kfree_skb(skb);

	clock = dp83640_clock_get(dp83640->clock);

@@ -1405,7 +1405,7 @@ static void dp83640_txtstamp(struct phy_device *phydev,

	case HWTSTAMP_TX_ONESTEP_SYNC:
		if (is_sync(skb, type)) {
			skb_complete_tx_timestamp(skb, NULL);
			kfree_skb(skb);
			return;
		}
		/* fall through */
@@ -1416,7 +1416,7 @@ static void dp83640_txtstamp(struct phy_device *phydev,

	case HWTSTAMP_TX_OFF:
	default:
		skb_complete_tx_timestamp(skb, NULL);
		kfree_skb(skb);
		break;
	}
}
+2 −0
Original line number Diff line number Diff line
@@ -2690,6 +2690,8 @@ static inline ktime_t net_invalid_timestamp(void)
	return ktime_set(0, 0);
}

struct sk_buff *skb_clone_sk(struct sk_buff *skb);

#ifdef CONFIG_NETWORK_PHY_TIMESTAMPING

void skb_clone_tx_timestamp(struct sk_buff *skb);
+1 −0
Original line number Diff line number Diff line
@@ -1574,6 +1574,7 @@ struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force,
void sock_wfree(struct sk_buff *skb);
void skb_orphan_partial(struct sk_buff *skb);
void sock_rfree(struct sk_buff *skb);
void sock_efree(struct sk_buff *skb);
void sock_edemux(struct sk_buff *skb);

int sock_setsockopt(struct socket *sock, int level, int op,
+25 −7
Original line number Diff line number Diff line
@@ -3511,6 +3511,27 @@ struct sk_buff *sock_dequeue_err_skb(struct sock *sk)
}
EXPORT_SYMBOL(sock_dequeue_err_skb);

struct sk_buff *skb_clone_sk(struct sk_buff *skb)
{
	struct sock *sk = skb->sk;
	struct sk_buff *clone;

	if (!sk || !atomic_inc_not_zero(&sk->sk_refcnt))
		return NULL;

	clone = skb_clone(skb, GFP_ATOMIC);
	if (!clone) {
		sock_put(sk);
		return NULL;
	}

	clone->sk = sk;
	clone->destructor = sock_efree;

	return clone;
}
EXPORT_SYMBOL(skb_clone_sk);

static void __skb_complete_tx_timestamp(struct sk_buff *skb,
					struct sock *sk,
					int tstype)
@@ -3540,14 +3561,11 @@ void skb_complete_tx_timestamp(struct sk_buff *skb,
{
	struct sock *sk = skb->sk;

	skb->sk = NULL;
	/* take a reference to prevent skb_orphan() from freeing the socket */
	sock_hold(sk);

	if (hwtstamps) {
	*skb_hwtstamps(skb) = *hwtstamps;
	__skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND);
	} else {
		kfree_skb(skb);
	}

	sock_put(sk);
}
+6 −0
Original line number Diff line number Diff line
@@ -1637,6 +1637,12 @@ void sock_rfree(struct sk_buff *skb)
}
EXPORT_SYMBOL(sock_rfree);

void sock_efree(struct sk_buff *skb)
{
	sock_put(skb->sk);
}
EXPORT_SYMBOL(sock_efree);

void sock_edemux(struct sk_buff *skb)
{
	struct sock *sk = skb->sk;
Loading