/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
- */
-/*
- * Copyright (c) 2011 Whamcloud, Inc.
+ *
+ * Copyright (c) 2011, 2012, Whamcloud, Inc.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
int lu_cdebug_printer(const struct lu_env *env,
void *cookie, const char *format, ...)
{
- struct lu_cdebug_print_info *info = cookie;
- struct lu_cdebug_data *key;
+ struct libcfs_debug_msg_data *msgdata = cookie;
+ struct lu_cdebug_data *key;
int used;
int complete;
va_list args;
vsnprintf(key->lck_area + used,
ARRAY_SIZE(key->lck_area) - used, format, args);
if (complete) {
- if (cfs_cdebug_show(info->lpi_mask, info->lpi_subsys))
- libcfs_debug_msg(NULL, info->lpi_subsys, info->lpi_mask,
- (char *)info->lpi_file, info->lpi_fn,
- info->lpi_line, "%s", key->lck_area);
+ if (cfs_cdebug_show(msgdata->msg_mask, msgdata->msg_subsys))
+ libcfs_debug_msg(msgdata, "%s", key->lck_area);
key->lck_area[0] = 0;
}
va_end(args);
h = container_of0(hnode, struct lu_object_header, loh_hash);
if (likely(!lu_object_is_dying(h))) {
lprocfs_counter_incr(s->ls_stats, LU_SS_CACHE_HIT);
+ cfs_list_del_init(&h->loh_lru);
return lu_object_top(h);
}
hs = s->ls_obj_hash;
cfs_hash_bd_get_and_lock(hs, (void *)f, &bd, 1);
o = htable_lookup(s, &bd, f, waiter, &version);
- if (o != NULL && !cfs_list_empty(&o->lo_header->loh_lru))
- cfs_list_del_init(&o->lo_header->loh_lru);
cfs_hash_bd_unlock(hs, &bd, 1);
if (o != NULL)
return o;
cfs_hash_bd_lock(hs, &bd, 1);
shadow = htable_lookup(s, &bd, f, waiter, &version);
- if (shadow == NULL) {
+ if (likely(shadow == NULL)) {
struct lu_site_bkt_data *bkt;
bkt = cfs_hash_bd_extra_get(hs, &bd);
bkt->lsb_busy++;
cfs_hash_bd_unlock(hs, &bd, 1);
return o;
- } else {
- if (!cfs_list_empty(&shadow->lo_header->loh_lru))
- cfs_list_del_init(&shadow->lo_header->loh_lru);
- lprocfs_counter_incr(s->ls_stats, LU_SS_CACHE_RACE);
- cfs_hash_bd_unlock(hs, &bd, 1);
- lu_object_free(env, o);
- return shadow;
}
+
+ lprocfs_counter_incr(s->ls_stats, LU_SS_CACHE_RACE);
+ cfs_hash_bd_unlock(hs, &bd, 1);
+ lu_object_free(env, o);
+ return shadow;
}
/**
* Global list of all sites on this node
*/
static CFS_LIST_HEAD(lu_sites);
-static CFS_DECLARE_MUTEX(lu_sites_guard);
+static CFS_DEFINE_MUTEX(lu_sites_guard);
/**
* Global environment used by site shrinker.
*/
void lu_site_fini(struct lu_site *s)
{
- cfs_down(&lu_sites_guard);
+ cfs_mutex_lock(&lu_sites_guard);
cfs_list_del_init(&s->ls_linkage);
- cfs_up(&lu_sites_guard);
+ cfs_mutex_unlock(&lu_sites_guard);
if (s->ls_obj_hash != NULL) {
cfs_hash_putref(s->ls_obj_hash);
int lu_site_init_finish(struct lu_site *s)
{
int result;
- cfs_down(&lu_sites_guard);
+ cfs_mutex_lock(&lu_sites_guard);
result = lu_context_refill(&lu_shrink_env.le_ctx);
if (result == 0)
cfs_list_add(&s->ls_linkage, &lu_sites);
- cfs_up(&lu_sites_guard);
+ cfs_mutex_unlock(&lu_sites_guard);
return result;
}
EXPORT_SYMBOL(lu_site_init_finish);
/*
* Uh-oh, objects still exist.
*/
- static DECLARE_LU_CDEBUG_PRINT_INFO(cookie, D_ERROR);
+ LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_ERROR, NULL);
- lu_site_print(env, site, &cookie, lu_cdebug_printer);
+ lu_site_print(env, site, &msgdata, lu_cdebug_printer);
}
for (scan = top; scan != NULL; scan = next) {
{
int i;
+ LINVRNT(ctx->lc_value != NULL);
for (i = 0; i < ARRAY_SIZE(lu_keys); ++i) {
struct lu_context_key *key;
/**
* Allocate for context all missing keys that were registered after context
- * creation.
+ * creation. key_set_version is only changed in rare cases when modules
+ * are loaded and removed.
*/
int lu_context_refill(struct lu_context *ctx)
{
- LINVRNT(ctx->lc_value != NULL);
- return ctx->lc_version == key_set_version ? 0 : keys_fill(ctx);
+ return likely(ctx->lc_version == key_set_version) ? 0 : keys_fill(ctx);
}
EXPORT_SYMBOL(lu_context_refill);
+/**
+ * lu_ctx_tags/lu_ses_tags will be updated if there are new types of
+ * obd being added. Currently, this is only used on client side, specifically
+ * for echo device client, for other stack (like ptlrpc threads), context are
+ * predefined when the lu_device type are registered, during the module probe
+ * phase.
+ */
+__u32 lu_context_tags_default = 0;
+__u32 lu_session_tags_default = 0;
+
+void lu_context_tags_update(__u32 tags)
+{
+ cfs_spin_lock(&lu_keys_guard);
+ lu_context_tags_default |= tags;
+ key_set_version ++;
+ cfs_spin_unlock(&lu_keys_guard);
+}
+EXPORT_SYMBOL(lu_context_tags_update);
+
+void lu_context_tags_clear(__u32 tags)
+{
+ cfs_spin_lock(&lu_keys_guard);
+ lu_context_tags_default &= ~tags;
+ key_set_version ++;
+ cfs_spin_unlock(&lu_keys_guard);
+}
+EXPORT_SYMBOL(lu_context_tags_clear);
+
+void lu_session_tags_update(__u32 tags)
+{
+ cfs_spin_lock(&lu_keys_guard);
+ lu_session_tags_default |= tags;
+ key_set_version ++;
+ cfs_spin_unlock(&lu_keys_guard);
+}
+EXPORT_SYMBOL(lu_session_tags_update);
+
+void lu_session_tags_clear(__u32 tags)
+{
+ cfs_spin_lock(&lu_keys_guard);
+ lu_session_tags_default &= ~tags;
+ key_set_version ++;
+ cfs_spin_unlock(&lu_keys_guard);
+}
+EXPORT_SYMBOL(lu_session_tags_clear);
+
int lu_env_init(struct lu_env *env, __u32 tags)
{
int result;
}
EXPORT_SYMBOL(lu_env_refill);
+/**
+ * Currently, this API will only be used by echo client.
+ * Because echo client and normal lustre client will share
+ * same cl_env cache. So echo client needs to refresh
+ * the env context after it get one from the cache, especially
+ * when normal client and echo client co-exist in the same client.
+ */
+int lu_env_refill_by_tags(struct lu_env *env, __u32 ctags,
+ __u32 stags)
+{
+ int result;
+
+ if ((env->le_ctx.lc_tags & ctags) != ctags) {
+ env->le_ctx.lc_version = 0;
+ env->le_ctx.lc_tags |= ctags;
+ }
+
+ if (env->le_ses && (env->le_ses->lc_tags & stags) != stags) {
+ env->le_ses->lc_version = 0;
+ env->le_ses->lc_tags |= stags;
+ }
+
+ result = lu_env_refill(env);
+
+ return result;
+}
+EXPORT_SYMBOL(lu_env_refill_by_tags);
+
static struct cfs_shrinker *lu_site_shrinker = NULL;
typedef struct lu_site_stats{
CDEBUG(D_INODE, "Shrink %d objects\n", remain);
}
- cfs_down(&lu_sites_guard);
+ cfs_mutex_lock(&lu_sites_guard);
cfs_list_for_each_entry_safe(s, tmp, &lu_sites, ls_linkage) {
if (shrink_param(sc, nr_to_scan) != 0) {
remain = lu_site_purge(&lu_shrink_env, s, remain);
break;
}
cfs_list_splice(&splice, lu_sites.prev);
- cfs_up(&lu_sites_guard);
+ cfs_mutex_unlock(&lu_sites_guard);
cached = (cached / 100) * sysctl_vfs_cache_pressure;
if (shrink_param(sc, nr_to_scan) == 0)
* conservatively. This should not be too bad, because this
* environment is global.
*/
- cfs_down(&lu_sites_guard);
+ cfs_mutex_lock(&lu_sites_guard);
result = lu_env_init(&lu_shrink_env, LCT_SHRINKER);
- cfs_up(&lu_sites_guard);
+ cfs_mutex_unlock(&lu_sites_guard);
if (result != 0)
return result;
* Tear shrinker environment down _after_ de-registering
* lu_global_key, because the latter has a value in the former.
*/
- cfs_down(&lu_sites_guard);
+ cfs_mutex_lock(&lu_sites_guard);
lu_env_fini(&lu_shrink_env);
- cfs_up(&lu_sites_guard);
+ cfs_mutex_unlock(&lu_sites_guard);
lu_ref_global_fini();
}