@@ -605,6 +605,7 @@ inc_rfc1001_len(void *buf, int count)
605
605
struct TCP_Server_Info {
606
606
struct list_head tcp_ses_list ;
607
607
struct list_head smb_ses_list ;
608
+ spinlock_t srv_lock ; /* protect anything here that is not protected */
608
609
__u64 conn_id ; /* connection identifier (useful for debugging) */
609
610
int srv_count ; /* reference counter */
610
611
/* 15 character server name + 0x20 16th byte indicating type = srv */
@@ -622,6 +623,7 @@ struct TCP_Server_Info {
622
623
#endif
623
624
wait_queue_head_t response_q ;
624
625
wait_queue_head_t request_q ; /* if more than maxmpx to srvr must block*/
626
+ spinlock_t mid_lock ; /* protect mid queue and it's entries */
625
627
struct list_head pending_mid_q ;
626
628
bool noblocksnd ; /* use blocking sendmsg */
627
629
bool noautotune ; /* do not autotune send buf sizes */
@@ -1008,6 +1010,7 @@ struct cifs_ses {
1008
1010
struct list_head rlist ; /* reconnect list */
1009
1011
struct list_head tcon_list ;
1010
1012
struct cifs_tcon * tcon_ipc ;
1013
+ spinlock_t ses_lock ; /* protect anything here that is not protected */
1011
1014
struct mutex session_mutex ;
1012
1015
struct TCP_Server_Info * server ; /* pointer to server info */
1013
1016
int ses_count ; /* reference counter */
@@ -1169,6 +1172,7 @@ struct cifs_tcon {
1169
1172
struct list_head tcon_list ;
1170
1173
int tc_count ;
1171
1174
struct list_head rlist ; /* reconnect list */
1175
+ spinlock_t tc_lock ; /* protect anything here that is not protected */
1172
1176
atomic_t num_local_opens ; /* num of all opens including disconnected */
1173
1177
atomic_t num_remote_opens ; /* num of all network opens on server */
1174
1178
struct list_head openFileList ;
@@ -1899,33 +1903,78 @@ require use of the stronger protocol */
1899
1903
*/
1900
1904
1901
1905
/****************************************************************************
1902
- * Locking notes. All updates to global variables and lists should be
1903
- * protected by spinlocks or semaphores.
1906
+ * Here are all the locks (spinlock, mutex, semaphore) in cifs.ko, arranged according
1907
+ * to the locking order. i.e. if two locks are to be held together, the lock that
1908
+ * appears higher in this list needs to be taken before the other.
1904
1909
*
1905
- * Spinlocks
1906
- * ---------
1907
- * GlobalMid_Lock protects:
1908
- * list operations on pending_mid_q and oplockQ
1909
- * updates to XID counters, multiplex id and SMB sequence numbers
1910
- * list operations on global DnotifyReqList
1911
- * updates to ses->status and TCP_Server_Info->tcpStatus
1912
- * updates to server->CurrentMid
1913
- * tcp_ses_lock protects:
1914
- * list operations on tcp and SMB session lists
1915
- * tcon->open_file_lock protects the list of open files hanging off the tcon
1916
- * inode->open_file_lock protects the openFileList hanging off the inode
1917
- * cfile->file_info_lock protects counters and fields in cifs file struct
1918
- * f_owner.lock protects certain per file struct operations
1919
- * mapping->page_lock protects certain per page operations
1910
+ * If you hold a lock that is lower in this list, and you need to take a higher lock
1911
+ * (or if you think that one of the functions that you're calling may need to), first
1912
+ * drop the lock you hold, pick up the higher lock, then the lower one. This will
1913
+ * ensure that locks are picked up only in one direction in the below table
1914
+ * (top to bottom).
1920
1915
*
1921
- * Note that the cifs_tcon.open_file_lock should be taken before
1922
- * not after the cifsInodeInfo.open_file_lock
1916
+ * Also, if you expect a function to be called with a lock held, explicitly document
1917
+ * this in the comments on top of your function definition.
1923
1918
*
1924
- * Semaphores
1925
- * ----------
1926
- * cifsInodeInfo->lock_sem protects:
1927
- * the list of locks held by the inode
1919
+ * And also, try to keep the critical sections (lock hold time) to be as minimal as
1920
+ * possible. Blocking / calling other functions with a lock held always increase
1921
+ * the risk of a possible deadlock.
1928
1922
*
1923
+ * Following this rule will avoid unnecessary deadlocks, which can get really hard to
1924
+ * debug. Also, any new lock that you introduce, please add to this list in the correct
1925
+ * order.
1926
+ *
1927
+ * Please populate this list whenever you introduce new locks in your changes. Or in
1928
+ * case I've missed some existing locks. Please ensure that it's added in the list
1929
+ * based on the locking order expected.
1930
+ *
1931
+ * =====================================================================================
1932
+ * Lock Protects Initialization fn
1933
+ * =====================================================================================
1934
+ * vol_list_lock
1935
+ * vol_info->ctx_lock vol_info->ctx
1936
+ * cifs_sb_info->tlink_tree_lock cifs_sb_info->tlink_tree cifs_setup_cifs_sb
1937
+ * TCP_Server_Info-> TCP_Server_Info cifs_get_tcp_session
1938
+ * reconnect_mutex
1939
+ * TCP_Server_Info->srv_mutex TCP_Server_Info cifs_get_tcp_session
1940
+ * cifs_ses->session_mutex cifs_ses sesInfoAlloc
1941
+ * cifs_tcon
1942
+ * cifs_tcon->open_file_lock cifs_tcon->openFileList tconInfoAlloc
1943
+ * cifs_tcon->pending_opens
1944
+ * cifs_tcon->stat_lock cifs_tcon->bytes_read tconInfoAlloc
1945
+ * cifs_tcon->bytes_written
1946
+ * cifs_tcp_ses_lock cifs_tcp_ses_list sesInfoAlloc
1947
+ * GlobalMid_Lock GlobalMaxActiveXid init_cifs
1948
+ * GlobalCurrentXid
1949
+ * GlobalTotalActiveXid
1950
+ * TCP_Server_Info->srv_lock (anything in struct not protected by another lock and can change)
1951
+ * TCP_Server_Info->mid_lock TCP_Server_Info->pending_mid_q cifs_get_tcp_session
1952
+ * ->CurrentMid
1953
+ * (any changes in mid_q_entry fields)
1954
+ * TCP_Server_Info->req_lock TCP_Server_Info->in_flight cifs_get_tcp_session
1955
+ * ->credits
1956
+ * ->echo_credits
1957
+ * ->oplock_credits
1958
+ * ->reconnect_instance
1959
+ * cifs_ses->ses_lock (anything that is not protected by another lock and can change)
1960
+ * cifs_ses->iface_lock cifs_ses->iface_list sesInfoAlloc
1961
+ * ->iface_count
1962
+ * ->iface_last_update
1963
+ * cifs_ses->chan_lock cifs_ses->chans
1964
+ * ->chans_need_reconnect
1965
+ * ->chans_in_reconnect
1966
+ * cifs_tcon->tc_lock (anything that is not protected by another lock and can change)
1967
+ * cifsInodeInfo->open_file_lock cifsInodeInfo->openFileList cifs_alloc_inode
1968
+ * cifsInodeInfo->writers_lock cifsInodeInfo->writers cifsInodeInfo_alloc
1969
+ * cifsInodeInfo->lock_sem cifsInodeInfo->llist cifs_init_once
1970
+ * ->can_cache_brlcks
1971
+ * cifsInodeInfo->deferred_lock cifsInodeInfo->deferred_closes cifsInodeInfo_alloc
1972
+ * cached_fid->fid_mutex cifs_tcon->crfid tconInfoAlloc
1973
+ * cifsFileInfo->fh_mutex cifsFileInfo cifs_new_fileinfo
1974
+ * cifsFileInfo->file_info_lock cifsFileInfo->count cifs_new_fileinfo
1975
+ * ->invalidHandle initiate_cifs_search
1976
+ * ->oplock_break_cancelled
1977
+ * cifs_aio_ctx->aio_mutex cifs_aio_ctx cifs_aio_ctx_alloc
1929
1978
****************************************************************************/
1930
1979
1931
1980
#ifdef DECLARE_GLOBALS_HERE
@@ -1946,9 +1995,7 @@ extern struct list_head cifs_tcp_ses_list;
1946
1995
/*
1947
1996
* This lock protects the cifs_tcp_ses_list, the list of smb sessions per
1948
1997
* tcp session, and the list of tcon's per smb session. It also protects
1949
- * the reference counters for the server, smb session, and tcon. It also
1950
- * protects some fields in the TCP_Server_Info struct such as dstaddr. Finally,
1951
- * changes to the tcon->tidStatus should be done while holding this lock.
1998
+ * the reference counters for the server, smb session, and tcon.
1952
1999
* generally the locks should be taken in order tcp_ses_lock before
1953
2000
* tcon->open_file_lock and that before file->file_info_lock since the
1954
2001
* structure order is cifs_socket-->cifs_ses-->cifs_tcon-->cifs_file
0 commit comments