Skip to content

Commit 96b4059

Browse files
committed
rxrpc: Remove call->state_lock
All the setters of call->state are now in the I/O thread and thus the state lock is now unnecessary. Signed-off-by: David Howells <[email protected]> cc: Marc Dionne <[email protected]> cc: [email protected]
1 parent 93368b6 commit 96b4059

File tree

12 files changed

+142
-184
lines changed

12 files changed

+142
-184
lines changed

net/rxrpc/ar-internal.h

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -631,14 +631,13 @@ struct rxrpc_call {
631631
unsigned long flags;
632632
unsigned long events;
633633
spinlock_t notify_lock; /* Kernel notification lock */
634-
rwlock_t state_lock; /* lock for state transition */
635634
unsigned int send_abort_why; /* Why the abort [enum rxrpc_abort_reason] */
636635
s32 send_abort; /* Abort code to be sent */
637636
short send_abort_err; /* Error to be associated with the abort */
638637
rxrpc_seq_t send_abort_seq; /* DATA packet that incurred the abort (or 0) */
639638
s32 abort_code; /* Local/remote abort code */
640639
int error; /* Local error incurred */
641-
enum rxrpc_call_state state; /* current state of call */
640+
enum rxrpc_call_state _state; /* Current state of call (needs barrier) */
642641
enum rxrpc_call_completion completion; /* Call completion condition */
643642
refcount_t ref;
644643
u8 security_ix; /* Security type */
@@ -889,25 +888,37 @@ static inline bool rxrpc_is_client_call(const struct rxrpc_call *call)
889888
/*
890889
* call_state.c
891890
*/
892-
bool __rxrpc_set_call_completion(struct rxrpc_call *call,
893-
enum rxrpc_call_completion compl,
894-
u32 abort_code,
895-
int error);
896891
bool rxrpc_set_call_completion(struct rxrpc_call *call,
897892
enum rxrpc_call_completion compl,
898893
u32 abort_code,
899894
int error);
900-
bool __rxrpc_call_completed(struct rxrpc_call *call);
901895
bool rxrpc_call_completed(struct rxrpc_call *call);
902-
bool __rxrpc_abort_call(struct rxrpc_call *call, rxrpc_seq_t seq,
903-
u32 abort_code, int error, enum rxrpc_abort_reason why);
904896
bool rxrpc_abort_call(struct rxrpc_call *call, rxrpc_seq_t seq,
905897
u32 abort_code, int error, enum rxrpc_abort_reason why);
898+
void rxrpc_prefail_call(struct rxrpc_call *call, enum rxrpc_call_completion compl,
899+
int error);
900+
901+
static inline void rxrpc_set_call_state(struct rxrpc_call *call,
902+
enum rxrpc_call_state state)
903+
{
904+
/* Order write of completion info before write of ->state. */
905+
smp_store_release(&call->_state, state);
906+
}
907+
908+
static inline enum rxrpc_call_state __rxrpc_call_state(const struct rxrpc_call *call)
909+
{
910+
return call->_state; /* Only inside I/O thread */
911+
}
912+
913+
static inline bool __rxrpc_call_is_complete(const struct rxrpc_call *call)
914+
{
915+
return __rxrpc_call_state(call) == RXRPC_CALL_COMPLETE;
916+
}
906917

907918
static inline enum rxrpc_call_state rxrpc_call_state(const struct rxrpc_call *call)
908919
{
909-
/* Order read ->state before read ->error. */
910-
return smp_load_acquire(&call->state);
920+
/* Order read ->state before read of completion info. */
921+
return smp_load_acquire(&call->_state);
911922
}
912923

913924
static inline bool rxrpc_call_is_complete(const struct rxrpc_call *call)

net/rxrpc/call_accept.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ static int rxrpc_service_prealloc_one(struct rxrpc_sock *rx,
9999
if (!call)
100100
return -ENOMEM;
101101
call->flags |= (1 << RXRPC_CALL_IS_SERVICE);
102-
call->state = RXRPC_CALL_SERVER_PREALLOC;
102+
rxrpc_set_call_state(call, RXRPC_CALL_SERVER_PREALLOC);
103103
__set_bit(RXRPC_CALL_EV_INITIAL_PING, &call->events);
104104

105105
trace_rxrpc_call(call->debug_id, refcount_read(&call->ref),

net/rxrpc/call_event.c

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -257,20 +257,13 @@ void rxrpc_resend(struct rxrpc_call *call, struct sk_buff *ack_skb)
257257
*/
258258
static void rxrpc_begin_service_reply(struct rxrpc_call *call)
259259
{
260-
unsigned long now;
261-
262-
write_lock(&call->state_lock);
263-
264-
if (call->state == RXRPC_CALL_SERVER_ACK_REQUEST) {
265-
now = jiffies;
266-
call->state = RXRPC_CALL_SERVER_SEND_REPLY;
267-
WRITE_ONCE(call->delay_ack_at, now + MAX_JIFFY_OFFSET);
268-
if (call->ackr_reason == RXRPC_ACK_DELAY)
269-
call->ackr_reason = 0;
270-
trace_rxrpc_timer(call, rxrpc_timer_init_for_send_reply, now);
271-
}
260+
unsigned long now = jiffies;
272261

273-
write_unlock(&call->state_lock);
262+
rxrpc_set_call_state(call, RXRPC_CALL_SERVER_SEND_REPLY);
263+
WRITE_ONCE(call->delay_ack_at, now + MAX_JIFFY_OFFSET);
264+
if (call->ackr_reason == RXRPC_ACK_DELAY)
265+
call->ackr_reason = 0;
266+
trace_rxrpc_timer(call, rxrpc_timer_init_for_send_reply, now);
274267
}
275268

276269
/*
@@ -281,18 +274,16 @@ static void rxrpc_close_tx_phase(struct rxrpc_call *call)
281274
{
282275
_debug("________awaiting reply/ACK__________");
283276

284-
write_lock(&call->state_lock);
285-
switch (call->state) {
277+
switch (__rxrpc_call_state(call)) {
286278
case RXRPC_CALL_CLIENT_SEND_REQUEST:
287-
call->state = RXRPC_CALL_CLIENT_AWAIT_REPLY;
279+
rxrpc_set_call_state(call, RXRPC_CALL_CLIENT_AWAIT_REPLY);
288280
break;
289281
case RXRPC_CALL_SERVER_SEND_REPLY:
290-
call->state = RXRPC_CALL_SERVER_AWAIT_ACK;
282+
rxrpc_set_call_state(call, RXRPC_CALL_SERVER_AWAIT_ACK);
291283
break;
292284
default:
293285
break;
294286
}
295-
write_unlock(&call->state_lock);
296287
}
297288

298289
static bool rxrpc_tx_window_has_space(struct rxrpc_call *call)
@@ -341,7 +332,7 @@ static void rxrpc_decant_prepared_tx(struct rxrpc_call *call)
341332

342333
static void rxrpc_transmit_some_data(struct rxrpc_call *call)
343334
{
344-
switch (call->state) {
335+
switch (__rxrpc_call_state(call)) {
345336
case RXRPC_CALL_SERVER_ACK_REQUEST:
346337
if (list_empty(&call->tx_sendmsg))
347338
return;
@@ -390,9 +381,10 @@ bool rxrpc_input_call_event(struct rxrpc_call *call, struct sk_buff *skb)
390381

391382
//printk("\n--------------------\n");
392383
_enter("{%d,%s,%lx}",
393-
call->debug_id, rxrpc_call_states[call->state], call->events);
384+
call->debug_id, rxrpc_call_states[__rxrpc_call_state(call)],
385+
call->events);
394386

395-
if (call->state == RXRPC_CALL_COMPLETE)
387+
if (__rxrpc_call_is_complete(call))
396388
goto out;
397389

398390
/* Handle abort request locklessly, vs rxrpc_propose_abort(). */
@@ -415,7 +407,7 @@ bool rxrpc_input_call_event(struct rxrpc_call *call, struct sk_buff *skb)
415407
}
416408

417409
t = READ_ONCE(call->expect_req_by);
418-
if (call->state == RXRPC_CALL_SERVER_RECV_REQUEST &&
410+
if (__rxrpc_call_state(call) == RXRPC_CALL_SERVER_RECV_REQUEST &&
419411
time_after_eq(now, t)) {
420412
trace_rxrpc_timer(call, rxrpc_timer_exp_idle, now);
421413
expired = true;
@@ -499,7 +491,7 @@ bool rxrpc_input_call_event(struct rxrpc_call *call, struct sk_buff *skb)
499491
rxrpc_send_ACK(call, RXRPC_ACK_PING, 0,
500492
rxrpc_propose_ack_ping_for_lost_ack);
501493

502-
if (resend && call->state != RXRPC_CALL_CLIENT_RECV_REPLY)
494+
if (resend && __rxrpc_call_state(call) != RXRPC_CALL_CLIENT_RECV_REPLY)
503495
rxrpc_resend(call, NULL);
504496

505497
if (test_and_clear_bit(RXRPC_CALL_RX_IS_IDLE, &call->flags))
@@ -511,7 +503,7 @@ bool rxrpc_input_call_event(struct rxrpc_call *call, struct sk_buff *skb)
511503
rxrpc_propose_ack_input_data);
512504

513505
/* Make sure the timer is restarted */
514-
if (call->state != RXRPC_CALL_COMPLETE) {
506+
if (!__rxrpc_call_is_complete(call)) {
515507
next = call->expect_rx_by;
516508

517509
#define set(T) { t = READ_ONCE(T); if (time_before(t, next)) next = t; }
@@ -532,7 +524,7 @@ bool rxrpc_input_call_event(struct rxrpc_call *call, struct sk_buff *skb)
532524
}
533525

534526
out:
535-
if (call->state == RXRPC_CALL_COMPLETE) {
527+
if (__rxrpc_call_is_complete(call)) {
536528
del_timer_sync(&call->timer);
537529
if (!test_bit(RXRPC_CALL_DISCONNECTED, &call->flags))
538530
rxrpc_disconnect_call(call);

net/rxrpc/call_object.c

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ static void rxrpc_call_timer_expired(struct timer_list *t)
6969

7070
_enter("%d", call->debug_id);
7171

72-
if (call->state < RXRPC_CALL_COMPLETE) {
72+
if (!__rxrpc_call_is_complete(call)) {
7373
trace_rxrpc_timer_expired(call, jiffies);
7474
rxrpc_poke_call(call, rxrpc_call_poke_timer);
7575
}
@@ -162,7 +162,6 @@ struct rxrpc_call *rxrpc_alloc_call(struct rxrpc_sock *rx, gfp_t gfp,
162162
init_waitqueue_head(&call->waitq);
163163
spin_lock_init(&call->notify_lock);
164164
spin_lock_init(&call->tx_lock);
165-
rwlock_init(&call->state_lock);
166165
refcount_set(&call->ref, 1);
167166
call->debug_id = debug_id;
168167
call->tx_total_len = -1;
@@ -211,7 +210,6 @@ static struct rxrpc_call *rxrpc_alloc_client_call(struct rxrpc_sock *rx,
211210
now = ktime_get_real();
212211
call->acks_latest_ts = now;
213212
call->cong_tstamp = now;
214-
call->state = RXRPC_CALL_CLIENT_AWAIT_CONN;
215213
call->dest_srx = *srx;
216214
call->interruptibility = p->interruptibility;
217215
call->tx_total_len = p->tx_total_len;
@@ -227,11 +225,13 @@ static struct rxrpc_call *rxrpc_alloc_client_call(struct rxrpc_sock *rx,
227225

228226
ret = rxrpc_init_client_call_security(call);
229227
if (ret < 0) {
230-
__rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR, 0, ret);
228+
rxrpc_prefail_call(call, RXRPC_CALL_LOCAL_ERROR, ret);
231229
rxrpc_put_call(call, rxrpc_call_put_discard_error);
232230
return ERR_PTR(ret);
233231
}
234232

233+
rxrpc_set_call_state(call, RXRPC_CALL_CLIENT_AWAIT_CONN);
234+
235235
trace_rxrpc_call(call->debug_id, refcount_read(&call->ref),
236236
p->user_call_ID, rxrpc_call_new_client);
237237

@@ -384,8 +384,7 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
384384
error_dup_user_ID:
385385
write_unlock(&rx->call_lock);
386386
release_sock(&rx->sk);
387-
__rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR,
388-
RX_CALL_DEAD, -EEXIST);
387+
rxrpc_prefail_call(call, RXRPC_CALL_LOCAL_ERROR, -EEXIST);
389388
trace_rxrpc_call(call->debug_id, refcount_read(&call->ref), 0,
390389
rxrpc_call_see_userid_exists);
391390
rxrpc_release_call(rx, call);
@@ -403,8 +402,7 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
403402
trace_rxrpc_call(call->debug_id, refcount_read(&call->ref), ret,
404403
rxrpc_call_see_connect_failed);
405404
set_bit(RXRPC_CALL_DISCONNECTED, &call->flags);
406-
__rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR,
407-
RX_CALL_DEAD, ret);
405+
rxrpc_prefail_call(call, RXRPC_CALL_LOCAL_ERROR, ret);
408406
_leave(" = c=%08x [err]", call->debug_id);
409407
return call;
410408
}
@@ -427,25 +425,25 @@ void rxrpc_incoming_call(struct rxrpc_sock *rx,
427425
call->call_id = sp->hdr.callNumber;
428426
call->dest_srx.srx_service = sp->hdr.serviceId;
429427
call->cid = sp->hdr.cid;
430-
call->state = RXRPC_CALL_SERVER_SECURING;
431428
call->cong_tstamp = skb->tstamp;
432429

433430
__set_bit(RXRPC_CALL_EXPOSED, &call->flags);
431+
rxrpc_set_call_state(call, RXRPC_CALL_SERVER_SECURING);
434432

435433
spin_lock(&conn->state_lock);
436434

437435
switch (conn->state) {
438436
case RXRPC_CONN_SERVICE_UNSECURED:
439437
case RXRPC_CONN_SERVICE_CHALLENGING:
440-
call->state = RXRPC_CALL_SERVER_SECURING;
438+
rxrpc_set_call_state(call, RXRPC_CALL_SERVER_SECURING);
441439
break;
442440
case RXRPC_CONN_SERVICE:
443-
call->state = RXRPC_CALL_SERVER_RECV_REQUEST;
441+
rxrpc_set_call_state(call, RXRPC_CALL_SERVER_RECV_REQUEST);
444442
break;
445443

446444
case RXRPC_CONN_ABORTED:
447-
__rxrpc_set_call_completion(call, conn->completion,
448-
conn->abort_code, conn->error);
445+
rxrpc_set_call_completion(call, conn->completion,
446+
conn->abort_code, conn->error);
449447
break;
450448
default:
451449
BUG();
@@ -614,7 +612,7 @@ void rxrpc_put_call(struct rxrpc_call *call, enum rxrpc_call_trace why)
614612
dead = __refcount_dec_and_test(&call->ref, &r);
615613
trace_rxrpc_call(debug_id, r - 1, 0, why);
616614
if (dead) {
617-
ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE);
615+
ASSERTCMP(__rxrpc_call_state(call), ==, RXRPC_CALL_COMPLETE);
618616

619617
if (!list_empty(&call->link)) {
620618
spin_lock(&rxnet->call_lock);
@@ -677,7 +675,7 @@ void rxrpc_cleanup_call(struct rxrpc_call *call)
677675
{
678676
memset(&call->sock_node, 0xcd, sizeof(call->sock_node));
679677

680-
ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE);
678+
ASSERTCMP(__rxrpc_call_state(call), ==, RXRPC_CALL_COMPLETE);
681679
ASSERT(test_bit(RXRPC_CALL_RELEASED, &call->flags));
682680

683681
del_timer(&call->timer);
@@ -715,7 +713,7 @@ void rxrpc_destroy_all_calls(struct rxrpc_net *rxnet)
715713

716714
pr_err("Call %p still in use (%d,%s,%lx,%lx)!\n",
717715
call, refcount_read(&call->ref),
718-
rxrpc_call_states[call->state],
716+
rxrpc_call_states[__rxrpc_call_state(call)],
719717
call->flags, call->events);
720718

721719
spin_unlock(&rxnet->call_lock);

0 commit comments

Comments
 (0)