From: Simon Wilkinson Date: Fri, 26 Oct 2012 11:21:41 +0000 (+0100) Subject: rx: Don't build a call to immediately abort it X-Git-Tag: upstream/1.8.0_pre1^2~1864 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=a0ae8f514519b73ba7f7653bb78b9fc5b6e228f8;p=packages%2Fo%2Fopenafs.git rx: Don't build a call to immediately abort it If the server is over the busy threshold, then don't create a new call structure just to be able to send an abort on that call. Instead, use rx_SendRawAbort to send an abort packet on the appropriate channel. Change-Id: I02782fc25fe8ed7608b39e3f8355e2793f7526e3 Reviewed-on: http://gerrit.openafs.org/8296 Reviewed-by: Jeffrey Altman Tested-by: BuildBot Reviewed-by: Derrick Brashear --- diff --git a/src/rx/rx.c b/src/rx/rx.c index 631cd978f..7a255be87 100644 --- a/src/rx/rx.c +++ b/src/rx/rx.c @@ -3208,6 +3208,26 @@ rxi_CheckBusy(struct rx_call *call) MUTEX_EXIT(&conn->conn_call_lock); } +/*! + * Abort the call if the server is over the busy threshold. This + * can be used without requiring a call structure be initialised, + * or connected to a particular channel + */ +static_inline int +rxi_AbortIfServerBusy(osi_socket socket, afs_uint32 host, + u_short port, struct rx_packet *np) +{ + if ((rx_BusyThreshold > 0) && + (rx_atomic_read(&rx_nWaiting) > rx_BusyThreshold)) { + rxi_SendRawAbort(socket, host, port, rx_BusyError, np, 0); + if (rx_stats_active) + rx_atomic_inc(&rx_stats.nBusies); + return 1; + } + + return 0; +} + /* There are two packet tracing routines available for testing and monitoring * Rx. One is called just after every packet is received and the other is * called just before every packet is sent. Received packets, have had their @@ -3398,6 +3418,12 @@ rxi_ReceivePacket(struct rx_packet *np, osi_socket socket, currentCallNumber = conn->callNumber[channel]; MUTEX_EXIT(&conn->conn_call_lock); } else if (type == RX_SERVER_CONNECTION) { /* No call allocated */ + + if (rxi_AbortIfServerBusy(socket, host, port, np)) { + putConnection(conn); + return np; + } + call = rxi_NewCall(conn, channel); /* returns locked call */ *call->callNumber = currentCallNumber = np->header.callNumber; MUTEX_EXIT(&conn->conn_call_lock); @@ -3405,23 +3431,8 @@ rxi_ReceivePacket(struct rx_packet *np, osi_socket socket, clock_GetTime(&call->queueTime); call->app.bytesSent = 0; call->app.bytesRcvd = 0; - /* - * If the number of queued calls exceeds the overload - * threshold then abort this call. - */ - if ((rx_BusyThreshold > 0) && - (rx_atomic_read(&rx_nWaiting) > rx_BusyThreshold)) { - struct rx_packet *tp; - - rxi_CallError(call, rx_BusyError); - tp = rxi_SendCallAbort(call, np, 1, 0); - MUTEX_EXIT(&call->lock); - putConnection(conn); - if (rx_stats_active) - rx_atomic_inc(&rx_stats.nBusies); - return tp; - } rxi_KeepAliveOn(call); + } else { /* RX_CLIENT_CONNECTION and No call allocated */ /* This packet can't be for this call. If the new call address is * 0 then no call is running on this channel. If there is a call @@ -3478,6 +3489,13 @@ rxi_ReceivePacket(struct rx_packet *np, osi_socket socket, putConnection(conn); return tp; } + + if (rxi_AbortIfServerBusy(socket, host, port, np)) { + MUTEX_EXIT(&call->lock); + putConnection(conn); + return np; + } + rxi_ResetCall(call, 0); /* * The conn_call_lock is not held but no one else should be @@ -3489,22 +3507,6 @@ rxi_ReceivePacket(struct rx_packet *np, osi_socket socket, clock_GetTime(&call->queueTime); call->app.bytesSent = 0; call->app.bytesRcvd = 0; - /* - * If the number of queued calls exceeds the overload - * threshold then abort this call. - */ - if ((rx_BusyThreshold > 0) && - (rx_atomic_read(&rx_nWaiting) > rx_BusyThreshold)) { - struct rx_packet *tp; - - rxi_CallError(call, rx_BusyError); - tp = rxi_SendCallAbort(call, np, 1, 0); - MUTEX_EXIT(&call->lock); - putConnection(conn); - if (rx_stats_active) - rx_atomic_inc(&rx_stats.nBusies); - return tp; - } rxi_KeepAliveOn(call); } else { /* Continuing call; do nothing here. */