mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	SUNRPC: Prevent thundering herd when the socket is not connected
If the socket is not connected, then we want to initiate a reconnect
rather that trying to transmit requests. If there is a large number
of requests queued and waiting for the lock in call_transmit(),
then it can take a while for one of the to loop back and retake
the lock in call_connect.
Fixes: 89f90fe1ad ("SUNRPC: Allow calls to xprt_transmit() to drain...")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
			
			
This commit is contained in:
		
							parent
							
								
									0d1bf3407c
								
							
						
					
					
						commit
						ed7dc973bd
					
				
					 1 changed files with 17 additions and 4 deletions
				
			
		| 
						 | 
					@ -1807,7 +1807,12 @@ call_encode(struct rpc_task *task)
 | 
				
			||||||
		xprt_request_enqueue_receive(task);
 | 
							xprt_request_enqueue_receive(task);
 | 
				
			||||||
	xprt_request_enqueue_transmit(task);
 | 
						xprt_request_enqueue_transmit(task);
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	task->tk_action = call_bind;
 | 
						task->tk_action = call_transmit;
 | 
				
			||||||
 | 
						/* Check that the connection is OK */
 | 
				
			||||||
 | 
						if (!xprt_bound(task->tk_xprt))
 | 
				
			||||||
 | 
							task->tk_action = call_bind;
 | 
				
			||||||
 | 
						else if (!xprt_connected(task->tk_xprt))
 | 
				
			||||||
 | 
							task->tk_action = call_connect;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -1999,13 +2004,19 @@ call_transmit(struct rpc_task *task)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	dprint_status(task);
 | 
						dprint_status(task);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	task->tk_status = 0;
 | 
						task->tk_action = call_transmit_status;
 | 
				
			||||||
	if (test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate)) {
 | 
						if (test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate)) {
 | 
				
			||||||
		if (!xprt_prepare_transmit(task))
 | 
							if (!xprt_prepare_transmit(task))
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		xprt_transmit(task);
 | 
							task->tk_status = 0;
 | 
				
			||||||
 | 
							if (test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate)) {
 | 
				
			||||||
 | 
								if (!xprt_connected(task->tk_xprt)) {
 | 
				
			||||||
 | 
									task->tk_status = -ENOTCONN;
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								xprt_transmit(task);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	task->tk_action = call_transmit_status;
 | 
					 | 
				
			||||||
	xprt_end_transmit(task);
 | 
						xprt_end_transmit(task);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2067,6 +2078,8 @@ call_transmit_status(struct rpc_task *task)
 | 
				
			||||||
	case -EADDRINUSE:
 | 
						case -EADDRINUSE:
 | 
				
			||||||
	case -ENOTCONN:
 | 
						case -ENOTCONN:
 | 
				
			||||||
	case -EPIPE:
 | 
						case -EPIPE:
 | 
				
			||||||
 | 
							task->tk_action = call_bind;
 | 
				
			||||||
 | 
							task->tk_status = 0;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue