Skip to content

Commit a387436

Browse files
dhowellsgregkh
authored andcommitted
rxrpc: Pull out certain app callback funcs into an ops table
[ Upstream commit 23738cc ] A number of functions separately furnish an AF_RXRPC socket with callback function pointers into a kernel app (such as the AFS filesystem) that is using it. Replace most of these with an ops table for the entire socket. This makes it easier to add more callback functions. Note that the call incoming data processing callback is retaind as that gets set to different things, depending on the type of op. Signed-off-by: David Howells <dhowells@redhat.com> cc: Marc Dionne <marc.dionne@auristor.com> cc: Simon Horman <horms@kernel.org> cc: linux-afs@lists.infradead.org Link: https://patch.msgid.link/20250411095303.2316168-3-dhowells@redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Stable-dep-of: dc17538 ("rxrpc: serialize kernel accept preallocation with socket teardown") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 93a1a59 commit a387436

6 files changed

Lines changed: 55 additions & 48 deletions

File tree

fs/afs/rxrpc.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,15 @@ static void afs_wake_up_async_call(struct sock *, struct rxrpc_call *, unsigned
2424
static void afs_process_async_call(struct work_struct *);
2525
static void afs_rx_new_call(struct sock *, struct rxrpc_call *, unsigned long);
2626
static void afs_rx_discard_new_call(struct rxrpc_call *, unsigned long);
27+
static void afs_rx_attach(struct rxrpc_call *rxcall, unsigned long user_call_ID);
2728
static int afs_deliver_cm_op_id(struct afs_call *);
2829

30+
static const struct rxrpc_kernel_ops afs_rxrpc_callback_ops = {
31+
.notify_new_call = afs_rx_new_call,
32+
.discard_new_call = afs_rx_discard_new_call,
33+
.user_attach_call = afs_rx_attach,
34+
};
35+
2936
/* asynchronous incoming call initial processing */
3037
static const struct afs_call_type afs_RXCMxxxx = {
3138
.name = "CB.xxxx",
@@ -84,8 +91,7 @@ int afs_open_socket(struct afs_net *net)
8491
* it sends back to us.
8592
*/
8693

87-
rxrpc_kernel_new_call_notification(socket, afs_rx_new_call,
88-
afs_rx_discard_new_call);
94+
rxrpc_kernel_set_notifications(socket, &afs_rxrpc_callback_ops);
8995

9096
ret = kernel_listen(socket, INT_MAX);
9197
if (ret < 0)
@@ -758,7 +764,6 @@ void afs_charge_preallocation(struct work_struct *work)
758764

759765
if (rxrpc_kernel_charge_accept(net->socket,
760766
afs_wake_up_async_call,
761-
afs_rx_attach,
762767
(unsigned long)call,
763768
GFP_KERNEL,
764769
call->debug_id) < 0)

include/net/af_rxrpc.h

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,23 @@ enum rxrpc_interruptibility {
2929
*/
3030
extern atomic_t rxrpc_debug_id;
3131

32+
/*
33+
* Operations table for rxrpc to call out to a kernel application (e.g. kAFS).
34+
*/
35+
struct rxrpc_kernel_ops {
36+
void (*notify_new_call)(struct sock *sk, struct rxrpc_call *call,
37+
unsigned long user_call_ID);
38+
void (*discard_new_call)(struct rxrpc_call *call, unsigned long user_call_ID);
39+
void (*user_attach_call)(struct rxrpc_call *call, unsigned long user_call_ID);
40+
};
41+
3242
typedef void (*rxrpc_notify_rx_t)(struct sock *, struct rxrpc_call *,
3343
unsigned long);
3444
typedef void (*rxrpc_notify_end_tx_t)(struct sock *, struct rxrpc_call *,
3545
unsigned long);
36-
typedef void (*rxrpc_notify_new_call_t)(struct sock *, struct rxrpc_call *,
37-
unsigned long);
38-
typedef void (*rxrpc_discard_new_call_t)(struct rxrpc_call *, unsigned long);
39-
typedef void (*rxrpc_user_attach_call_t)(struct rxrpc_call *, unsigned long);
4046

41-
void rxrpc_kernel_new_call_notification(struct socket *,
42-
rxrpc_notify_new_call_t,
43-
rxrpc_discard_new_call_t);
47+
void rxrpc_kernel_set_notifications(struct socket *sock,
48+
const struct rxrpc_kernel_ops *app_ops);
4449
struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
4550
struct rxrpc_peer *peer,
4651
struct key *key,
@@ -70,9 +75,9 @@ struct rxrpc_peer *rxrpc_kernel_get_call_peer(struct socket *sock, struct rxrpc_
7075
const struct sockaddr_rxrpc *rxrpc_kernel_remote_srx(const struct rxrpc_peer *peer);
7176
const struct sockaddr *rxrpc_kernel_remote_addr(const struct rxrpc_peer *peer);
7277
unsigned int rxrpc_kernel_get_srtt(const struct rxrpc_peer *);
73-
int rxrpc_kernel_charge_accept(struct socket *, rxrpc_notify_rx_t,
74-
rxrpc_user_attach_call_t, unsigned long, gfp_t,
75-
unsigned int);
78+
int rxrpc_kernel_charge_accept(struct socket *sock, rxrpc_notify_rx_t notify_rx,
79+
unsigned long user_call_ID, gfp_t gfp,
80+
unsigned int debug_id);
7681
void rxrpc_kernel_set_tx_length(struct socket *, struct rxrpc_call *, s64);
7782
bool rxrpc_kernel_check_life(const struct socket *, const struct rxrpc_call *);
7883
u32 rxrpc_kernel_get_epoch(struct socket *, struct rxrpc_call *);

net/rxrpc/af_rxrpc.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -464,24 +464,20 @@ u32 rxrpc_kernel_get_epoch(struct socket *sock, struct rxrpc_call *call)
464464
EXPORT_SYMBOL(rxrpc_kernel_get_epoch);
465465

466466
/**
467-
* rxrpc_kernel_new_call_notification - Get notifications of new calls
468-
* @sock: The socket to intercept received messages on
469-
* @notify_new_call: Function to be called when new calls appear
470-
* @discard_new_call: Function to discard preallocated calls
467+
* rxrpc_kernel_set_notifications - Set table of callback operations
468+
* @sock: The socket to install table upon
469+
* @app_ops: Callback operation table to set
471470
*
472-
* Allow a kernel service to be given notifications about new calls.
471+
* Allow a kernel service to set a table of event notifications on a socket.
473472
*/
474-
void rxrpc_kernel_new_call_notification(
475-
struct socket *sock,
476-
rxrpc_notify_new_call_t notify_new_call,
477-
rxrpc_discard_new_call_t discard_new_call)
473+
void rxrpc_kernel_set_notifications(struct socket *sock,
474+
const struct rxrpc_kernel_ops *app_ops)
478475
{
479476
struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
480477

481-
rx->notify_new_call = notify_new_call;
482-
rx->discard_new_call = discard_new_call;
478+
rx->app_ops = app_ops;
483479
}
484-
EXPORT_SYMBOL(rxrpc_kernel_new_call_notification);
480+
EXPORT_SYMBOL(rxrpc_kernel_set_notifications);
485481

486482
/**
487483
* rxrpc_kernel_set_max_life - Set maximum lifespan on a call

net/rxrpc/ar-internal.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,7 @@ struct rxrpc_backlog {
142142
struct rxrpc_sock {
143143
/* WARNING: sk has to be the first member */
144144
struct sock sk;
145-
rxrpc_notify_new_call_t notify_new_call; /* Func to notify of new call */
146-
rxrpc_discard_new_call_t discard_new_call; /* Func to discard a new call */
145+
const struct rxrpc_kernel_ops *app_ops; /* Table of kernel app notification funcs */
147146
struct rxrpc_local *local; /* local endpoint */
148147
struct rxrpc_backlog *backlog; /* Preallocation for services */
149148
spinlock_t incoming_lock; /* Incoming call vs service shutdown lock */

net/rxrpc/call_accept.c

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ static void rxrpc_dummy_notify(struct sock *sk, struct rxrpc_call *call,
3434
static int rxrpc_service_prealloc_one(struct rxrpc_sock *rx,
3535
struct rxrpc_backlog *b,
3636
rxrpc_notify_rx_t notify_rx,
37-
rxrpc_user_attach_call_t user_attach_call,
3837
unsigned long user_call_ID, gfp_t gfp,
3938
unsigned int debug_id)
4039
{
@@ -123,9 +122,10 @@ static int rxrpc_service_prealloc_one(struct rxrpc_sock *rx,
123122

124123
call->user_call_ID = user_call_ID;
125124
call->notify_rx = notify_rx;
126-
if (user_attach_call) {
125+
if (rx->app_ops &&
126+
rx->app_ops->user_attach_call) {
127127
rxrpc_get_call(call, rxrpc_call_get_kernel_service);
128-
user_attach_call(call, user_call_ID);
128+
rx->app_ops->user_attach_call(call, user_call_ID);
129129
}
130130

131131
rxrpc_get_call(call, rxrpc_call_get_userid);
@@ -221,9 +221,10 @@ void rxrpc_discard_prealloc(struct rxrpc_sock *rx)
221221
struct rxrpc_call *call = b->call_backlog[tail];
222222
rxrpc_see_call(call, rxrpc_call_see_discard);
223223
rcu_assign_pointer(call->socket, rx);
224-
if (rx->discard_new_call) {
224+
if (rx->app_ops &&
225+
rx->app_ops->discard_new_call) {
225226
_debug("discard %lx", call->user_call_ID);
226-
rx->discard_new_call(call, call->user_call_ID);
227+
rx->app_ops->discard_new_call(call, call->user_call_ID);
227228
if (call->notify_rx)
228229
call->notify_rx = rxrpc_dummy_notify;
229230
rxrpc_put_call(call, rxrpc_call_put_kernel);
@@ -392,8 +393,9 @@ bool rxrpc_new_incoming_call(struct rxrpc_local *local,
392393
rxrpc_incoming_call(rx, call, skb);
393394
conn = call->conn;
394395

395-
if (rx->notify_new_call)
396-
rx->notify_new_call(&rx->sk, call, call->user_call_ID);
396+
if (rx->app_ops &&
397+
rx->app_ops->notify_new_call)
398+
rx->app_ops->notify_new_call(&rx->sk, call, call->user_call_ID);
397399

398400
spin_lock(&conn->state_lock);
399401
if (conn->state == RXRPC_CONN_SERVICE_UNSECURED) {
@@ -445,29 +447,26 @@ int rxrpc_user_charge_accept(struct rxrpc_sock *rx, unsigned long user_call_ID)
445447
if (rx->sk.sk_state == RXRPC_CLOSE)
446448
return -ESHUTDOWN;
447449

448-
return rxrpc_service_prealloc_one(rx, b, NULL, NULL, user_call_ID,
449-
GFP_KERNEL,
450+
return rxrpc_service_prealloc_one(rx, b, NULL, user_call_ID, GFP_KERNEL,
450451
atomic_inc_return(&rxrpc_debug_id));
451452
}
452453

453454
/*
454455
* rxrpc_kernel_charge_accept - Charge up socket with preallocated calls
455456
* @sock: The socket on which to preallocate
456457
* @notify_rx: Event notification function for the call
457-
* @user_attach_call: Func to attach call to user_call_ID
458458
* @user_call_ID: The tag to attach to the preallocated call
459459
* @gfp: The allocation conditions.
460460
* @debug_id: The tracing debug ID.
461461
*
462-
* Charge up the socket with preallocated calls, each with a user ID. A
463-
* function should be provided to effect the attachment from the user's side.
464-
* The user is given a ref to hold on the call.
462+
* Charge up the socket with preallocated calls, each with a user ID. The
463+
* ->user_attach_call() callback function should be provided to effect the
464+
* attachment from the user's side. The user is given a ref to hold on the
465+
* call.
465466
*
466467
* Note that the call may be come connected before this function returns.
467468
*/
468-
int rxrpc_kernel_charge_accept(struct socket *sock,
469-
rxrpc_notify_rx_t notify_rx,
470-
rxrpc_user_attach_call_t user_attach_call,
469+
int rxrpc_kernel_charge_accept(struct socket *sock, rxrpc_notify_rx_t notify_rx,
471470
unsigned long user_call_ID, gfp_t gfp,
472471
unsigned int debug_id)
473472
{
@@ -477,8 +476,7 @@ int rxrpc_kernel_charge_accept(struct socket *sock,
477476
if (sock->sk->sk_state == RXRPC_CLOSE)
478477
return -ESHUTDOWN;
479478

480-
return rxrpc_service_prealloc_one(rx, b, notify_rx,
481-
user_attach_call, user_call_ID,
479+
return rxrpc_service_prealloc_one(rx, b, notify_rx, user_call_ID,
482480
gfp, debug_id);
483481
}
484482
EXPORT_SYMBOL(rxrpc_kernel_charge_accept);

net/rxrpc/rxperf.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,12 @@ static void rxperf_notify_end_reply_tx(struct sock *sock,
136136
RXPERF_CALL_SV_AWAIT_ACK);
137137
}
138138

139+
static const struct rxrpc_kernel_ops rxperf_rxrpc_callback_ops = {
140+
.notify_new_call = rxperf_rx_new_call,
141+
.discard_new_call = rxperf_rx_discard_new_call,
142+
.user_attach_call = rxperf_rx_attach,
143+
};
144+
139145
/*
140146
* Charge the incoming call preallocation.
141147
*/
@@ -161,7 +167,6 @@ static void rxperf_charge_preallocation(struct work_struct *work)
161167

162168
if (rxrpc_kernel_charge_accept(rxperf_socket,
163169
rxperf_notify_rx,
164-
rxperf_rx_attach,
165170
(unsigned long)call,
166171
GFP_KERNEL,
167172
call->debug_id) < 0)
@@ -209,8 +214,7 @@ static int rxperf_open_socket(void)
209214
if (ret < 0)
210215
goto error_2;
211216

212-
rxrpc_kernel_new_call_notification(socket, rxperf_rx_new_call,
213-
rxperf_rx_discard_new_call);
217+
rxrpc_kernel_set_notifications(socket, &rxperf_rxrpc_callback_ops);
214218

215219
ret = kernel_listen(socket, INT_MAX);
216220
if (ret < 0)

0 commit comments

Comments
 (0)