aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--Documentation/networking/rxrpc.txt11
-rw-r--r--fs/afs/rxrpc.c1
-rw-r--r--include/net/af_rxrpc.h1
-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
8 files changed, 28 insertions, 4 deletions
diff --git a/Documentation/networking/rxrpc.txt b/Documentation/networking/rxrpc.txt
index ff035a6418e3..180e07d956a7 100644
--- a/Documentation/networking/rxrpc.txt
+++ b/Documentation/networking/rxrpc.txt
@@ -796,7 +796,9 @@ The kernel interface functions are as follows:
796 s64 tx_total_len, 796 s64 tx_total_len,
797 gfp_t gfp, 797 gfp_t gfp,
798 rxrpc_notify_rx_t notify_rx, 798 rxrpc_notify_rx_t notify_rx,
799 bool upgrade); 799 bool upgrade,
800 bool intr,
801 unsigned int debug_id);
800 802
801 This allocates the infrastructure to make a new RxRPC call and assigns 803 This allocates the infrastructure to make a new RxRPC call and assigns
802 call and connection numbers. The call will be made on the UDP port that 804 call and connection numbers. The call will be made on the UDP port that
@@ -824,6 +826,13 @@ The kernel interface functions are as follows:
824 the server upgrade the service to a better one. The resultant service ID 826 the server upgrade the service to a better one. The resultant service ID
825 is returned by rxrpc_kernel_recv_data(). 827 is returned by rxrpc_kernel_recv_data().
826 828
829 intr should be set to true if the call should be interruptible. If this
830 is not set, this function may not return until a channel has been
831 allocated; if it is set, the function may return -ERESTARTSYS.
832
833 debug_id is the call debugging ID to be used for tracing. This can be
834 obtained by atomically incrementing rxrpc_debug_id.
835
827 If this function is successful, an opaque reference to the RxRPC call is 836 If this function is successful, an opaque reference to the RxRPC call is
828 returned. The caller now holds a reference on this and it must be 837 returned. The caller now holds a reference on this and it must be
829 properly ended. 838 properly ended.
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c
index 4974defb4592..87763379952d 100644
--- a/fs/afs/rxrpc.c
+++ b/fs/afs/rxrpc.c
@@ -417,6 +417,7 @@ void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp)
417 afs_wake_up_async_call : 417 afs_wake_up_async_call :
418 afs_wake_up_call_waiter), 418 afs_wake_up_call_waiter),
419 call->upgrade, 419 call->upgrade,
420 true,
420 call->debug_id); 421 call->debug_id);
421 if (IS_ERR(rxcall)) { 422 if (IS_ERR(rxcall)) {
422 ret = PTR_ERR(rxcall); 423 ret = PTR_ERR(rxcall);
diff --git a/include/net/af_rxrpc.h b/include/net/af_rxrpc.h
index c04602ca4a55..93358bfc0e1b 100644
--- a/include/net/af_rxrpc.h
+++ b/include/net/af_rxrpc.h
@@ -45,6 +45,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *,
45 gfp_t, 45 gfp_t,
46 rxrpc_notify_rx_t, 46 rxrpc_notify_rx_t,
47 bool, 47 bool,
48 bool,
48 unsigned int); 49 unsigned int);
49int rxrpc_kernel_send_data(struct socket *, struct rxrpc_call *, 50int rxrpc_kernel_send_data(struct socket *, struct rxrpc_call *,
50 struct msghdr *, size_t, 51 struct msghdr *, size_t,
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,