Skip to content

Commit 9a1654b

Browse files
Jarek Poplawskidavem330
authored andcommitted
net: Optimize hard_start_xmit() return checking
Recent changes in the TX error propagation require additional checking and masking of values returned from hard_start_xmit(), mainly to separate cases where skb was consumed. This aim can be simplified by changing the order of NETDEV_TX and NET_XMIT codes, because the latter are treated similarly to negative (ERRNO) values. After this change much simpler dev_xmit_complete() is also used in sch_direct_xmit(), so it is moved to netdevice.h. Additionally NET_RX definitions in netdevice.h are moved up from between TX codes to avoid confusion while reading the TX comment. Signed-off-by: Jarek Poplawski <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent cb43e23 commit 9a1654b

File tree

3 files changed

+35
-47
lines changed

3 files changed

+35
-47
lines changed

include/linux/netdevice.h

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ struct wireless_dev;
6363
#define HAVE_FREE_NETDEV /* free_netdev() */
6464
#define HAVE_NETDEV_PRIV /* netdev_priv() */
6565

66+
/* Backlog congestion levels */
67+
#define NET_RX_SUCCESS 0 /* keep 'em coming, baby */
68+
#define NET_RX_DROP 1 /* packet dropped */
69+
6670
/*
6771
* Transmit return codes: transmit return codes originate from three different
6872
* namespaces:
@@ -82,14 +86,10 @@ struct wireless_dev;
8286

8387
/* qdisc ->enqueue() return codes. */
8488
#define NET_XMIT_SUCCESS 0x00
85-
#define NET_XMIT_DROP 0x10 /* skb dropped */
86-
#define NET_XMIT_CN 0x20 /* congestion notification */
87-
#define NET_XMIT_POLICED 0x30 /* skb is shot by police */
88-
#define NET_XMIT_MASK 0xf0 /* qdisc flags in net/sch_generic.h */
89-
90-
/* Backlog congestion levels */
91-
#define NET_RX_SUCCESS 0 /* keep 'em coming, baby */
92-
#define NET_RX_DROP 1 /* packet dropped */
89+
#define NET_XMIT_DROP 0x01 /* skb dropped */
90+
#define NET_XMIT_CN 0x02 /* congestion notification */
91+
#define NET_XMIT_POLICED 0x03 /* skb is shot by police */
92+
#define NET_XMIT_MASK 0x0f /* qdisc flags in net/sch_generic.h */
9393

9494
/* NET_XMIT_CN is special. It does not guarantee that this packet is lost. It
9595
* indicates that the device will soon be dropping packets, or already drops
@@ -98,16 +98,34 @@ struct wireless_dev;
9898
#define net_xmit_errno(e) ((e) != NET_XMIT_CN ? -ENOBUFS : 0)
9999

100100
/* Driver transmit return codes */
101-
#define NETDEV_TX_MASK 0xf
101+
#define NETDEV_TX_MASK 0xf0
102102

103103
enum netdev_tx {
104104
__NETDEV_TX_MIN = INT_MIN, /* make sure enum is signed */
105-
NETDEV_TX_OK = 0, /* driver took care of packet */
106-
NETDEV_TX_BUSY = 1, /* driver tx path was busy*/
107-
NETDEV_TX_LOCKED = 2, /* driver tx lock was already taken */
105+
NETDEV_TX_OK = 0x00, /* driver took care of packet */
106+
NETDEV_TX_BUSY = 0x10, /* driver tx path was busy*/
107+
NETDEV_TX_LOCKED = 0x20, /* driver tx lock was already taken */
108108
};
109109
typedef enum netdev_tx netdev_tx_t;
110110

111+
/*
112+
* Current order: NETDEV_TX_MASK > NET_XMIT_MASK >= 0 is significant;
113+
* hard_start_xmit() return < NET_XMIT_MASK means skb was consumed.
114+
*/
115+
static inline bool dev_xmit_complete(int rc)
116+
{
117+
/*
118+
* Positive cases with an skb consumed by a driver:
119+
* - successful transmission (rc == NETDEV_TX_OK)
120+
* - error while transmitting (rc < 0)
121+
* - error while queueing to a different device (rc & NET_XMIT_MASK)
122+
*/
123+
if (likely(rc < NET_XMIT_MASK))
124+
return true;
125+
126+
return false;
127+
}
128+
111129
#endif
112130

113131
#define MAX_ADDR_LEN 32 /* Largest hardware address length */

net/core/dev.c

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1924,23 +1924,6 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
19241924
return rc;
19251925
}
19261926

1927-
static inline bool dev_xmit_complete(int rc)
1928-
{
1929-
/* successful transmission */
1930-
if (rc == NETDEV_TX_OK)
1931-
return true;
1932-
1933-
/* error while transmitting, driver consumed skb */
1934-
if (rc < 0)
1935-
return true;
1936-
1937-
/* error while queueing to a different device, driver consumed skb */
1938-
if (rc & NET_XMIT_MASK)
1939-
return true;
1940-
1941-
return false;
1942-
}
1943-
19441927
/**
19451928
* dev_queue_xmit - transmit a buffer
19461929
* @skb: buffer to transmit

net/sched/sch_generic.c

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -119,39 +119,26 @@ int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
119119
spin_unlock(root_lock);
120120

121121
HARD_TX_LOCK(dev, txq, smp_processor_id());
122-
if (!netif_tx_queue_stopped(txq) &&
123-
!netif_tx_queue_frozen(txq)) {
122+
if (!netif_tx_queue_stopped(txq) && !netif_tx_queue_frozen(txq))
124123
ret = dev_hard_start_xmit(skb, dev, txq);
125124

126-
/* an error implies that the skb was consumed */
127-
if (ret < 0)
128-
ret = NETDEV_TX_OK;
129-
/* all NET_XMIT codes map to NETDEV_TX_OK */
130-
ret &= ~NET_XMIT_MASK;
131-
}
132125
HARD_TX_UNLOCK(dev, txq);
133126

134127
spin_lock(root_lock);
135128

136-
switch (ret) {
137-
case NETDEV_TX_OK:
138-
/* Driver sent out skb successfully */
129+
if (dev_xmit_complete(ret)) {
130+
/* Driver sent out skb successfully or skb was consumed */
139131
ret = qdisc_qlen(q);
140-
break;
141-
142-
case NETDEV_TX_LOCKED:
132+
} else if (ret == NETDEV_TX_LOCKED) {
143133
/* Driver try lock failed */
144134
ret = handle_dev_cpu_collision(skb, txq, q);
145-
break;
146-
147-
default:
135+
} else {
148136
/* Driver returned NETDEV_TX_BUSY - requeue skb */
149137
if (unlikely (ret != NETDEV_TX_BUSY && net_ratelimit()))
150138
printk(KERN_WARNING "BUG %s code %d qlen %d\n",
151139
dev->name, ret, q->q.qlen);
152140

153141
ret = dev_requeue_skb(skb, q);
154-
break;
155142
}
156143

157144
if (ret && (netif_tx_queue_stopped(txq) ||

0 commit comments

Comments
 (0)