summaryrefslogtreecommitdiffstats
path: root/net/rxrpc
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2019-05-09 03:21:21 -0400
committerDavid Howells <dhowells@redhat.com>2019-05-16 11:25:20 -0400
commitb960a34b73e4c1c972623bc2076e24b97588d09e (patch)
treeb7fafd6110ffa1aed594d55097755eea65da5d8d /net/rxrpc
parent0ab4c9594812c4bc5606daf0677ae304bf7ec8c8 (diff)
rxrpc: Allow the kernel to mark a call as being non-interruptible
Allow kernel services using AF_RXRPC to indicate that a call should be non-interruptible. This allows kafs to make things like lock-extension and writeback data storage calls non-interruptible. If this is set, signals will be ignored for operations on that call where possible - such as waiting to get a call channel on an rxrpc connection. It doesn't prevent UDP sendmsg from being interrupted, but that will be handled by packet retransmission. rxrpc_kernel_recv_data() isn't affected by this since that never waits, preferring instead to return -EAGAIN and leave the waiting to the caller. Userspace initiated calls can't be set to be uninterruptible at this time. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'net/rxrpc')
-rw-r--r--net/rxrpc/af_rxrpc.c3
-rw-r--r--net/rxrpc/ar-internal.h2
-rw-r--r--net/rxrpc/call_object.c2
-rw-r--r--net/rxrpc/conn_client.c8
-rw-r--r--net/rxrpc/sendmsg.c4
5 files changed, 16 insertions, 3 deletions
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index 213935fbbbf7..ffde5b187f5d 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -270,6 +270,7 @@ static int rxrpc_listen(struct socket *sock, int backlog)
270 * @gfp: The allocation constraints 270 * @gfp: The allocation constraints
271 * @notify_rx: Where to send notifications instead of socket queue 271 * @notify_rx: Where to send notifications instead of socket queue
272 * @upgrade: Request service upgrade for call 272 * @upgrade: Request service upgrade for call
273 * @intr: The call is interruptible
273 * @debug_id: The debug ID for tracing to be assigned to the call 274 * @debug_id: The debug ID for tracing to be assigned to the call
274 * 275 *
275 * Allow a kernel service to begin a call on the nominated socket. This just 276 * Allow a kernel service to begin a call on the nominated socket. This just
@@ -287,6 +288,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
287 gfp_t gfp, 288 gfp_t gfp,
288 rxrpc_notify_rx_t notify_rx, 289 rxrpc_notify_rx_t notify_rx,
289 bool upgrade, 290 bool upgrade,
291 bool intr,
290 unsigned int debug_id) 292 unsigned int debug_id)
291{ 293{
292 struct rxrpc_conn_parameters cp; 294 struct rxrpc_conn_parameters cp;
@@ -311,6 +313,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
311 memset(&p, 0, sizeof(p)); 313 memset(&p, 0, sizeof(p));
312 p.user_call_ID = user_call_ID; 314 p.user_call_ID = user_call_ID;
313 p.tx_total_len = tx_total_len; 315 p.tx_total_len = tx_total_len;
316 p.intr = intr;
314 317
315 memset(&cp, 0, sizeof(cp)); 318 memset(&cp, 0, sizeof(cp));
316 cp.local = rx->local; 319 cp.local = rx->local;
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index 062ca9dc29b8..07fc1dfa4878 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -482,6 +482,7 @@ enum rxrpc_call_flag {
482 RXRPC_CALL_BEGAN_RX_TIMER, /* We began the expect_rx_by timer */ 482 RXRPC_CALL_BEGAN_RX_TIMER, /* We began the expect_rx_by timer */
483 RXRPC_CALL_RX_HEARD, /* The peer responded at least once to this call */ 483 RXRPC_CALL_RX_HEARD, /* The peer responded at least once to this call */
484 RXRPC_CALL_RX_UNDERRUN, /* Got data underrun */ 484 RXRPC_CALL_RX_UNDERRUN, /* Got data underrun */
485 RXRPC_CALL_IS_INTR, /* The call is interruptible */
485}; 486};
486 487
487/* 488/*
@@ -711,6 +712,7 @@ struct rxrpc_call_params {
711 u32 normal; /* Max time since last call packet (msec) */ 712 u32 normal; /* Max time since last call packet (msec) */
712 } timeouts; 713 } timeouts;
713 u8 nr_timeouts; /* Number of timeouts specified */ 714 u8 nr_timeouts; /* Number of timeouts specified */
715 bool intr; /* The call is interruptible */
714}; 716};
715 717
716struct rxrpc_send_params { 718struct rxrpc_send_params {
diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c
index fe96881a334d..d0ca98d7aef5 100644
--- a/net/rxrpc/call_object.c
+++ b/net/rxrpc/call_object.c
@@ -241,6 +241,8 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
241 return call; 241 return call;
242 } 242 }
243 243
244 if (p->intr)
245 __set_bit(RXRPC_CALL_IS_INTR, &call->flags);
244 call->tx_total_len = p->tx_total_len; 246 call->tx_total_len = p->tx_total_len;
245 trace_rxrpc_call(call, rxrpc_call_new_client, atomic_read(&call->usage), 247 trace_rxrpc_call(call, rxrpc_call_new_client, atomic_read(&call->usage),
246 here, (const void *)p->user_call_ID); 248 here, (const void *)p->user_call_ID);
diff --git a/net/rxrpc/conn_client.c b/net/rxrpc/conn_client.c
index 83797b3949e2..5cf5595a14d8 100644
--- a/net/rxrpc/conn_client.c
+++ b/net/rxrpc/conn_client.c
@@ -656,10 +656,14 @@ static int rxrpc_wait_for_channel(struct rxrpc_call *call, gfp_t gfp)
656 656
657 add_wait_queue_exclusive(&call->waitq, &myself); 657 add_wait_queue_exclusive(&call->waitq, &myself);
658 for (;;) { 658 for (;;) {
659 set_current_state(TASK_INTERRUPTIBLE); 659 if (test_bit(RXRPC_CALL_IS_INTR, &call->flags))
660 set_current_state(TASK_INTERRUPTIBLE);
661 else
662 set_current_state(TASK_UNINTERRUPTIBLE);
660 if (call->call_id) 663 if (call->call_id)
661 break; 664 break;
662 if (signal_pending(current)) { 665 if (test_bit(RXRPC_CALL_IS_INTR, &call->flags) &&
666 signal_pending(current)) {
663 ret = -ERESTARTSYS; 667 ret = -ERESTARTSYS;
664 break; 668 break;
665 } 669 }
diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c
index bec64deb7b0a..45a05d9a27fa 100644
--- a/net/rxrpc/sendmsg.c
+++ b/net/rxrpc/sendmsg.c
@@ -80,7 +80,8 @@ static int rxrpc_wait_for_tx_window_nonintr(struct rxrpc_sock *rx,
80 if (call->state >= RXRPC_CALL_COMPLETE) 80 if (call->state >= RXRPC_CALL_COMPLETE)
81 return call->error; 81 return call->error;
82 82
83 if (timeout == 0 && 83 if (test_bit(RXRPC_CALL_IS_INTR, &call->flags) &&
84 timeout == 0 &&
84 tx_win == tx_start && signal_pending(current)) 85 tx_win == tx_start && signal_pending(current))
85 return -EINTR; 86 return -EINTR;
86 87
@@ -620,6 +621,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len)
620 .call.tx_total_len = -1, 621 .call.tx_total_len = -1,
621 .call.user_call_ID = 0, 622 .call.user_call_ID = 0,
622 .call.nr_timeouts = 0, 623 .call.nr_timeouts = 0,
624 .call.intr = true,
623 .abort_code = 0, 625 .abort_code = 0,
624 .command = RXRPC_CMD_SEND_DATA, 626 .command = RXRPC_CMD_SEND_DATA,
625 .exclusive = false, 627 .exclusive = false,