1 // SPDX-License-Identifier: GPL-2.0
3 /* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
4 * Copyright (c) 2012, 2015, Intel Corporation.
7 /* This file is part of Lustre, http://www.lustre.org/
9 * Author: liang@whamcloud.com
12 #define DEBUG_SUBSYSTEM S_LNET
14 #include <lnet/lib-lnet.h>
16 /** destroy cpu-partition lock, see libcfs_private.h for more detail */
18 cfs_percpt_lock_free(struct cfs_percpt_lock *pcl)
20 LASSERT(pcl->pcl_locks != NULL);
21 LASSERT(!pcl->pcl_locked);
23 cfs_percpt_free(pcl->pcl_locks);
24 LIBCFS_FREE(pcl, sizeof(*pcl));
26 EXPORT_SYMBOL(cfs_percpt_lock_free);
29 * create cpu-partition lock, see libcfs_private.h for more detail.
31 * cpu-partition lock is designed for large-scale SMP system, so we need to
32 * reduce cacheline conflict as possible as we can, that's the
33 * reason we always allocate cacheline-aligned memory block.
35 struct cfs_percpt_lock *
36 cfs_percpt_lock_create(struct cfs_cpt_table *cptab,
37 struct lock_class_key *keys)
39 struct cfs_percpt_lock *pcl;
43 /* NB: cptab can be NULL, pcl will be for HW CPUs on that case */
44 LIBCFS_ALLOC(pcl, sizeof(*pcl));
48 pcl->pcl_cptab = cptab;
49 pcl->pcl_locks = cfs_percpt_alloc(cptab, sizeof(*lock));
50 if (pcl->pcl_locks == NULL) {
51 LIBCFS_FREE(pcl, sizeof(*pcl));
56 CWARN("Cannot setup class key for percpt lock, you may see recursive locking warnings which are actually fake.\n");
59 cfs_percpt_for_each(lock, i, pcl->pcl_locks) {
62 lockdep_set_class(lock, &keys[i]);
67 EXPORT_SYMBOL(cfs_percpt_lock_create);
70 * lock a CPU partition
72 * \a index != CFS_PERCPT_LOCK_EX
73 * hold private lock indexed by \a index
75 * \a index == CFS_PERCPT_LOCK_EX
76 * exclusively lock @pcl and nobody can take private lock
79 cfs_percpt_lock(struct cfs_percpt_lock *pcl, int index)
80 __acquires(pcl->pcl_locks)
82 int ncpt = cfs_cpt_number(pcl->pcl_cptab);
85 LASSERT(index >= CFS_PERCPT_LOCK_EX && index < ncpt);
89 } else { /* serialize with exclusive lock */
90 while (pcl->pcl_locked)
94 if (likely(index != CFS_PERCPT_LOCK_EX)) {
95 spin_lock(pcl->pcl_locks[index]);
99 /* exclusive lock request */
100 for (i = 0; i < ncpt; i++) {
101 spin_lock(pcl->pcl_locks[i]);
103 LASSERT(!pcl->pcl_locked);
104 /* nobody should take private lock after this
105 * so I wouldn't starve for too long time
111 EXPORT_SYMBOL(cfs_percpt_lock);
113 /** unlock a CPU partition */
115 cfs_percpt_unlock(struct cfs_percpt_lock *pcl, int index)
116 __releases(pcl->pcl_locks)
118 int ncpt = cfs_cpt_number(pcl->pcl_cptab);
121 index = ncpt == 1 ? 0 : index;
123 if (likely(index != CFS_PERCPT_LOCK_EX)) {
124 spin_unlock(pcl->pcl_locks[index]);
128 for (i = ncpt - 1; i >= 0; i--) {
130 LASSERT(pcl->pcl_locked);
133 spin_unlock(pcl->pcl_locks[i]);
136 EXPORT_SYMBOL(cfs_percpt_unlock);