Commit b960a34b authored by David Howells's avatar David Howells
Browse files

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: default avatarDavid Howells <dhowells@redhat.com>
parent 0ab4c959
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -796,7 +796,9 @@ The kernel interface functions are as follows:
				s64 tx_total_len,
				gfp_t gfp,
				rxrpc_notify_rx_t notify_rx,
				bool upgrade);
				bool upgrade,
				bool intr,
				unsigned int debug_id);

     This allocates the infrastructure to make a new RxRPC call and assigns
     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:
     the server upgrade the service to a better one.  The resultant service ID
     is returned by rxrpc_kernel_recv_data().

     intr should be set to true if the call should be interruptible.  If this
     is not set, this function may not return until a channel has been
     allocated; if it is set, the function may return -ERESTARTSYS.

     debug_id is the call debugging ID to be used for tracing.  This can be
     obtained by atomically incrementing rxrpc_debug_id.

     If this function is successful, an opaque reference to the RxRPC call is
     returned.  The caller now holds a reference on this and it must be
     properly ended.
+1 −0
Original line number Diff line number Diff line
@@ -417,6 +417,7 @@ void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp)
					  afs_wake_up_async_call :
					  afs_wake_up_call_waiter),
					 call->upgrade,
					 true,
					 call->debug_id);
	if (IS_ERR(rxcall)) {
		ret = PTR_ERR(rxcall);
+1 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *,
					   gfp_t,
					   rxrpc_notify_rx_t,
					   bool,
					   bool,
					   unsigned int);
int rxrpc_kernel_send_data(struct socket *, struct rxrpc_call *,
			   struct msghdr *, size_t,
+3 −0
Original line number Diff line number Diff line
@@ -270,6 +270,7 @@ static int rxrpc_listen(struct socket *sock, int backlog)
 * @gfp: The allocation constraints
 * @notify_rx: Where to send notifications instead of socket queue
 * @upgrade: Request service upgrade for call
 * @intr: The call is interruptible
 * @debug_id: The debug ID for tracing to be assigned to the call
 *
 * 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,
					   gfp_t gfp,
					   rxrpc_notify_rx_t notify_rx,
					   bool upgrade,
					   bool intr,
					   unsigned int debug_id)
{
	struct rxrpc_conn_parameters cp;
@@ -311,6 +313,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
	memset(&p, 0, sizeof(p));
	p.user_call_ID = user_call_ID;
	p.tx_total_len = tx_total_len;
	p.intr = intr;

	memset(&cp, 0, sizeof(cp));
	cp.local		= rx->local;
+2 −0
Original line number Diff line number Diff line
@@ -482,6 +482,7 @@ enum rxrpc_call_flag {
	RXRPC_CALL_BEGAN_RX_TIMER,	/* We began the expect_rx_by timer */
	RXRPC_CALL_RX_HEARD,		/* The peer responded at least once to this call */
	RXRPC_CALL_RX_UNDERRUN,		/* Got data underrun */
	RXRPC_CALL_IS_INTR,		/* The call is interruptible */
};

/*
@@ -711,6 +712,7 @@ struct rxrpc_call_params {
		u32		normal;		/* Max time since last call packet (msec) */
	} timeouts;
	u8			nr_timeouts;	/* Number of timeouts specified */
	bool			intr;		/* The call is interruptible */
};

struct rxrpc_send_params {
Loading