Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: simplify flags for tx timestamping

This patch removes the abstraction introduced by the union skb_shared_tx in
the shared skb data.

The access of the different union elements at several places led to some
confusion about accessing the shared tx_flags e.g. in skb_orphan_try().

http://marc.info/?l=linux-netdev&m=128084897415886&w=2

Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Oliver Hartkopp and committed by
David S. Miller
2244d07b 4d5870ec

+68 -87
+13 -9
Documentation/networking/timestamping.txt
··· 172 172 }; 173 173 174 174 Time stamps for outgoing packets are to be generated as follows: 175 - - In hard_start_xmit(), check if skb_tx(skb)->hardware is set no-zero. 176 - If yes, then the driver is expected to do hardware time stamping. 175 + - In hard_start_xmit(), check if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) 176 + is set no-zero. If yes, then the driver is expected to do hardware time 177 + stamping. 177 178 - If this is possible for the skb and requested, then declare 178 - that the driver is doing the time stamping by setting the field 179 - skb_tx(skb)->in_progress non-zero. You might want to keep a pointer 180 - to the associated skb for the next step and not free the skb. A driver 181 - not supporting hardware time stamping doesn't do that. A driver must 182 - never touch sk_buff::tstamp! It is used to store software generated 183 - time stamps by the network subsystem. 179 + that the driver is doing the time stamping by setting the flag 180 + SKBTX_IN_PROGRESS in skb_shinfo(skb)->tx_flags , e.g. with 181 + 182 + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; 183 + 184 + You might want to keep a pointer to the associated skb for the next step 185 + and not free the skb. A driver not supporting hardware time stamping doesn't 186 + do that. A driver must never touch sk_buff::tstamp! It is used to store 187 + software generated time stamps by the network subsystem. 184 188 - As soon as the driver has sent the packet and/or obtained a 185 189 hardware time stamp for it, it passes the time stamp back by 186 190 calling skb_hwtstamp_tx() with the original skb, the raw ··· 195 191 this would occur at a later time in the processing pipeline than other 196 192 software time stamping and therefore could lead to unexpected deltas 197 193 between time stamps. 198 - - If the driver did not call set skb_tx(skb)->in_progress, then 194 + - If the driver did not set the SKBTX_IN_PROGRESS flag (see above), then 199 195 dev_hard_start_xmit() checks whether software time stamping 200 196 is wanted as fallback and potentially generates the time stamp.
+4 -6
drivers/net/bfin_mac.c
··· 803 803 static void bfin_tx_hwtstamp(struct net_device *netdev, struct sk_buff *skb) 804 804 { 805 805 struct bfin_mac_local *lp = netdev_priv(netdev); 806 - union skb_shared_tx *shtx = skb_tx(skb); 807 806 808 - if (shtx->hardware) { 807 + if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) { 809 808 int timeout_cnt = MAX_TIMEOUT_CNT; 810 809 811 810 /* When doing time stamping, keep the connection to the socket 812 811 * a while longer 813 812 */ 814 - shtx->in_progress = 1; 813 + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; 815 814 816 815 /* 817 816 * The timestamping is done at the EMAC module's MII/RMII interface ··· 990 991 struct bfin_mac_local *lp = netdev_priv(dev); 991 992 u16 *data; 992 993 u32 data_align = (unsigned long)(skb->data) & 0x3; 993 - union skb_shared_tx *shtx = skb_tx(skb); 994 994 995 995 current_tx_ptr->skb = skb; 996 996 ··· 1003 1005 * of this field are the length of the packet payload in bytes and the higher 1004 1006 * 4 bits are the timestamping enable field. 1005 1007 */ 1006 - if (shtx->hardware) 1008 + if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) 1007 1009 *data |= 0x1000; 1008 1010 1009 1011 current_tx_ptr->desc_a.start_addr = (u32)data; ··· 1013 1015 } else { 1014 1016 *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len); 1015 1017 /* enable timestamping for the sent packet */ 1016 - if (shtx->hardware) 1018 + if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) 1017 1019 *((u16 *)(current_tx_ptr->packet)) |= 0x1000; 1018 1020 memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data, 1019 1021 skb->len);
+6 -9
drivers/net/gianfar.c
··· 2048 2048 u32 bufaddr; 2049 2049 unsigned long flags; 2050 2050 unsigned int nr_frags, nr_txbds, length; 2051 - union skb_shared_tx *shtx; 2052 2051 2053 2052 /* 2054 2053 * TOE=1 frames larger than 2500 bytes may see excess delays ··· 2068 2069 txq = netdev_get_tx_queue(dev, rq); 2069 2070 base = tx_queue->tx_bd_base; 2070 2071 regs = tx_queue->grp->regs; 2071 - shtx = skb_tx(skb); 2072 2072 2073 2073 /* check if time stamp should be generated */ 2074 - if (unlikely(shtx->hardware && priv->hwts_tx_en)) 2074 + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && 2075 + priv->hwts_tx_en)) 2075 2076 do_tstamp = 1; 2076 2077 2077 2078 /* make space for additional header when fcb is needed */ ··· 2173 2174 2174 2175 /* Setup tx hardware time stamping if requested */ 2175 2176 if (unlikely(do_tstamp)) { 2176 - shtx->in_progress = 1; 2177 + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; 2177 2178 if (fcb == NULL) 2178 2179 fcb = gfar_add_fcb(skb); 2179 2180 fcb->ptp = 1; ··· 2445 2446 int howmany = 0; 2446 2447 u32 lstatus; 2447 2448 size_t buflen; 2448 - union skb_shared_tx *shtx; 2449 2449 2450 2450 rx_queue = priv->rx_queue[tx_queue->qindex]; 2451 2451 bdp = tx_queue->dirty_tx; ··· 2459 2461 * When time stamping, one additional TxBD must be freed. 2460 2462 * Also, we need to dma_unmap_single() the TxPAL. 2461 2463 */ 2462 - shtx = skb_tx(skb); 2463 - if (unlikely(shtx->in_progress)) 2464 + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) 2464 2465 nr_txbds = frags + 2; 2465 2466 else 2466 2467 nr_txbds = frags + 1; ··· 2473 2476 (lstatus & BD_LENGTH_MASK)) 2474 2477 break; 2475 2478 2476 - if (unlikely(shtx->in_progress)) { 2479 + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) { 2477 2480 next = next_txbd(bdp, base, tx_ring_size); 2478 2481 buflen = next->length + GMAC_FCB_LEN; 2479 2482 } else ··· 2482 2485 dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr, 2483 2486 buflen, DMA_TO_DEVICE); 2484 2487 2485 - if (unlikely(shtx->in_progress)) { 2488 + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) { 2486 2489 struct skb_shared_hwtstamps shhwtstamps; 2487 2490 u64 *ns = (u64*) (((u32)skb->data + 0x10) & ~0x7); 2488 2491 memset(&shhwtstamps, 0, sizeof(shhwtstamps));
+1 -1
drivers/net/igb/igb.h
··· 143 143 u16 next_to_watch; 144 144 unsigned int bytecount; 145 145 u16 gso_segs; 146 - union skb_shared_tx shtx; 146 + u8 tx_flags; 147 147 u8 mapped_as_page; 148 148 }; 149 149 /* RX */
+5 -6
drivers/net/igb/igb_main.c
··· 3954 3954 } 3955 3955 3956 3956 tx_ring->buffer_info[i].skb = skb; 3957 - tx_ring->buffer_info[i].shtx = skb_shinfo(skb)->tx_flags; 3957 + tx_ring->buffer_info[i].tx_flags = skb_shinfo(skb)->tx_flags; 3958 3958 /* multiply data chunks by size of headers */ 3959 3959 tx_ring->buffer_info[i].bytecount = ((gso_segs - 1) * hlen) + skb->len; 3960 3960 tx_ring->buffer_info[i].gso_segs = gso_segs; ··· 4088 4088 u32 tx_flags = 0; 4089 4089 u16 first; 4090 4090 u8 hdr_len = 0; 4091 - union skb_shared_tx *shtx = skb_tx(skb); 4092 4091 4093 4092 /* need: 1 descriptor per page, 4094 4093 * + 2 desc gap to keep tail from touching head, ··· 4099 4100 return NETDEV_TX_BUSY; 4100 4101 } 4101 4102 4102 - if (unlikely(shtx->hardware)) { 4103 - shtx->in_progress = 1; 4103 + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { 4104 + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; 4104 4105 tx_flags |= IGB_TX_FLAGS_TSTAMP; 4105 4106 } 4106 4107 ··· 5318 5319 u64 regval; 5319 5320 5320 5321 /* if skb does not support hw timestamp or TX stamp not valid exit */ 5321 - if (likely(!buffer_info->shtx.hardware) || 5322 + if (likely(!(buffer_info->tx_flags & SKBTX_HW_TSTAMP)) || 5322 5323 !(rd32(E1000_TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID)) 5323 5324 return; 5324 5325 ··· 5499 5500 * values must belong to this one here and therefore we don't need to 5500 5501 * compare any of the additional attributes stored for it. 5501 5502 * 5502 - * If nothing went wrong, then it should have a skb_shared_tx that we 5503 + * If nothing went wrong, then it should have a shared tx_flags that we 5503 5504 * can turn into a skb_shared_hwtstamps. 5504 5505 */ 5505 5506 if (staterr & E1000_RXDADV_STAT_TSIP) {
+16 -28
include/linux/skbuff.h
··· 163 163 ktime_t syststamp; 164 164 }; 165 165 166 - /** 167 - * struct skb_shared_tx - instructions for time stamping of outgoing packets 168 - * @hardware: generate hardware time stamp 169 - * @software: generate software time stamp 170 - * @in_progress: device driver is going to provide 171 - * hardware time stamp 172 - * @prevent_sk_orphan: make sk reference available on driver level 173 - * @flags: all shared_tx flags 174 - * 175 - * These flags are attached to packets as part of the 176 - * &skb_shared_info. Use skb_tx() to get a pointer. 177 - */ 178 - union skb_shared_tx { 179 - struct { 180 - __u8 hardware:1, 181 - software:1, 182 - in_progress:1, 183 - prevent_sk_orphan:1; 184 - }; 185 - __u8 flags; 166 + /* Definitions for tx_flags in struct skb_shared_info */ 167 + enum { 168 + /* generate hardware time stamp */ 169 + SKBTX_HW_TSTAMP = 1 << 0, 170 + 171 + /* generate software time stamp */ 172 + SKBTX_SW_TSTAMP = 1 << 1, 173 + 174 + /* device driver is going to provide hardware time stamp */ 175 + SKBTX_IN_PROGRESS = 1 << 2, 176 + 177 + /* ensure the originating sk reference is available on driver level */ 178 + SKBTX_DRV_NEEDS_SK_REF = 1 << 3, 186 179 }; 187 180 188 181 /* This data is invariant across clones and lives at ··· 188 195 unsigned short gso_segs; 189 196 unsigned short gso_type; 190 197 __be32 ip6_frag_id; 191 - union skb_shared_tx tx_flags; 198 + __u8 tx_flags; 192 199 struct sk_buff *frag_list; 193 200 struct skb_shared_hwtstamps hwtstamps; 194 201 ··· 578 585 static inline struct skb_shared_hwtstamps *skb_hwtstamps(struct sk_buff *skb) 579 586 { 580 587 return &skb_shinfo(skb)->hwtstamps; 581 - } 582 - 583 - static inline union skb_shared_tx *skb_tx(struct sk_buff *skb) 584 - { 585 - return &skb_shinfo(skb)->tx_flags; 586 588 } 587 589 588 590 /** ··· 1984 1996 1985 1997 static inline void sw_tx_timestamp(struct sk_buff *skb) 1986 1998 { 1987 - union skb_shared_tx *shtx = skb_tx(skb); 1988 - if (shtx->software && !shtx->in_progress) 1999 + if (skb_shinfo(skb)->tx_flags & SKBTX_SW_TSTAMP && 2000 + !(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) 1989 2001 skb_tstamp_tx(skb, NULL); 1990 2002 } 1991 2003
+1 -1
include/net/ip.h
··· 53 53 __be32 addr; 54 54 int oif; 55 55 struct ip_options *opt; 56 - union skb_shared_tx shtx; 56 + __u8 tx_flags; 57 57 }; 58 58 59 59 #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb))
+2 -6
include/net/sock.h
··· 1669 1669 1670 1670 /** 1671 1671 * sock_tx_timestamp - checks whether the outgoing packet is to be time stamped 1672 - * @msg: outgoing packet 1673 1672 * @sk: socket sending this packet 1674 - * @shtx: filled with instructions for time stamping 1673 + * @tx_flags: filled with instructions for time stamping 1675 1674 * 1676 1675 * Currently only depends on SOCK_TIMESTAMPING* flags. Returns error code if 1677 1676 * parameters are invalid. 1678 1677 */ 1679 - extern int sock_tx_timestamp(struct msghdr *msg, 1680 - struct sock *sk, 1681 - union skb_shared_tx *shtx); 1682 - 1678 + extern int sock_tx_timestamp(struct sock *sk, __u8 *tx_flags); 1683 1679 1684 1680 /** 1685 1681 * sk_eat_skb - Release a skb if it is no longer needed
+2 -2
net/can/raw.c
··· 647 647 err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); 648 648 if (err < 0) 649 649 goto free_skb; 650 - err = sock_tx_timestamp(msg, sk, skb_tx(skb)); 650 + err = sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags); 651 651 if (err < 0) 652 652 goto free_skb; 653 653 654 654 /* to be able to check the received tx sock reference in raw_rcv() */ 655 - skb_tx(skb)->prevent_sk_orphan = 1; 655 + skb_shinfo(skb)->tx_flags |= SKBTX_DRV_NEEDS_SK_REF; 656 656 657 657 skb->dev = dev; 658 658 skb->sk = sk;
+3 -3
net/core/dev.c
··· 1902 1902 1903 1903 /* 1904 1904 * Try to orphan skb early, right before transmission by the device. 1905 - * We cannot orphan skb if tx timestamp is requested, since 1906 - * drivers need to call skb_tstamp_tx() to send the timestamp. 1905 + * We cannot orphan skb if tx timestamp is requested or the sk-reference 1906 + * is needed on driver level for other reasons, e.g. see net/can/raw.c 1907 1907 */ 1908 1908 static inline void skb_orphan_try(struct sk_buff *skb) 1909 1909 { 1910 1910 struct sock *sk = skb->sk; 1911 1911 1912 - if (sk && !skb_tx(skb)->flags) { 1912 + if (sk && !skb_shinfo(skb)->tx_flags) { 1913 1913 /* skb_tx_hash() wont be able to get sk. 1914 1914 * We copy sk_hash into skb->rxhash 1915 1915 */
+1 -1
net/core/skbuff.c
··· 3016 3016 } else { 3017 3017 /* 3018 3018 * no hardware time stamps available, 3019 - * so keep the skb_shared_tx and only 3019 + * so keep the shared tx_flags and only 3020 3020 * store software time stamp 3021 3021 */ 3022 3022 skb->tstamp = ktime_get_real();
+2 -2
net/ipv4/icmp.c
··· 379 379 inet->tos = ip_hdr(skb)->tos; 380 380 daddr = ipc.addr = rt->rt_src; 381 381 ipc.opt = NULL; 382 - ipc.shtx.flags = 0; 382 + ipc.tx_flags = 0; 383 383 if (icmp_param->replyopts.optlen) { 384 384 ipc.opt = &icmp_param->replyopts; 385 385 if (ipc.opt->srr) ··· 538 538 inet_sk(sk)->tos = tos; 539 539 ipc.addr = iph->saddr; 540 540 ipc.opt = &icmp_param.replyopts; 541 - ipc.shtx.flags = 0; 541 + ipc.tx_flags = 0; 542 542 543 543 { 544 544 struct flowi fl = {
+3 -3
net/ipv4/ip_output.c
··· 953 953 else 954 954 /* only the initial fragment is 955 955 time stamped */ 956 - ipc->shtx.flags = 0; 956 + ipc->tx_flags = 0; 957 957 } 958 958 if (skb == NULL) 959 959 goto error; ··· 964 964 skb->ip_summed = csummode; 965 965 skb->csum = 0; 966 966 skb_reserve(skb, hh_len); 967 - *skb_tx(skb) = ipc->shtx; 967 + skb_shinfo(skb)->tx_flags = ipc->tx_flags; 968 968 969 969 /* 970 970 * Find where to start putting bytes. ··· 1384 1384 1385 1385 daddr = ipc.addr = rt->rt_src; 1386 1386 ipc.opt = NULL; 1387 - ipc.shtx.flags = 0; 1387 + ipc.tx_flags = 0; 1388 1388 1389 1389 if (replyopts.opt.optlen) { 1390 1390 ipc.opt = &replyopts.opt;
+1 -1
net/ipv4/raw.c
··· 505 505 506 506 ipc.addr = inet->inet_saddr; 507 507 ipc.opt = NULL; 508 - ipc.shtx.flags = 0; 508 + ipc.tx_flags = 0; 509 509 ipc.oif = sk->sk_bound_dev_if; 510 510 511 511 if (msg->msg_controllen) {
+2 -2
net/ipv4/udp.c
··· 797 797 return -EOPNOTSUPP; 798 798 799 799 ipc.opt = NULL; 800 - ipc.shtx.flags = 0; 800 + ipc.tx_flags = 0; 801 801 802 802 if (up->pending) { 803 803 /* ··· 845 845 ipc.addr = inet->inet_saddr; 846 846 847 847 ipc.oif = sk->sk_bound_dev_if; 848 - err = sock_tx_timestamp(msg, sk, &ipc.shtx); 848 + err = sock_tx_timestamp(sk, &ipc.tx_flags); 849 849 if (err) 850 850 return err; 851 851 if (msg->msg_controllen) {
+2 -2
net/packet/af_packet.c
··· 488 488 skb->dev = dev; 489 489 skb->priority = sk->sk_priority; 490 490 skb->mark = sk->sk_mark; 491 - err = sock_tx_timestamp(msg, sk, skb_tx(skb)); 491 + err = sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags); 492 492 if (err < 0) 493 493 goto out_unlock; 494 494 ··· 1209 1209 err = skb_copy_datagram_from_iovec(skb, offset, msg->msg_iov, 0, len); 1210 1210 if (err) 1211 1211 goto out_free; 1212 - err = sock_tx_timestamp(msg, sk, skb_tx(skb)); 1212 + err = sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags); 1213 1213 if (err < 0) 1214 1214 goto out_free; 1215 1215
+4 -5
net/socket.c
··· 535 535 } 536 536 EXPORT_SYMBOL(sock_release); 537 537 538 - int sock_tx_timestamp(struct msghdr *msg, struct sock *sk, 539 - union skb_shared_tx *shtx) 538 + int sock_tx_timestamp(struct sock *sk, __u8 *tx_flags) 540 539 { 541 - shtx->flags = 0; 540 + *tx_flags = 0; 542 541 if (sock_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE)) 543 - shtx->hardware = 1; 542 + *tx_flags |= SKBTX_HW_TSTAMP; 544 543 if (sock_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE)) 545 - shtx->software = 1; 544 + *tx_flags |= SKBTX_SW_TSTAMP; 546 545 return 0; 547 546 } 548 547 EXPORT_SYMBOL(sock_tx_timestamp);