Skip to content

Commit 2c048e6

Browse files
committed
Merge branch 'timestamping'
Alexander Duyck says: ==================== This change makes it so that the core path for the phy timestamping logic is shared between skb_tx_tstamp and skb_complete_tx_timestamp. In addition it provides a means of using the same skb clone type path in non phy timestamping drivers. The main motivation for this is to enable non-phy drivers to be able to manipulate tx timestamp skbs for such things as putting them in lists or setting aside buffer in the context block. v2: Incorporated suggested changes from Willem de Bruijn and Eric Dumazet dropped uneeded comment restored order of hwtstamp vs swtstamp added destructor for skb Dropped usage of skb_complete_tx_timestamp as a kfree_skb w/ destructor v3: Updated destructor handling and dealt with socket reference counting issues v4: Split out combining destructors into a separate patch ====================
2 parents d546c62 + 82eabd9 commit 2c048e6

File tree

7 files changed

+80
-67
lines changed

7 files changed

+80
-67
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: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,7 +1574,12 @@ 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);
1578+
#ifdef CONFIG_INET
15771579
void sock_edemux(struct sk_buff *skb);
1580+
#else
1581+
#define sock_edemux(skb) sock_efree(skb)
1582+
#endif
15781583

15791584
int sock_setsockopt(struct socket *sock, int level, int op,
15801585
char __user *optval, unsigned int optlen);

net/core/skbuff.c

Lines changed: 58 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3511,32 +3511,33 @@ struct sk_buff *sock_dequeue_err_skb(struct sock *sk)
35113511
}
35123512
EXPORT_SYMBOL(sock_dequeue_err_skb);
35133513

3514-
void __skb_tstamp_tx(struct sk_buff *orig_skb,
3515-
struct skb_shared_hwtstamps *hwtstamps,
3516-
struct sock *sk, int tstype)
3514+
struct sk_buff *skb_clone_sk(struct sk_buff *skb)
35173515
{
3518-
struct sock_exterr_skb *serr;
3519-
struct sk_buff *skb;
3520-
int err;
3516+
struct sock *sk = skb->sk;
3517+
struct sk_buff *clone;
35213518

3522-
if (!sk)
3523-
return;
3519+
if (!sk || !atomic_inc_not_zero(&sk->sk_refcnt))
3520+
return NULL;
35243521

3525-
if (hwtstamps) {
3526-
*skb_hwtstamps(orig_skb) =
3527-
*hwtstamps;
3528-
} else {
3529-
/*
3530-
* no hardware time stamps available,
3531-
* so keep the shared tx_flags and only
3532-
* store software time stamp
3533-
*/
3534-
orig_skb->tstamp = ktime_get_real();
3522+
clone = skb_clone(skb, GFP_ATOMIC);
3523+
if (!clone) {
3524+
sock_put(sk);
3525+
return NULL;
35353526
}
35363527

3537-
skb = skb_clone(orig_skb, GFP_ATOMIC);
3538-
if (!skb)
3539-
return;
3528+
clone->sk = sk;
3529+
clone->destructor = sock_efree;
3530+
3531+
return clone;
3532+
}
3533+
EXPORT_SYMBOL(skb_clone_sk);
3534+
3535+
static void __skb_complete_tx_timestamp(struct sk_buff *skb,
3536+
struct sock *sk,
3537+
int tstype)
3538+
{
3539+
struct sock_exterr_skb *serr;
3540+
int err;
35403541

35413542
serr = SKB_EXT_ERR(skb);
35423543
memset(serr, 0, sizeof(*serr));
@@ -3554,6 +3555,42 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
35543555
if (err)
35553556
kfree_skb(skb);
35563557
}
3558+
3559+
void skb_complete_tx_timestamp(struct sk_buff *skb,
3560+
struct skb_shared_hwtstamps *hwtstamps)
3561+
{
3562+
struct sock *sk = skb->sk;
3563+
3564+
/* take a reference to prevent skb_orphan() from freeing the socket */
3565+
sock_hold(sk);
3566+
3567+
*skb_hwtstamps(skb) = *hwtstamps;
3568+
__skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND);
3569+
3570+
sock_put(sk);
3571+
}
3572+
EXPORT_SYMBOL_GPL(skb_complete_tx_timestamp);
3573+
3574+
void __skb_tstamp_tx(struct sk_buff *orig_skb,
3575+
struct skb_shared_hwtstamps *hwtstamps,
3576+
struct sock *sk, int tstype)
3577+
{
3578+
struct sk_buff *skb;
3579+
3580+
if (!sk)
3581+
return;
3582+
3583+
if (hwtstamps)
3584+
*skb_hwtstamps(orig_skb) = *hwtstamps;
3585+
else
3586+
orig_skb->tstamp = ktime_get_real();
3587+
3588+
skb = skb_clone(orig_skb, GFP_ATOMIC);
3589+
if (!skb)
3590+
return;
3591+
3592+
__skb_complete_tx_timestamp(skb, sk, tstype);
3593+
}
35573594
EXPORT_SYMBOL_GPL(__skb_tstamp_tx);
35583595

35593596
void skb_tstamp_tx(struct sk_buff *orig_skb,

net/core/sock.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,18 +1637,24 @@ 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+
1646+
#ifdef CONFIG_INET
16401647
void sock_edemux(struct sk_buff *skb)
16411648
{
16421649
struct sock *sk = skb->sk;
16431650

1644-
#ifdef CONFIG_INET
16451651
if (sk->sk_state == TCP_TIME_WAIT)
16461652
inet_twsk_put(inet_twsk(sk));
16471653
else
1648-
#endif
16491654
sock_put(sk);
16501655
}
16511656
EXPORT_SYMBOL(sock_edemux);
1657+
#endif
16521658

16531659
kuid_t sock_i_uid(struct sock *sk)
16541660
{

net/core/timestamping.c

Lines changed: 3 additions & 40 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,50 +47,14 @@ 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
}
6456
EXPORT_SYMBOL_GPL(skb_clone_tx_timestamp);
6557

66-
void skb_complete_tx_timestamp(struct sk_buff *skb,
67-
struct skb_shared_hwtstamps *hwtstamps)
68-
{
69-
struct sock *sk = skb->sk;
70-
struct sock_exterr_skb *serr;
71-
int err;
72-
73-
if (!hwtstamps) {
74-
sock_put(sk);
75-
kfree_skb(skb);
76-
return;
77-
}
78-
79-
*skb_hwtstamps(skb) = *hwtstamps;
80-
81-
serr = SKB_EXT_ERR(skb);
82-
memset(serr, 0, sizeof(*serr));
83-
serr->ee.ee_errno = ENOMSG;
84-
serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING;
85-
skb->sk = NULL;
86-
87-
err = sock_queue_err_skb(sk, skb);
88-
89-
sock_put(sk);
90-
if (err)
91-
kfree_skb(skb);
92-
}
93-
EXPORT_SYMBOL_GPL(skb_complete_tx_timestamp);
94-
9558
bool skb_defer_rx_timestamp(struct sk_buff *skb)
9659
{
9760
struct phy_device *phydev;

net/ipv4/udp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1972,7 +1972,7 @@ void udp_v4_early_demux(struct sk_buff *skb)
19721972
return;
19731973

19741974
skb->sk = sk;
1975-
skb->destructor = sock_edemux;
1975+
skb->destructor = sock_efree;
19761976
dst = sk->sk_rx_dst;
19771977

19781978
if (dst)

0 commit comments

Comments
 (0)