X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fobdclass%2Flu_ref.c;h=15419490d121d5b41edc566b62e646b943d9290d;hb=26c55b24d8745f3384370c8dcf1c1f302e19805d;hp=fdaac5fddca42d29085ebce958a7e7522fae2c3c;hpb=a6527b28ba2082a445fbf584909a7791ce407ef3;p=fs%2Flustre-release.git diff --git a/lustre/obdclass/lu_ref.c b/lustre/obdclass/lu_ref.c index fdaac5f..1541949 100644 --- a/lustre/obdclass/lu_ref.c +++ b/lustre/obdclass/lu_ref.c @@ -1,6 +1,4 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * +/* * GPL HEADER START * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -28,6 +26,8 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2012, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -41,9 +41,6 @@ */ #define DEBUG_SUBSYSTEM S_CLASS -#ifndef EXPORT_SYMTAB -# define EXPORT_SYMTAB -#endif #ifdef __KERNEL__ # include @@ -62,27 +59,19 @@ * Asserts a condition for a given lu_ref. Must be called with * lu_ref::lf_guard held. */ -#define REFASSERT(ref, expr) \ - do { \ - struct lu_ref *__ref = (ref); \ - \ - if (unlikely(!(expr))) { \ - lu_ref_print(__ref); \ - cfs_spin_unlock(&__ref->lf_guard); \ - lu_ref_print_all(); \ - LASSERT(0); \ - cfs_spin_lock(&__ref->lf_guard); \ - } \ - } while (0) - -struct lu_ref_link { - struct lu_ref *ll_ref; - cfs_list_t ll_linkage; - const char *ll_scope; - const void *ll_source; -}; - -static cfs_mem_cache_t *lu_ref_link_kmem; +#define REFASSERT(ref, expr) do { \ + struct lu_ref *__tmp = (ref); \ + \ + if (unlikely(!(expr))) { \ + lu_ref_print(__tmp); \ + spin_unlock(&__tmp->lf_guard); \ + lu_ref_print_all(); \ + LASSERT(0); \ + spin_lock(&__tmp->lf_guard); \ + } \ +} while (0) + +static struct kmem_cache *lu_ref_link_kmem; static struct lu_kmem_descr lu_ref_caches[] = { { @@ -101,11 +90,11 @@ static struct lu_kmem_descr lu_ref_caches[] = { * Protected by lu_ref_refs_guard. */ static CFS_LIST_HEAD(lu_ref_refs); -static cfs_spinlock_t lu_ref_refs_guard; +static spinlock_t lu_ref_refs_guard; static struct lu_ref lu_ref_marker = { - .lf_guard = CFS_SPIN_LOCK_UNLOCKED, - .lf_list = CFS_LIST_HEAD_INIT(lu_ref_marker.lf_list), - .lf_linkage = CFS_LIST_HEAD_INIT(lu_ref_marker.lf_linkage) + .lf_guard = __SPIN_LOCK_UNLOCKED(lu_ref_marker.lf_guard), + .lf_list = CFS_LIST_HEAD_INIT(lu_ref_marker.lf_list), + .lf_linkage = CFS_LIST_HEAD_INIT(lu_ref_marker.lf_linkage) }; void lu_ref_print(const struct lu_ref *ref) @@ -127,46 +116,46 @@ static int lu_ref_is_marker(const struct lu_ref *ref) void lu_ref_print_all(void) { - struct lu_ref *ref; - - cfs_spin_lock(&lu_ref_refs_guard); - cfs_list_for_each_entry(ref, &lu_ref_refs, lf_linkage) { - if (lu_ref_is_marker(ref)) - continue; - - cfs_spin_lock(&ref->lf_guard); - lu_ref_print(ref); - cfs_spin_unlock(&ref->lf_guard); - } - cfs_spin_unlock(&lu_ref_refs_guard); + struct lu_ref *ref; + + spin_lock(&lu_ref_refs_guard); + cfs_list_for_each_entry(ref, &lu_ref_refs, lf_linkage) { + if (lu_ref_is_marker(ref)) + continue; + + spin_lock(&ref->lf_guard); + lu_ref_print(ref); + spin_unlock(&ref->lf_guard); + } + spin_unlock(&lu_ref_refs_guard); } EXPORT_SYMBOL(lu_ref_print_all); void lu_ref_init_loc(struct lu_ref *ref, const char *func, const int line) { - ref->lf_refs = 0; - ref->lf_func = func; - ref->lf_line = line; - cfs_spin_lock_init(&ref->lf_guard); - CFS_INIT_LIST_HEAD(&ref->lf_list); - cfs_spin_lock(&lu_ref_refs_guard); - cfs_list_add(&ref->lf_linkage, &lu_ref_refs); - cfs_spin_unlock(&lu_ref_refs_guard); + ref->lf_refs = 0; + ref->lf_func = func; + ref->lf_line = line; + spin_lock_init(&ref->lf_guard); + CFS_INIT_LIST_HEAD(&ref->lf_list); + spin_lock(&lu_ref_refs_guard); + cfs_list_add(&ref->lf_linkage, &lu_ref_refs); + spin_unlock(&lu_ref_refs_guard); } EXPORT_SYMBOL(lu_ref_init_loc); void lu_ref_fini(struct lu_ref *ref) { - REFASSERT(ref, cfs_list_empty(&ref->lf_list)); - REFASSERT(ref, ref->lf_refs == 0); - cfs_spin_lock(&lu_ref_refs_guard); - cfs_list_del_init(&ref->lf_linkage); - cfs_spin_unlock(&lu_ref_refs_guard); + REFASSERT(ref, cfs_list_empty(&ref->lf_list)); + REFASSERT(ref, ref->lf_refs == 0); + spin_lock(&lu_ref_refs_guard); + cfs_list_del_init(&ref->lf_linkage); + spin_unlock(&lu_ref_refs_guard); } EXPORT_SYMBOL(lu_ref_fini); static struct lu_ref_link *lu_ref_add_context(struct lu_ref *ref, - enum cfs_alloc_flags flags, + int flags, const char *scope, const void *source) { @@ -179,38 +168,50 @@ static struct lu_ref_link *lu_ref_add_context(struct lu_ref *ref, link->ll_ref = ref; link->ll_scope = scope; link->ll_source = source; - cfs_spin_lock(&ref->lf_guard); - cfs_list_add_tail(&link->ll_linkage, &ref->lf_list); - ref->lf_refs++; - cfs_spin_unlock(&ref->lf_guard); - } - } - - if (link == NULL) { - cfs_spin_lock(&ref->lf_guard); - ref->lf_failed++; - cfs_spin_unlock(&ref->lf_guard); - link = ERR_PTR(-ENOMEM); - } - - return link; + spin_lock(&ref->lf_guard); + cfs_list_add_tail(&link->ll_linkage, &ref->lf_list); + ref->lf_refs++; + spin_unlock(&ref->lf_guard); + } + } + + if (link == NULL) { + spin_lock(&ref->lf_guard); + ref->lf_failed++; + spin_unlock(&ref->lf_guard); + link = ERR_PTR(-ENOMEM); + } + + return link; } -struct lu_ref_link *lu_ref_add(struct lu_ref *ref, const char *scope, - const void *source) +void lu_ref_add(struct lu_ref *ref, const char *scope, const void *source) { - cfs_might_sleep(); - return lu_ref_add_context(ref, CFS_ALLOC_STD, scope, source); + might_sleep(); + lu_ref_add_context(ref, GFP_IOFS, scope, source); } EXPORT_SYMBOL(lu_ref_add); +void lu_ref_add_at(struct lu_ref *ref, struct lu_ref_link *link, + const char *scope, const void *source) +{ + link->ll_ref = ref; + link->ll_scope = scope; + link->ll_source = source; + spin_lock(&ref->lf_guard); + cfs_list_add_tail(&link->ll_linkage, &ref->lf_list); + ref->lf_refs++; + spin_unlock(&ref->lf_guard); +} +EXPORT_SYMBOL(lu_ref_add_at); + /** * Version of lu_ref_add() to be used in non-blockable contexts. */ -struct lu_ref_link *lu_ref_add_atomic(struct lu_ref *ref, const char *scope, - const void *source) +void lu_ref_add_atomic(struct lu_ref *ref, const char *scope, + const void *source) { - return lu_ref_add_context(ref, CFS_ALLOC_ATOMIC, scope, source); + lu_ref_add_context(ref, GFP_ATOMIC, scope, source); } EXPORT_SYMBOL(lu_ref_add_atomic); @@ -239,7 +240,7 @@ static struct lu_ref_link *lu_ref_find(struct lu_ref *ref, const char *scope, ++iterations; if (lu_ref_link_eq(link, scope, source)) { if (iterations > lu_ref_chain_max_length) { - CWARN("Long lu_ref chain %i \"%s\":%p\n", + CWARN("Long lu_ref chain %d \"%s\":%p\n", iterations, scope, source); lu_ref_chain_max_length = iterations * 3 / 2; } @@ -251,56 +252,47 @@ static struct lu_ref_link *lu_ref_find(struct lu_ref *ref, const char *scope, void lu_ref_del(struct lu_ref *ref, const char *scope, const void *source) { - struct lu_ref_link *link; - - cfs_spin_lock(&ref->lf_guard); - link = lu_ref_find(ref, scope, source); - if (link != NULL) { - cfs_list_del(&link->ll_linkage); - ref->lf_refs--; - cfs_spin_unlock(&ref->lf_guard); - OBD_SLAB_FREE(link, lu_ref_link_kmem, sizeof(*link)); - } else { - REFASSERT(ref, ref->lf_failed > 0); - ref->lf_failed--; - cfs_spin_unlock(&ref->lf_guard); - } + struct lu_ref_link *link; + + spin_lock(&ref->lf_guard); + link = lu_ref_find(ref, scope, source); + if (link != NULL) { + cfs_list_del(&link->ll_linkage); + ref->lf_refs--; + spin_unlock(&ref->lf_guard); + OBD_SLAB_FREE(link, lu_ref_link_kmem, sizeof(*link)); + } else { + REFASSERT(ref, ref->lf_failed > 0); + ref->lf_failed--; + spin_unlock(&ref->lf_guard); + } } EXPORT_SYMBOL(lu_ref_del); void lu_ref_set_at(struct lu_ref *ref, struct lu_ref_link *link, - const char *scope, - const void *source0, const void *source1) + const char *scope, + const void *source0, const void *source1) { - cfs_spin_lock(&ref->lf_guard); - if (link != ERR_PTR(-ENOMEM)) { - REFASSERT(ref, link->ll_ref == ref); - REFASSERT(ref, lu_ref_link_eq(link, scope, source0)); - link->ll_source = source1; - } else { - REFASSERT(ref, ref->lf_failed > 0); - } - cfs_spin_unlock(&ref->lf_guard); + REFASSERT(ref, link != NULL && !IS_ERR(link)); + + spin_lock(&ref->lf_guard); + REFASSERT(ref, link->ll_ref == ref); + REFASSERT(ref, lu_ref_link_eq(link, scope, source0)); + link->ll_source = source1; + spin_unlock(&ref->lf_guard); } EXPORT_SYMBOL(lu_ref_set_at); void lu_ref_del_at(struct lu_ref *ref, struct lu_ref_link *link, - const char *scope, const void *source) + const char *scope, const void *source) { - if (link != ERR_PTR(-ENOMEM)) { - cfs_spin_lock(&ref->lf_guard); - REFASSERT(ref, link->ll_ref == ref); - REFASSERT(ref, lu_ref_link_eq(link, scope, source)); - cfs_list_del(&link->ll_linkage); - ref->lf_refs--; - cfs_spin_unlock(&ref->lf_guard); - OBD_SLAB_FREE(link, lu_ref_link_kmem, sizeof(*link)); - } else { - cfs_spin_lock(&ref->lf_guard); - REFASSERT(ref, ref->lf_failed > 0); - ref->lf_failed--; - cfs_spin_unlock(&ref->lf_guard); - } + REFASSERT(ref, link != NULL && !IS_ERR(link)); + spin_lock(&ref->lf_guard); + REFASSERT(ref, link->ll_ref == ref); + REFASSERT(ref, lu_ref_link_eq(link, scope, source)); + cfs_list_del(&link->ll_linkage); + ref->lf_refs--; + spin_unlock(&ref->lf_guard); } EXPORT_SYMBOL(lu_ref_del_at); @@ -308,14 +300,14 @@ EXPORT_SYMBOL(lu_ref_del_at); static void *lu_ref_seq_start(struct seq_file *seq, loff_t *pos) { - struct lu_ref *ref = seq->private; + struct lu_ref *ref = seq->private; - cfs_spin_lock(&lu_ref_refs_guard); - if (cfs_list_empty(&ref->lf_linkage)) - ref = NULL; - cfs_spin_unlock(&lu_ref_refs_guard); + spin_lock(&lu_ref_refs_guard); + if (cfs_list_empty(&ref->lf_linkage)) + ref = NULL; + spin_unlock(&lu_ref_refs_guard); - return ref; + return ref; } static void *lu_ref_seq_next(struct seq_file *seq, void *p, loff_t *pos) @@ -326,16 +318,16 @@ static void *lu_ref_seq_next(struct seq_file *seq, void *p, loff_t *pos) LASSERT(seq->private == p); LASSERT(!cfs_list_empty(&ref->lf_linkage)); - cfs_spin_lock(&lu_ref_refs_guard); - next = cfs_list_entry(ref->lf_linkage.next, struct lu_ref, lf_linkage); - if (&next->lf_linkage == &lu_ref_refs) { - p = NULL; - } else { - (*pos)++; - cfs_list_move(&ref->lf_linkage, &next->lf_linkage); - } - cfs_spin_unlock(&lu_ref_refs_guard); - return p; + spin_lock(&lu_ref_refs_guard); + next = cfs_list_entry(ref->lf_linkage.next, struct lu_ref, lf_linkage); + if (&next->lf_linkage == &lu_ref_refs) { + p = NULL; + } else { + (*pos)++; + cfs_list_move(&ref->lf_linkage, &next->lf_linkage); + } + spin_unlock(&lu_ref_refs_guard); + return p; } static void lu_ref_seq_stop(struct seq_file *seq, void *p) @@ -346,19 +338,18 @@ static void lu_ref_seq_stop(struct seq_file *seq, void *p) static int lu_ref_seq_show(struct seq_file *seq, void *p) { - struct lu_ref *ref = p; - struct lu_ref *next; - - cfs_spin_lock(&lu_ref_refs_guard); - next = cfs_list_entry(ref->lf_linkage.next, struct lu_ref, lf_linkage); - if ((&next->lf_linkage == &lu_ref_refs) || lu_ref_is_marker(next)) { - cfs_spin_unlock(&lu_ref_refs_guard); - return 0; - } - - /* print the entry */ - - cfs_spin_lock(&next->lf_guard); + struct lu_ref *ref = p; + struct lu_ref *next; + + spin_lock(&lu_ref_refs_guard); + next = cfs_list_entry(ref->lf_linkage.next, struct lu_ref, lf_linkage); + if ((&next->lf_linkage == &lu_ref_refs) || lu_ref_is_marker(next)) { + spin_unlock(&lu_ref_refs_guard); + return 0; + } + + /* print the entry */ + spin_lock(&next->lf_guard); seq_printf(seq, "lu_ref: %p %d %d %s:%d\n", next, next->lf_refs, next->lf_failed, next->lf_func, next->lf_line); @@ -372,10 +363,10 @@ static int lu_ref_seq_show(struct seq_file *seq, void *p) seq_printf(seq, " #%d link: %s %p\n", i++, link->ll_scope, link->ll_source); } - cfs_spin_unlock(&next->lf_guard); - cfs_spin_unlock(&lu_ref_refs_guard); + spin_unlock(&next->lf_guard); + spin_unlock(&lu_ref_refs_guard); - return 0; + return 0; } static struct seq_operations lu_ref_seq_ops = { @@ -387,17 +378,17 @@ static struct seq_operations lu_ref_seq_ops = { static int lu_ref_seq_open(struct inode *inode, struct file *file) { - struct lu_ref *marker = &lu_ref_marker; - int result = 0; - - result = seq_open(file, &lu_ref_seq_ops); - if (result == 0) { - cfs_spin_lock(&lu_ref_refs_guard); - if (!cfs_list_empty(&marker->lf_linkage)) - result = -EAGAIN; - else - cfs_list_add(&marker->lf_linkage, &lu_ref_refs); - cfs_spin_unlock(&lu_ref_refs_guard); + struct lu_ref *marker = &lu_ref_marker; + int result = 0; + + result = seq_open(file, &lu_ref_seq_ops); + if (result == 0) { + spin_lock(&lu_ref_refs_guard); + if (!cfs_list_empty(&marker->lf_linkage)) + result = -EAGAIN; + else + cfs_list_add(&marker->lf_linkage, &lu_ref_refs); + spin_unlock(&lu_ref_refs_guard); if (result == 0) { struct seq_file *f = file->private_data; @@ -412,13 +403,13 @@ static int lu_ref_seq_open(struct inode *inode, struct file *file) static int lu_ref_seq_release(struct inode *inode, struct file *file) { - struct lu_ref *ref = ((struct seq_file *)file->private_data)->private; + struct lu_ref *ref = ((struct seq_file *)file->private_data)->private; - cfs_spin_lock(&lu_ref_refs_guard); - cfs_list_del_init(&ref->lf_linkage); - cfs_spin_unlock(&lu_ref_refs_guard); + spin_lock(&lu_ref_refs_guard); + cfs_list_del_init(&ref->lf_linkage); + spin_unlock(&lu_ref_refs_guard); - return seq_release(inode, file); + return seq_release(inode, file); } static struct file_operations lu_ref_dump_fops = { @@ -433,13 +424,12 @@ static struct file_operations lu_ref_dump_fops = { int lu_ref_global_init(void) { - int result; - - CDEBUG(D_CONSOLE, - "lu_ref tracking is enabled. Performance isn't.\n"); + int result; + CDEBUG(D_CONSOLE, + "lu_ref tracking is enabled. Performance isn't.\n"); - cfs_spin_lock_init(&lu_ref_refs_guard); + spin_lock_init(&lu_ref_refs_guard); result = lu_kmem_init(lu_ref_caches); #if defined(__KERNEL__) && defined(LPROCFS)