X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fobdclass%2Flustre_handles.c;h=9c91df35d2326726dac9bc6520081dc6aaa979a2;hp=dfdfec41a3369f955110e23f27a27c5b2192446e;hb=56293e79aec17670718dcaf50a733ec5119210d2;hpb=a25adb47c7b7eeb68a922e2647d74eeff3401c6a diff --git a/lustre/obdclass/lustre_handles.c b/lustre/obdclass/lustre_handles.c index dfdfec4..9c91df3 100644 --- a/lustre/obdclass/lustre_handles.c +++ b/lustre/obdclass/lustre_handles.c @@ -1,26 +1,41 @@ /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * - * Copyright (C) 2002 Cluster File Systems, Inc. - * Author: Phil Schwan + * GPL HEADER START * - * This file is part of the Lustre file system, http://www.lustre.org - * Lustre is a trademark of Cluster File Systems, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * You may have signed or agreed to another license before downloading - * this software. If so, you are bound by the terms and conditions - * of that agreement, and the following does not apply to you. See the - * LICENSE file included with this distribution for more information. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. * - * If you did not agree to a different license, then this copy of Lustre - * is open source software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). * - * In either case, Lustre is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * license text for more details. + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see + * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + * GPL HEADER END + */ +/* + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Use is subject to license terms. + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + * Lustre is a trademark of Sun Microsystems, Inc. + * + * lustre/obdclass/lustre_handles.c + * + * Author: Phil Schwan */ #define DEBUG_SUBSYSTEM S_CLASS @@ -33,26 +48,36 @@ #include #if !defined(HAVE_RCU) || !defined(__KERNEL__) -# define list_add_rcu list_add -# define list_del_rcu list_del -# define list_for_each_rcu list_for_each -# define list_for_each_safe_rcu list_for_each_safe -# define rcu_read_lock() spin_lock(&bucket->lock) -# define rcu_read_unlock() spin_unlock(&bucket->lock) +# define list_add_rcu cfs_list_add +# define list_del_rcu cfs_list_del +# define list_for_each_rcu cfs_list_for_each +# define list_for_each_safe_rcu cfs_list_for_each_safe +# define list_for_each_entry_rcu cfs_list_for_each_entry +# define rcu_read_lock() cfs_spin_lock(&bucket->lock) +# define rcu_read_unlock() cfs_spin_unlock(&bucket->lock) #endif /* ifndef HAVE_RCU */ static __u64 handle_base; #define HANDLE_INCR 7 -static spinlock_t handle_base_lock; +static cfs_spinlock_t handle_base_lock; static struct handle_bucket { - spinlock_t lock; - struct list_head head; + cfs_spinlock_t lock; + cfs_list_t head; } *handle_hash; -static atomic_t handle_count = ATOMIC_INIT(0); +static cfs_atomic_t handle_count = CFS_ATOMIC_INIT(0); +#ifdef __arch_um__ +/* For unknown reason, UML uses kmalloc rather than vmalloc to allocate + * memory(OBD_VMALLOC). Therefore, we have to redefine the + * HANDLE_HASH_SIZE to make the hash heads don't exceed 128K. + */ +#define HANDLE_HASH_SIZE 4096 +#else #define HANDLE_HASH_SIZE (1 << 14) +#endif /* ifdef __arch_um__ */ + #define HANDLE_HASH_MASK (HANDLE_HASH_SIZE - 1) /* @@ -65,13 +90,13 @@ void class_handle_hash(struct portals_handle *h, portals_handle_addref_cb cb) ENTRY; LASSERT(h != NULL); - LASSERT(list_empty(&h->h_link)); + LASSERT(cfs_list_empty(&h->h_link)); /* * This is fast, but simplistic cookie generation algorithm, it will * need a re-do at some point in the future for security. */ - spin_lock(&handle_base_lock); + cfs_spin_lock(&handle_base_lock); handle_base += HANDLE_INCR; h->h_cookie = handle_base; @@ -84,17 +109,17 @@ void class_handle_hash(struct portals_handle *h, portals_handle_addref_cb cb) CWARN("The universe has been exhausted: cookie wrap-around.\n"); handle_base += HANDLE_INCR; } - spin_unlock(&handle_base_lock); + cfs_spin_unlock(&handle_base_lock); - atomic_inc(&handle_count); + cfs_atomic_inc(&handle_count); h->h_addref = cb; - spin_lock_init(&h->h_lock); + cfs_spin_lock_init(&h->h_lock); bucket = &handle_hash[h->h_cookie & HANDLE_HASH_MASK]; - spin_lock(&bucket->lock); + cfs_spin_lock(&bucket->lock); list_add_rcu(&h->h_link, &bucket->head); h->h_in = 1; - spin_unlock(&bucket->lock); + cfs_spin_unlock(&bucket->lock); CDEBUG(D_INFO, "added object %p with handle "LPX64" to hash\n", h, h->h_cookie); @@ -103,7 +128,7 @@ void class_handle_hash(struct portals_handle *h, portals_handle_addref_cb cb) static void class_handle_unhash_nolock(struct portals_handle *h) { - if (list_empty(&h->h_link)) { + if (cfs_list_empty(&h->h_link)) { CERROR("removing an already-removed handle ("LPX64")\n", h->h_cookie); return; @@ -112,13 +137,13 @@ static void class_handle_unhash_nolock(struct portals_handle *h) CDEBUG(D_INFO, "removing object %p with handle "LPX64" from hash\n", h, h->h_cookie); - spin_lock(&h->h_lock); + cfs_spin_lock(&h->h_lock); if (h->h_in == 0) { - spin_unlock(&h->h_lock); + cfs_spin_unlock(&h->h_lock); return; } h->h_in = 0; - spin_unlock(&h->h_lock); + cfs_spin_unlock(&h->h_lock); list_del_rcu(&h->h_link); } @@ -127,11 +152,11 @@ void class_handle_unhash(struct portals_handle *h) struct handle_bucket *bucket; bucket = handle_hash + (h->h_cookie & HANDLE_HASH_MASK); - spin_lock(&bucket->lock); + cfs_spin_lock(&bucket->lock); class_handle_unhash_nolock(h); - spin_unlock(&bucket->lock); + cfs_spin_unlock(&bucket->lock); - atomic_dec(&handle_count); + cfs_atomic_dec(&handle_count); } void class_handle_hash_back(struct portals_handle *h) @@ -141,11 +166,11 @@ void class_handle_hash_back(struct portals_handle *h) bucket = handle_hash + (h->h_cookie & HANDLE_HASH_MASK); - atomic_inc(&handle_count); - spin_lock(&bucket->lock); + cfs_atomic_inc(&handle_count); + cfs_spin_lock(&bucket->lock); list_add_rcu(&h->h_link, &bucket->head); h->h_in = 1; - spin_unlock(&bucket->lock); + cfs_spin_unlock(&bucket->lock); EXIT; } @@ -153,7 +178,7 @@ void class_handle_hash_back(struct portals_handle *h) void *class_handle2object(__u64 cookie) { struct handle_bucket *bucket; - struct list_head *tmp; + struct portals_handle *h; void *retval = NULL; ENTRY; @@ -164,18 +189,16 @@ void *class_handle2object(__u64 cookie) bucket = handle_hash + (cookie & HANDLE_HASH_MASK); rcu_read_lock(); - list_for_each_rcu(tmp, &bucket->head) { - struct portals_handle *h; - h = list_entry(tmp, struct portals_handle, h_link); + list_for_each_entry_rcu(h, &bucket->head, h_link) { if (h->h_cookie != cookie) continue; - spin_lock(&h->h_lock); - if (likely(h->h_cookie != 0)) { + cfs_spin_lock(&h->h_lock); + if (likely(h->h_in != 0)) { h->h_addref(h); retval = h; } - spin_unlock(&h->h_lock); + cfs_spin_unlock(&h->h_lock); break; } rcu_read_unlock(); @@ -183,7 +206,7 @@ void *class_handle2object(__u64 cookie) RETURN(retval); } -void class_handle_free_cb(struct rcu_head *rcu) +void class_handle_free_cb(cfs_rcu_head_t *rcu) { struct portals_handle *h = RCU2HANDLE(rcu); if (h->h_free_cb) { @@ -198,6 +221,8 @@ void class_handle_free_cb(struct rcu_head *rcu) int class_handle_init(void) { struct handle_bucket *bucket; + struct timeval tv; + int seed[2]; LASSERT(handle_hash == NULL); @@ -205,13 +230,19 @@ int class_handle_init(void) if (handle_hash == NULL) return -ENOMEM; - spin_lock_init(&handle_base_lock); + cfs_spin_lock_init(&handle_base_lock); for (bucket = handle_hash + HANDLE_HASH_SIZE - 1; bucket >= handle_hash; bucket--) { CFS_INIT_LIST_HEAD(&bucket->head); - spin_lock_init(&bucket->lock); + cfs_spin_lock_init(&bucket->lock); } - ll_get_random_bytes(&handle_base, sizeof(handle_base)); + + /** bug 21430: add randomness to the initial base */ + cfs_get_random_bytes(seed, sizeof(seed)); + cfs_gettimeofday(&tv); + cfs_srand(tv.tv_sec ^ seed[0], tv.tv_usec ^ seed[1]); + + cfs_get_random_bytes(&handle_base, sizeof(handle_base)); LASSERT(handle_base != 0ULL); return 0; @@ -222,18 +253,16 @@ static void cleanup_all_handles(void) int i; for (i = 0; i < HANDLE_HASH_SIZE; i++) { - struct list_head *tmp, *pos; - spin_lock(&handle_hash[i].lock); - list_for_each_safe_rcu(tmp, pos, &(handle_hash[i].head)) { - struct portals_handle *h; - h = list_entry(tmp, struct portals_handle, h_link); + struct portals_handle *h; + cfs_spin_lock(&handle_hash[i].lock); + list_for_each_entry_rcu(h, &(handle_hash[i].head), h_link) { CERROR("force clean handle "LPX64" addr %p addref %p\n", h->h_cookie, h, h->h_addref); class_handle_unhash_nolock(h); } - spin_unlock(&handle_hash[i].lock); + cfs_spin_unlock(&handle_hash[i].lock); } } @@ -242,7 +271,7 @@ void class_handle_cleanup(void) int count; LASSERT(handle_hash != NULL); - count = atomic_read(&handle_count); + count = cfs_atomic_read(&handle_count); if (count != 0) { CERROR("handle_count at cleanup: %d\n", count); cleanup_all_handles(); @@ -251,6 +280,6 @@ void class_handle_cleanup(void) OBD_VFREE(handle_hash, sizeof(*handle_hash) * HANDLE_HASH_SIZE); handle_hash = NULL; - if (atomic_read(&handle_count)) - CERROR("leaked %d handles\n", atomic_read(&handle_count)); + if (cfs_atomic_read(&handle_count)) + CERROR("leaked %d handles\n", cfs_atomic_read(&handle_count)); }