Skip to content

Commit 62bccb8

Browse files
Alexander Duyckdavem330
authored andcommitted
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: Alexander Duyck <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 37846ef commit 62bccb8

File tree

6 files changed

+40
-21
lines changed

6 files changed

+40
-21
lines changed

drivers/net/phy/dp83640.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,7 +1148,7 @@ static void dp83640_remove(struct phy_device *phydev)
11481148
kfree_skb(skb);
11491149

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

11531153
clock = dp83640_clock_get(dp83640->clock);
11541154

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

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

14171417
case HWTSTAMP_TX_OFF:
14181418
default:
1419-
skb_complete_tx_timestamp(skb, NULL);
1419+
kfree_skb(skb);
14201420
break;
14211421
}
14221422
}

include/linux/skbuff.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2690,6 +2690,8 @@ static inline ktime_t net_invalid_timestamp(void)
26902690
return ktime_set(0, 0);
26912691
}
26922692

2693+
struct sk_buff *skb_clone_sk(struct sk_buff *skb);
2694+
26932695
#ifdef CONFIG_NETWORK_PHY_TIMESTAMPING
26942696

26952697
void skb_clone_tx_timestamp(struct sk_buff *skb);

include/net/sock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,6 +1574,7 @@ struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force,
15741574
void sock_wfree(struct sk_buff *skb);
15751575
void skb_orphan_partial(struct sk_buff *skb);
15761576
void sock_rfree(struct sk_buff *skb);
1577+
void sock_efree(struct sk_buff *skb);
15771578
void sock_edemux(struct sk_buff *skb);
15781579

15791580
int sock_setsockopt(struct socket *sock, int level, int op,

net/core/skbuff.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3511,6 +3511,27 @@ struct sk_buff *sock_dequeue_err_skb(struct sock *sk)
35113511
}
35123512
EXPORT_SYMBOL(sock_dequeue_err_skb);
35133513

3514+
struct sk_buff *skb_clone_sk(struct sk_buff *skb)
3515+
{
3516+
struct sock *sk = skb->sk;
3517+
struct sk_buff *clone;
3518+
3519+
if (!sk || !atomic_inc_not_zero(&sk->sk_refcnt))
3520+
return NULL;
3521+
3522+
clone = skb_clone(skb, GFP_ATOMIC);
3523+
if (!clone) {
3524+
sock_put(sk);
3525+
return NULL;
3526+
}
3527+
3528+
clone->sk = sk;
3529+
clone->destructor = sock_efree;
3530+
3531+
return clone;
3532+
}
3533+
EXPORT_SYMBOL(skb_clone_sk);
3534+
35143535
static void __skb_complete_tx_timestamp(struct sk_buff *skb,
35153536
struct sock *sk,
35163537
int tstype)
@@ -3540,14 +3561,11 @@ void skb_complete_tx_timestamp(struct sk_buff *skb,
35403561
{
35413562
struct sock *sk = skb->sk;
35423563

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

3545-
if (hwtstamps) {
3546-
*skb_hwtstamps(skb) = *hwtstamps;
3547-
__skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND);
3548-
} else {
3549-
kfree_skb(skb);
3550-
}
3567+
*skb_hwtstamps(skb) = *hwtstamps;
3568+
__skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND);
35513569

35523570
sock_put(sk);
35533571
}

net/core/sock.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,6 +1637,12 @@ void sock_rfree(struct sk_buff *skb)
16371637
}
16381638
EXPORT_SYMBOL(sock_rfree);
16391639

1640+
void sock_efree(struct sk_buff *skb)
1641+
{
1642+
sock_put(skb->sk);
1643+
}
1644+
EXPORT_SYMBOL(sock_efree);
1645+
16401646
void sock_edemux(struct sk_buff *skb)
16411647
{
16421648
struct sock *sk = skb->sk;

net/core/timestamping.c

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,9 @@ void skb_clone_tx_timestamp(struct sk_buff *skb)
3636
{
3737
struct phy_device *phydev;
3838
struct sk_buff *clone;
39-
struct sock *sk = skb->sk;
4039
unsigned int type;
4140

42-
if (!sk)
41+
if (!skb->sk)
4342
return;
4443

4544
type = classify(skb);
@@ -48,16 +47,9 @@ void skb_clone_tx_timestamp(struct sk_buff *skb)
4847

4948
phydev = skb->dev->phydev;
5049
if (likely(phydev->drv->txtstamp)) {
51-
if (!atomic_inc_not_zero(&sk->sk_refcnt))
50+
clone = skb_clone_sk(skb);
51+
if (!clone)
5252
return;
53-
54-
clone = skb_clone(skb, GFP_ATOMIC);
55-
if (!clone) {
56-
sock_put(sk);
57-
return;
58-
}
59-
60-
clone->sk = sk;
6153
phydev->drv->txtstamp(phydev, clone, type);
6254
}
6355
}

0 commit comments

Comments
 (0)