4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
18 /* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
19 * Copyright (c) 2012, 2015 Intel Corporation.
22 * This file is part of Lustre, http://www.lustre.org/
23 * Lustre is a trademark of Sun Microsystems, Inc.
25 * Author: liang@whamcloud.com
28 #define DEBUG_SUBSYSTEM S_LNET
30 #include "../../include/linux/libcfs/libcfs.h"
32 /** destroy cpu-partition lock, see libcfs_private.h for more detail */
34 cfs_percpt_lock_free(struct cfs_percpt_lock *pcl)
36 LASSERT(pcl->pcl_locks);
37 LASSERT(!pcl->pcl_locked);
39 cfs_percpt_free(pcl->pcl_locks);
40 LIBCFS_FREE(pcl, sizeof(*pcl));
42 EXPORT_SYMBOL(cfs_percpt_lock_free);
45 * create cpu-partition lock, see libcfs_private.h for more detail.
47 * cpu-partition lock is designed for large-scale SMP system, so we need to
48 * reduce cacheline conflict as possible as we can, that's the
49 * reason we always allocate cacheline-aligned memory block.
51 struct cfs_percpt_lock *
52 cfs_percpt_lock_create(struct cfs_cpt_table *cptab,
53 struct lock_class_key *keys)
55 struct cfs_percpt_lock *pcl;
59 /* NB: cptab can be NULL, pcl will be for HW CPUs on that case */
60 LIBCFS_ALLOC(pcl, sizeof(*pcl));
64 pcl->pcl_cptab = cptab;
65 pcl->pcl_locks = cfs_percpt_alloc(cptab, sizeof(*lock));
66 if (!pcl->pcl_locks) {
67 LIBCFS_FREE(pcl, sizeof(*pcl));
72 CWARN("Cannot setup class key for percpt lock, you may see recursive locking warnings which are actually fake.\n");
74 cfs_percpt_for_each(lock, i, pcl->pcl_locks) {
77 lockdep_set_class(lock, &keys[i]);
82 EXPORT_SYMBOL(cfs_percpt_lock_create);
85 * lock a CPU partition
87 * \a index != CFS_PERCPT_LOCK_EX
88 * hold private lock indexed by \a index
90 * \a index == CFS_PERCPT_LOCK_EX
91 * exclusively lock @pcl and nobody can take private lock
94 cfs_percpt_lock(struct cfs_percpt_lock *pcl, int index)
95 __acquires(pcl->pcl_locks)
97 int ncpt = cfs_cpt_number(pcl->pcl_cptab);
100 LASSERT(index >= CFS_PERCPT_LOCK_EX && index < ncpt);
104 } else { /* serialize with exclusive lock */
105 while (pcl->pcl_locked)
109 if (likely(index != CFS_PERCPT_LOCK_EX)) {
110 spin_lock(pcl->pcl_locks[index]);
114 /* exclusive lock request */
115 for (i = 0; i < ncpt; i++) {
116 spin_lock(pcl->pcl_locks[i]);
118 LASSERT(!pcl->pcl_locked);
119 /* nobody should take private lock after this
120 * so I wouldn't starve for too long time
126 EXPORT_SYMBOL(cfs_percpt_lock);
128 /** unlock a CPU partition */
130 cfs_percpt_unlock(struct cfs_percpt_lock *pcl, int index)
131 __releases(pcl->pcl_locks)
133 int ncpt = cfs_cpt_number(pcl->pcl_cptab);
136 index = ncpt == 1 ? 0 : index;
138 if (likely(index != CFS_PERCPT_LOCK_EX)) {
139 spin_unlock(pcl->pcl_locks[index]);
143 for (i = ncpt - 1; i >= 0; i--) {
145 LASSERT(pcl->pcl_locked);
148 spin_unlock(pcl->pcl_locks[i]);
151 EXPORT_SYMBOL(cfs_percpt_unlock);