aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2016-09-29 17:37:15 -0400
committerDavid Howells <dhowells@redhat.com>2016-09-29 17:57:47 -0400
commit2629c7fa7c0adfdf023051b404cd538951bd0354 (patch)
tree0875f34ec86644b5d728006feefdf33c7943cadb
parenta1767077b0176de17fa40ec743a20cbdac7a0d56 (diff)
rxrpc: When activating client conn channels, do state check inside lock
In rxrpc_activate_channels(), the connection cache state is checked outside of the lock, which means it can change whilst we're waking calls up, thereby changing whether or not we're allowed to wake calls up. Fix this by moving the check inside the locked region. The check to see if all the channels are currently busy can stay outside of the locked region. Whilst we're at it: (1) Split the locked section out into its own function so that we can call it from other places in a later patch. (2) Determine the mask of channels dependent on the state as we're going to add another state in a later patch that will restrict the number of simultaneous calls to 1 on a connection. Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r--net/rxrpc/conn_client.c36
1 files changed, 25 insertions, 11 deletions
diff --git a/net/rxrpc/conn_client.c b/net/rxrpc/conn_client.c
index f5ee8bfa5bef..60ef9605167e 100644
--- a/net/rxrpc/conn_client.c
+++ b/net/rxrpc/conn_client.c
@@ -576,28 +576,42 @@ static void rxrpc_activate_one_channel(struct rxrpc_connection *conn,
576} 576}
577 577
578/* 578/*
579 * Assign channels and callNumbers to waiting calls with channel_lock
580 * held by caller.
581 */
582static void rxrpc_activate_channels_locked(struct rxrpc_connection *conn)
583{
584 u8 avail, mask;
585
586 switch (conn->cache_state) {
587 case RXRPC_CONN_CLIENT_ACTIVE:
588 mask = RXRPC_ACTIVE_CHANS_MASK;
589 break;
590 default:
591 return;
592 }
593
594 while (!list_empty(&conn->waiting_calls) &&
595 (avail = ~conn->active_chans,
596 avail &= mask,
597 avail != 0))
598 rxrpc_activate_one_channel(conn, __ffs(avail));
599}
600
601/*
579 * Assign channels and callNumbers to waiting calls. 602 * Assign channels and callNumbers to waiting calls.
580 */ 603 */
581static void rxrpc_activate_channels(struct rxrpc_connection *conn) 604static void rxrpc_activate_channels(struct rxrpc_connection *conn)
582{ 605{
583 unsigned char mask;
584
585 _enter("%d", conn->debug_id); 606 _enter("%d", conn->debug_id);
586 607
587 trace_rxrpc_client(conn, -1, rxrpc_client_activate_chans); 608 trace_rxrpc_client(conn, -1, rxrpc_client_activate_chans);
588 609
589 if (conn->cache_state != RXRPC_CONN_CLIENT_ACTIVE || 610 if (conn->active_chans == RXRPC_ACTIVE_CHANS_MASK)
590 conn->active_chans == RXRPC_ACTIVE_CHANS_MASK)
591 return; 611 return;
592 612
593 spin_lock(&conn->channel_lock); 613 spin_lock(&conn->channel_lock);
594 614 rxrpc_activate_channels_locked(conn);
595 while (!list_empty(&conn->waiting_calls) &&
596 (mask = ~conn->active_chans,
597 mask &= RXRPC_ACTIVE_CHANS_MASK,
598 mask != 0))
599 rxrpc_activate_one_channel(conn, __ffs(mask));
600
601 spin_unlock(&conn->channel_lock); 615 spin_unlock(&conn->channel_lock);
602 _leave(""); 616 _leave("");
603} 617}