Whamcloud - gitweb
LU-6142 lnet: SPDX for lnet/include/ and misc files
[fs/lustre-release.git] / lnet / include / lnet / lock.h
1 // SPDX-License-Identifier: GPL-2.0
2
3 /* This file is part of Lustre, http://www.lustre.org/
4  *
5  * percpu partition lock
6  *
7  * There are some use-cases like this in Lustre:
8  * . each CPU partition has it's own private data which is frequently changed,
9  *   and mostly by the local CPU partition.
10  * . all CPU partitions share some global data, these data are rarely changed.
11  *
12  * LNet is typical example.
13  * CPU partition lock is designed for this kind of use-cases:
14  * . each CPU partition has it's own private lock
15  * . change on private data just needs to take the private lock
16  * . read on shared data just needs to take _any_ of private locks
17  * . change on shared data needs to take _all_ private locks,
18  *   which is slow and should be really rare.
19  */
20
21 enum {
22         CFS_PERCPT_LOCK_EX      = -1,   /* negative */
23 };
24
25 struct cfs_percpt_lock {
26         /* cpu-partition-table for this lock */
27         struct cfs_cpt_table     *pcl_cptab;
28         /* exclusively locked */
29         unsigned int              pcl_locked;
30         /* private lock table */
31         spinlock_t              **pcl_locks;
32 };
33
34 /* return number of private locks */
35 #define cfs_percpt_lock_num(pcl)        cfs_cpt_number(pcl->pcl_cptab)
36
37 /* create a cpu-partition lock based on CPU partition table \a cptab,
38  * each private lock has extra \a psize bytes padding data
39  */
40 struct cfs_percpt_lock *cfs_percpt_lock_create(struct cfs_cpt_table *cptab,
41                                                struct lock_class_key *keys);
42 /* destroy a cpu-partition lock */
43 void cfs_percpt_lock_free(struct cfs_percpt_lock *pcl);
44
45 /* lock private lock \a index of \a pcl */
46 void cfs_percpt_lock(struct cfs_percpt_lock *pcl, int index);
47
48 /* unlock private lock \a index of \a pcl */
49 void cfs_percpt_unlock(struct cfs_percpt_lock *pcl, int index);
50
51 #define CFS_PERCPT_LOCK_KEYS    256
52
53 /* NB: don't allocate keys dynamically, lockdep needs them to be in ".data" */
54 #define cfs_percpt_lock_alloc(cptab)                                    \
55 ({                                                                      \
56         static struct lock_class_key ___keys[CFS_PERCPT_LOCK_KEYS];     \
57         struct cfs_percpt_lock *___lk;                                  \
58                                                                         \
59         if (cfs_cpt_number(cptab) > CFS_PERCPT_LOCK_KEYS)               \
60                 ___lk = cfs_percpt_lock_create(cptab, NULL);            \
61         else                                                            \
62                 ___lk = cfs_percpt_lock_create(cptab, ___keys);         \
63         ___lk;                                                          \
64 })