summaryrefslogtreecommitdiffstats
path: root/net/rxrpc/recvmsg.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2019-11-04 05:32:04 -0500
committerThomas Gleixner <tglx@linutronix.de>2019-11-04 05:32:04 -0500
commitca8888d7ae6fa18454c9e4f192c56bc6c8ca9b33 (patch)
treec2b86b162f8fc2adf8a98f7e074500bee155d603 /net/rxrpc/recvmsg.c
parentdb616173d787395787ecc93eef075fa975227b10 (diff)
parenta99d8080aaf358d5d23581244e5da23b35e340b9 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux
to pick up the KVM fix which is required for the NX series.
Diffstat (limited to 'net/rxrpc/recvmsg.c')
-rw-r--r--net/rxrpc/recvmsg.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c
index a4090797c9b2..8578c39ec839 100644
--- a/net/rxrpc/recvmsg.c
+++ b/net/rxrpc/recvmsg.c
@@ -267,11 +267,13 @@ static int rxrpc_verify_packet(struct rxrpc_call *call, struct sk_buff *skb,
267 */ 267 */
268static int rxrpc_locate_data(struct rxrpc_call *call, struct sk_buff *skb, 268static int rxrpc_locate_data(struct rxrpc_call *call, struct sk_buff *skb,
269 u8 *_annotation, 269 u8 *_annotation,
270 unsigned int *_offset, unsigned int *_len) 270 unsigned int *_offset, unsigned int *_len,
271 bool *_last)
271{ 272{
272 struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 273 struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
273 unsigned int offset = sizeof(struct rxrpc_wire_header); 274 unsigned int offset = sizeof(struct rxrpc_wire_header);
274 unsigned int len; 275 unsigned int len;
276 bool last = false;
275 int ret; 277 int ret;
276 u8 annotation = *_annotation; 278 u8 annotation = *_annotation;
277 u8 subpacket = annotation & RXRPC_RX_ANNO_SUBPACKET; 279 u8 subpacket = annotation & RXRPC_RX_ANNO_SUBPACKET;
@@ -281,6 +283,8 @@ static int rxrpc_locate_data(struct rxrpc_call *call, struct sk_buff *skb,
281 len = skb->len - offset; 283 len = skb->len - offset;
282 if (subpacket < sp->nr_subpackets - 1) 284 if (subpacket < sp->nr_subpackets - 1)
283 len = RXRPC_JUMBO_DATALEN; 285 len = RXRPC_JUMBO_DATALEN;
286 else if (sp->rx_flags & RXRPC_SKB_INCL_LAST)
287 last = true;
284 288
285 if (!(annotation & RXRPC_RX_ANNO_VERIFIED)) { 289 if (!(annotation & RXRPC_RX_ANNO_VERIFIED)) {
286 ret = rxrpc_verify_packet(call, skb, annotation, offset, len); 290 ret = rxrpc_verify_packet(call, skb, annotation, offset, len);
@@ -291,6 +295,7 @@ static int rxrpc_locate_data(struct rxrpc_call *call, struct sk_buff *skb,
291 295
292 *_offset = offset; 296 *_offset = offset;
293 *_len = len; 297 *_len = len;
298 *_last = last;
294 call->security->locate_data(call, skb, _offset, _len); 299 call->security->locate_data(call, skb, _offset, _len);
295 return 0; 300 return 0;
296} 301}
@@ -309,7 +314,7 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call,
309 rxrpc_serial_t serial; 314 rxrpc_serial_t serial;
310 rxrpc_seq_t hard_ack, top, seq; 315 rxrpc_seq_t hard_ack, top, seq;
311 size_t remain; 316 size_t remain;
312 bool last; 317 bool rx_pkt_last;
313 unsigned int rx_pkt_offset, rx_pkt_len; 318 unsigned int rx_pkt_offset, rx_pkt_len;
314 int ix, copy, ret = -EAGAIN, ret2; 319 int ix, copy, ret = -EAGAIN, ret2;
315 320
@@ -319,6 +324,7 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call,
319 324
320 rx_pkt_offset = call->rx_pkt_offset; 325 rx_pkt_offset = call->rx_pkt_offset;
321 rx_pkt_len = call->rx_pkt_len; 326 rx_pkt_len = call->rx_pkt_len;
327 rx_pkt_last = call->rx_pkt_last;
322 328
323 if (call->state >= RXRPC_CALL_SERVER_ACK_REQUEST) { 329 if (call->state >= RXRPC_CALL_SERVER_ACK_REQUEST) {
324 seq = call->rx_hard_ack; 330 seq = call->rx_hard_ack;
@@ -329,6 +335,7 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call,
329 /* Barriers against rxrpc_input_data(). */ 335 /* Barriers against rxrpc_input_data(). */
330 hard_ack = call->rx_hard_ack; 336 hard_ack = call->rx_hard_ack;
331 seq = hard_ack + 1; 337 seq = hard_ack + 1;
338
332 while (top = smp_load_acquire(&call->rx_top), 339 while (top = smp_load_acquire(&call->rx_top),
333 before_eq(seq, top) 340 before_eq(seq, top)
334 ) { 341 ) {
@@ -356,7 +363,8 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call,
356 if (rx_pkt_offset == 0) { 363 if (rx_pkt_offset == 0) {
357 ret2 = rxrpc_locate_data(call, skb, 364 ret2 = rxrpc_locate_data(call, skb,
358 &call->rxtx_annotations[ix], 365 &call->rxtx_annotations[ix],
359 &rx_pkt_offset, &rx_pkt_len); 366 &rx_pkt_offset, &rx_pkt_len,
367 &rx_pkt_last);
360 trace_rxrpc_recvmsg(call, rxrpc_recvmsg_next, seq, 368 trace_rxrpc_recvmsg(call, rxrpc_recvmsg_next, seq,
361 rx_pkt_offset, rx_pkt_len, ret2); 369 rx_pkt_offset, rx_pkt_len, ret2);
362 if (ret2 < 0) { 370 if (ret2 < 0) {
@@ -396,13 +404,12 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call,
396 } 404 }
397 405
398 /* The whole packet has been transferred. */ 406 /* The whole packet has been transferred. */
399 last = sp->hdr.flags & RXRPC_LAST_PACKET;
400 if (!(flags & MSG_PEEK)) 407 if (!(flags & MSG_PEEK))
401 rxrpc_rotate_rx_window(call); 408 rxrpc_rotate_rx_window(call);
402 rx_pkt_offset = 0; 409 rx_pkt_offset = 0;
403 rx_pkt_len = 0; 410 rx_pkt_len = 0;
404 411
405 if (last) { 412 if (rx_pkt_last) {
406 ASSERTCMP(seq, ==, READ_ONCE(call->rx_top)); 413 ASSERTCMP(seq, ==, READ_ONCE(call->rx_top));
407 ret = 1; 414 ret = 1;
408 goto out; 415 goto out;
@@ -415,6 +422,7 @@ out:
415 if (!(flags & MSG_PEEK)) { 422 if (!(flags & MSG_PEEK)) {
416 call->rx_pkt_offset = rx_pkt_offset; 423 call->rx_pkt_offset = rx_pkt_offset;
417 call->rx_pkt_len = rx_pkt_len; 424 call->rx_pkt_len = rx_pkt_len;
425 call->rx_pkt_last = rx_pkt_last;
418 } 426 }
419done: 427done:
420 trace_rxrpc_recvmsg(call, rxrpc_recvmsg_data_return, seq, 428 trace_rxrpc_recvmsg(call, rxrpc_recvmsg_data_return, seq,