aboutsummaryrefslogtreecommitdiffstats
path: root/net/rxrpc/input.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2018-10-04 06:10:51 -0400
committerDavid Howells <dhowells@redhat.com>2018-10-08 10:45:18 -0400
commit5271953cad31b97dea80f848c16e96ad66401199 (patch)
treed7ebc9c86a13557a6802fab23b7b1a25a708d6b5 /net/rxrpc/input.c
parent2cfa2271604bb26e75b828d38f357ed084464795 (diff)
rxrpc: Use the UDP encap_rcv hook
Use the UDP encap_rcv hook to cut the bit out of the rxrpc packet reception in which a packet is placed onto the UDP receive queue and then immediately removed again by rxrpc. Going via the queue in this manner seems like it should be unnecessary. This does, however, require the invention of a value to place in encap_type as that's one of the conditions to switch packets out to the encap_rcv hook. Possibly the value doesn't actually matter for anything other than sockopts on the UDP socket, which aren't accessible outside of rxrpc anyway. This seems to cut a bit of time out of the time elapsed between each sk_buff being timestamped and turning up in rxrpc (the final number in the following trace excerpts). I measured this by making the rxrpc_rx_packet trace point print the time elapsed between the skb being timestamped and the current time (in ns), e.g.: ... 424.278721: rxrpc_rx_packet: ... ACK 25026 So doing a 512MiB DIO read from my test server, with an unmodified kernel: N min max sum mean stddev 27605 2626 7581 7.83992e+07 2840.04 181.029 and with the patch applied: N min max sum mean stddev 27547 1895 12165 6.77461e+07 2459.29 255.02 Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'net/rxrpc/input.c')
-rw-r--r--net/rxrpc/input.c50
1 files changed, 12 insertions, 38 deletions
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c
index c3114fa66c92..1866aeef2284 100644
--- a/net/rxrpc/input.c
+++ b/net/rxrpc/input.c
@@ -1121,7 +1121,7 @@ int rxrpc_extract_header(struct rxrpc_skb_priv *sp, struct sk_buff *skb)
1121 * shut down and the local endpoint from going away, thus sk_user_data will not 1121 * shut down and the local endpoint from going away, thus sk_user_data will not
1122 * be cleared until this function returns. 1122 * be cleared until this function returns.
1123 */ 1123 */
1124void rxrpc_input_packet(struct sock *udp_sk, struct sk_buff *skb) 1124int rxrpc_input_packet(struct sock *udp_sk, struct sk_buff *skb)
1125{ 1125{
1126 struct rxrpc_connection *conn; 1126 struct rxrpc_connection *conn;
1127 struct rxrpc_channel *chan; 1127 struct rxrpc_channel *chan;
@@ -1135,6 +1135,13 @@ void rxrpc_input_packet(struct sock *udp_sk, struct sk_buff *skb)
1135 1135
1136 _enter("%p", udp_sk); 1136 _enter("%p", udp_sk);
1137 1137
1138 if (skb->tstamp == 0)
1139 skb->tstamp = ktime_get_real();
1140
1141 rxrpc_new_skb(skb, rxrpc_skb_rx_received);
1142
1143 skb_pull(skb, sizeof(struct udphdr));
1144
1138 /* The UDP protocol already released all skb resources; 1145 /* The UDP protocol already released all skb resources;
1139 * we are free to add our own data there. 1146 * we are free to add our own data there.
1140 */ 1147 */
@@ -1148,8 +1155,8 @@ void rxrpc_input_packet(struct sock *udp_sk, struct sk_buff *skb)
1148 static int lose; 1155 static int lose;
1149 if ((lose++ & 7) == 7) { 1156 if ((lose++ & 7) == 7) {
1150 trace_rxrpc_rx_lose(sp); 1157 trace_rxrpc_rx_lose(sp);
1151 rxrpc_lose_skb(skb, rxrpc_skb_rx_lost); 1158 rxrpc_free_skb(skb, rxrpc_skb_rx_lost);
1152 return; 1159 return 0;
1153 } 1160 }
1154 } 1161 }
1155 1162
@@ -1332,7 +1339,7 @@ discard:
1332 rxrpc_free_skb(skb, rxrpc_skb_rx_freed); 1339 rxrpc_free_skb(skb, rxrpc_skb_rx_freed);
1333out: 1340out:
1334 trace_rxrpc_rx_done(0, 0); 1341 trace_rxrpc_rx_done(0, 0);
1335 return; 1342 return 0;
1336 1343
1337out_unlock: 1344out_unlock:
1338 rcu_read_unlock(); 1345 rcu_read_unlock();
@@ -1371,38 +1378,5 @@ reject_packet:
1371 trace_rxrpc_rx_done(skb->mark, skb->priority); 1378 trace_rxrpc_rx_done(skb->mark, skb->priority);
1372 rxrpc_reject_packet(local, skb); 1379 rxrpc_reject_packet(local, skb);
1373 _leave(" [badmsg]"); 1380 _leave(" [badmsg]");
1374} 1381 return 0;
1375
1376void rxrpc_data_ready(struct sock *udp_sk)
1377{
1378 struct sk_buff *skb;
1379 int ret;
1380
1381 for (;;) {
1382 skb = skb_recv_udp(udp_sk, 0, 1, &ret);
1383 if (!skb) {
1384 if (ret == -EAGAIN)
1385 return;
1386
1387 /* If there was a transmission failure, we get an error
1388 * here that we need to ignore.
1389 */
1390 _debug("UDP socket error %d", ret);
1391 continue;
1392 }
1393
1394 rxrpc_new_skb(skb, rxrpc_skb_rx_received);
1395
1396 /* we'll probably need to checksum it (didn't call sock_recvmsg) */
1397 if (skb_checksum_complete(skb)) {
1398 rxrpc_free_skb(skb, rxrpc_skb_rx_freed);
1399 __UDP_INC_STATS(sock_net(udp_sk), UDP_MIB_INERRORS, 0);
1400 _debug("csum failed");
1401 continue;
1402 }
1403
1404 __UDP_INC_STATS(sock_net(udp_sk), UDP_MIB_INDATAGRAMS, 0);
1405
1406 rxrpc_input_packet(udp_sk, skb);
1407 }
1408} 1382}