1 // SPDX-License-Identifier: GPL-2.0
3 /* This file is part of Lustre, http://www.lustre.org/
5 * percpu partition lock
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.
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.
22 CFS_PERCPT_LOCK_EX = -1, /* negative */
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;
34 /* return number of private locks */
35 #define cfs_percpt_lock_num(pcl) cfs_cpt_number(pcl->pcl_cptab)
37 /* create a cpu-partition lock based on CPU partition table \a cptab,
38 * each private lock has extra \a psize bytes padding data
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);
45 /* lock private lock \a index of \a pcl */
46 void cfs_percpt_lock(struct cfs_percpt_lock *pcl, int index);
48 /* unlock private lock \a index of \a pcl */
49 void cfs_percpt_unlock(struct cfs_percpt_lock *pcl, int index);
51 #define CFS_PERCPT_LOCK_KEYS 256
53 /* NB: don't allocate keys dynamically, lockdep needs them to be in ".data" */
54 #define cfs_percpt_lock_alloc(cptab) \
56 static struct lock_class_key ___keys[CFS_PERCPT_LOCK_KEYS]; \
57 struct cfs_percpt_lock *___lk; \
59 if (cfs_cpt_number(cptab) > CFS_PERCPT_LOCK_KEYS) \
60 ___lk = cfs_percpt_lock_create(cptab, NULL); \
62 ___lk = cfs_percpt_lock_create(cptab, ___keys); \