[CIFS] don't allow demultiplex thread to exit until kthread_stop is called

cifs_demultiplex_thread can exit under several conditions:

1) if it's signaled
2) if there's a problem with session setup
3) if kthread_stop is called on it

The first two are problems. If kthread_stop is called on the thread,
there is no guarantee that it will still be up. We need to have the
thread stay up until kthread_stop is called on it.

One option would be to not even try to tear things down until after
kthread_stop is called. However, in the case where there is a problem
setting up the session, there's no real reason to try continuing the
loop.

This patch allows the thread to clean up and prepare for exit under all
three conditions, but it has the thread go to sleep until kthread_stop
is called. This allows us to simplify the shutdown code somewhat since
we can be reasonably sure that the thread won't exit after being
signaled but before kthread_stop is called.

It also removes the places where the thread itself set the tsk variable
since it appeared that it could have a potential race where the thread
might never be shut down.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Acked-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Steve French <sfrench@us.ibm.com>

+14 -14
+14 -14
fs/cifs/connect.c
··· 348 int reconnect; 349 350 current->flags |= PF_MEMALLOC; 351 - server->tsk = current; /* save process info to wake at shutdown */ 352 cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current))); 353 write_lock(&GlobalSMBSeslock); 354 atomic_inc(&tcpSesAllocCount); ··· 650 651 spin_lock(&GlobalMid_Lock); 652 server->tcpStatus = CifsExiting; 653 - server->tsk = NULL; 654 /* check if we have blocked requests that need to free */ 655 /* Note that cifs_max_pending is normally 50, but 656 can be set at module install time to as little as two */ 657 if (atomic_read(&server->inFlight) >= cifs_max_pending) 658 atomic_set(&server->inFlight, cifs_max_pending - 1); 659 /* We do not want to set the max_pending too low or we ··· 2196 srvTcp->tcpStatus = CifsExiting; 2197 spin_unlock(&GlobalMid_Lock); 2198 if (srvTcp->tsk) { 2199 - struct task_struct *tsk; 2200 /* If we could verify that kthread_stop would 2201 always wake up processes blocked in 2202 tcp in recv_mesg then we could remove the 2203 send_sig call */ 2204 force_sig(SIGKILL, srvTcp->tsk); 2205 - tsk = srvTcp->tsk; 2206 - if (tsk) 2207 - kthread_stop(tsk); 2208 } 2209 } 2210 /* If find_unc succeeded then rc == 0 so we can not end */ ··· 2217 if ((temp_rc == -ESHUTDOWN) && 2218 (pSesInfo->server) && 2219 (pSesInfo->server->tsk)) { 2220 - struct task_struct *tsk; 2221 force_sig(SIGKILL, 2222 pSesInfo->server->tsk); 2223 - tsk = pSesInfo->server->tsk; 2224 - if (tsk) 2225 - kthread_stop(tsk); 2226 } 2227 } else { 2228 cFYI(1, ("No session or bad tcon")); 2229 if ((pSesInfo->server) && 2230 (pSesInfo->server->tsk)) { 2231 - struct task_struct *tsk; 2232 force_sig(SIGKILL, 2233 pSesInfo->server->tsk); 2234 - tsk = pSesInfo->server->tsk; 2235 - if (tsk) 2236 - kthread_stop(tsk); 2237 } 2238 } 2239 sesInfoFree(pSesInfo);
··· 348 int reconnect; 349 350 current->flags |= PF_MEMALLOC; 351 cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current))); 352 write_lock(&GlobalSMBSeslock); 353 atomic_inc(&tcpSesAllocCount); ··· 651 652 spin_lock(&GlobalMid_Lock); 653 server->tcpStatus = CifsExiting; 654 + spin_unlock(&GlobalMid_Lock); 655 + 656 + /* don't exit until kthread_stop is called */ 657 + set_current_state(TASK_UNINTERRUPTIBLE); 658 + while (!kthread_should_stop()) { 659 + schedule(); 660 + set_current_state(TASK_UNINTERRUPTIBLE); 661 + } 662 + set_current_state(TASK_RUNNING); 663 + 664 /* check if we have blocked requests that need to free */ 665 /* Note that cifs_max_pending is normally 50, but 666 can be set at module install time to as little as two */ 667 + spin_lock(&GlobalMid_Lock); 668 if (atomic_read(&server->inFlight) >= cifs_max_pending) 669 atomic_set(&server->inFlight, cifs_max_pending - 1); 670 /* We do not want to set the max_pending too low or we ··· 2187 srvTcp->tcpStatus = CifsExiting; 2188 spin_unlock(&GlobalMid_Lock); 2189 if (srvTcp->tsk) { 2190 /* If we could verify that kthread_stop would 2191 always wake up processes blocked in 2192 tcp in recv_mesg then we could remove the 2193 send_sig call */ 2194 force_sig(SIGKILL, srvTcp->tsk); 2195 + kthread_stop(srvTcp->tsk); 2196 } 2197 } 2198 /* If find_unc succeeded then rc == 0 so we can not end */ ··· 2211 if ((temp_rc == -ESHUTDOWN) && 2212 (pSesInfo->server) && 2213 (pSesInfo->server->tsk)) { 2214 force_sig(SIGKILL, 2215 pSesInfo->server->tsk); 2216 + kthread_stop(pSesInfo->server->tsk); 2217 } 2218 } else { 2219 cFYI(1, ("No session or bad tcon")); 2220 if ((pSesInfo->server) && 2221 (pSesInfo->server->tsk)) { 2222 force_sig(SIGKILL, 2223 pSesInfo->server->tsk); 2224 + kthread_stop(pSesInfo->server->tsk); 2225 } 2226 } 2227 sesInfoFree(pSesInfo);