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