Commit 9a1654ba0b50402a6bd03c7b0fe9b0200a5ea7b1
Committed by
David S. Miller
1 parent
cb43e23435
Exists in
master
and in
7 other branches
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 <jarkao2@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 3 changed files with 35 additions and 47 deletions Side-by-side Diff
include/linux/netdevice.h
... | ... | @@ -63,6 +63,10 @@ |
63 | 63 | #define HAVE_FREE_NETDEV /* free_netdev() */ |
64 | 64 | #define HAVE_NETDEV_PRIV /* netdev_priv() */ |
65 | 65 | |
66 | +/* Backlog congestion levels */ | |
67 | +#define NET_RX_SUCCESS 0 /* keep 'em coming, baby */ | |
68 | +#define NET_RX_DROP 1 /* packet dropped */ | |
69 | + | |
66 | 70 | /* |
67 | 71 | * Transmit return codes: transmit return codes originate from three different |
68 | 72 | * namespaces: |
69 | 73 | |
... | ... | @@ -82,15 +86,11 @@ |
82 | 86 | |
83 | 87 | /* qdisc ->enqueue() return codes. */ |
84 | 88 | #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 | +#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 */ | |
89 | 93 | |
90 | -/* Backlog congestion levels */ | |
91 | -#define NET_RX_SUCCESS 0 /* keep 'em coming, baby */ | |
92 | -#define NET_RX_DROP 1 /* packet dropped */ | |
93 | - | |
94 | 94 | /* NET_XMIT_CN is special. It does not guarantee that this packet is lost. It |
95 | 95 | * indicates that the device will soon be dropping packets, or already drops |
96 | 96 | * some packets of the same priority; prompting us to send less aggressively. */ |
97 | 97 | |
98 | 98 | |
... | ... | @@ -98,15 +98,33 @@ |
98 | 98 | #define net_xmit_errno(e) ((e) != NET_XMIT_CN ? -ENOBUFS : 0) |
99 | 99 | |
100 | 100 | /* Driver transmit return codes */ |
101 | -#define NETDEV_TX_MASK 0xf | |
101 | +#define NETDEV_TX_MASK 0xf0 | |
102 | 102 | |
103 | 103 | enum netdev_tx { |
104 | 104 | __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 */ | |
108 | 108 | }; |
109 | 109 | typedef enum netdev_tx netdev_tx_t; |
110 | + | |
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 | +} | |
110 | 128 | |
111 | 129 | #endif |
112 | 130 |
net/core/dev.c
... | ... | @@ -1924,23 +1924,6 @@ |
1924 | 1924 | return rc; |
1925 | 1925 | } |
1926 | 1926 | |
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 | - | |
1944 | 1927 | /** |
1945 | 1928 | * dev_queue_xmit - transmit a buffer |
1946 | 1929 | * @skb: buffer to transmit |
net/sched/sch_generic.c
... | ... | @@ -119,39 +119,26 @@ |
119 | 119 | spin_unlock(root_lock); |
120 | 120 | |
121 | 121 | 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)) | |
124 | 123 | ret = dev_hard_start_xmit(skb, dev, txq); |
125 | 124 | |
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 | - } | |
132 | 125 | HARD_TX_UNLOCK(dev, txq); |
133 | 126 | |
134 | 127 | spin_lock(root_lock); |
135 | 128 | |
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 */ | |
139 | 131 | ret = qdisc_qlen(q); |
140 | - break; | |
141 | - | |
142 | - case NETDEV_TX_LOCKED: | |
132 | + } else if (ret == NETDEV_TX_LOCKED) { | |
143 | 133 | /* Driver try lock failed */ |
144 | 134 | ret = handle_dev_cpu_collision(skb, txq, q); |
145 | - break; | |
146 | - | |
147 | - default: | |
135 | + } else { | |
148 | 136 | /* Driver returned NETDEV_TX_BUSY - requeue skb */ |
149 | 137 | if (unlikely (ret != NETDEV_TX_BUSY && net_ratelimit())) |
150 | 138 | printk(KERN_WARNING "BUG %s code %d qlen %d\n", |
151 | 139 | dev->name, ret, q->q.qlen); |
152 | 140 | |
153 | 141 | ret = dev_requeue_skb(skb, q); |
154 | - break; | |
155 | 142 | } |
156 | 143 | |
157 | 144 | if (ret && (netif_tx_queue_stopped(txq) || |