Whamcloud - gitweb
ORNL-24 skip unnecessary client obj hash lookup
[fs/lustre-release.git] / lustre / obdclass / lu_object.c
index 8c61aa9..3f1e5e7 100644 (file)
@@ -30,6 +30,9 @@
  * Use is subject to license terms.
  */
 /*
+ * Copyright (c) 2011 Whamcloud, Inc.
+ */
+/*
  * This file is part of Lustre, http://www.lustre.org/
  * Lustre is a trademark of Sun Microsystems, Inc.
  *
@@ -543,6 +546,30 @@ struct lu_object *lu_object_find(const struct lu_env *env,
 }
 EXPORT_SYMBOL(lu_object_find);
 
+static struct lu_object *lu_object_new(const struct lu_env *env,
+                                       struct lu_device *dev,
+                                       const struct lu_fid *f,
+                                       const struct lu_object_conf *conf)
+{
+        struct lu_object        *o;
+        cfs_hash_t              *hs;
+        cfs_hash_bd_t            bd;
+        struct lu_site_bkt_data *bkt;
+
+        o = lu_object_alloc(env, dev, f, conf);
+        if (unlikely(IS_ERR(o)))
+                return o;
+
+        hs = dev->ld_site->ls_obj_hash;
+        cfs_hash_bd_get_and_lock(hs, (void *)f, &bd, 1);
+        bkt = cfs_hash_bd_extra_get(hs, &bd);
+        cfs_hash_bd_add_locked(hs, &bd, &o->lo_header->loh_hash);
+        cfs_list_add_tail(&o->lo_header->loh_lru, &bkt->lsb_lru);
+        bkt->lsb_busy++;
+        cfs_hash_bd_unlock(hs, &bd, 1);
+        return o;
+}
+
 /**
  * Core logic of lu_object_find*() functions.
  */
@@ -572,9 +599,16 @@ static struct lu_object *lu_object_find_try(const struct lu_env *env,
          *     - unlock index;
          *     - return object.
          *
+         * For "LOC_F_NEW" case, we are sure the object is new established.
+         * It is unnecessary to perform lookup-alloc-lookup-insert, instead,
+         * just alloc and insert directly.
+         *
          * If dying object is found during index search, add @waiter to the
          * site wait-queue and return ERR_PTR(-EAGAIN).
          */
+        if (conf != NULL && conf->loc_flags & LOC_F_NEW)
+                return lu_object_new(env, dev, f, conf);
+
         s  = dev->ld_site;
         hs = s->ls_obj_hash;
         cfs_hash_bd_get_and_lock(hs, (void *)f, &bd, 1);
@@ -754,9 +788,14 @@ void lu_site_print(const struct lu_env *env, struct lu_site *s, void *cookie,
 EXPORT_SYMBOL(lu_site_print);
 
 enum {
-        LU_CACHE_PERCENT   = 20,
+        LU_CACHE_PERCENT_MAX     = 50,
+        LU_CACHE_PERCENT_DEFAULT = 20
 };
 
+static unsigned int lu_cache_percent = LU_CACHE_PERCENT_DEFAULT;
+CFS_MODULE_PARM(lu_cache_percent, "i", int, 0644,
+                "Percentage of memory to be used as lu_object cache");
+
 /**
  * Return desired hash table order.
  */
@@ -780,7 +819,16 @@ static int lu_htable_order(void)
                 cache_size = 1 << (30 - CFS_PAGE_SHIFT) * 3 / 4;
 #endif
 
-        cache_size = cache_size / 100 * LU_CACHE_PERCENT *
+        /* clear off unreasonable cache setting. */
+        if (lu_cache_percent == 0 || lu_cache_percent > LU_CACHE_PERCENT_MAX) {
+                CWARN("obdclass: invalid lu_cache_percent: %u, it must be in"
+                      " the range of (0, %u]. Will use default value: %u.\n",
+                      lu_cache_percent, LU_CACHE_PERCENT_MAX,
+                      LU_CACHE_PERCENT_DEFAULT);
+
+                lu_cache_percent = LU_CACHE_PERCENT_DEFAULT;
+        }
+        cache_size = cache_size / 100 * lu_cache_percent *
                 (CFS_PAGE_SIZE / 1024);
 
         for (bits = 1; (1 << bits) < cache_size; ++bits) {
@@ -789,7 +837,8 @@ static int lu_htable_order(void)
         return bits;
 }
 
-static unsigned lu_obj_hop_hash(cfs_hash_t *hs, void *key, unsigned mask)
+static unsigned lu_obj_hop_hash(cfs_hash_t *hs,
+                                const void *key, unsigned mask)
 {
         struct lu_fid  *fid = (struct lu_fid *)key;
         unsigned        hash;
@@ -812,7 +861,7 @@ static void *lu_obj_hop_key(cfs_hlist_node_t *hnode)
         return &h->loh_fid;
 }
 
-static int lu_obj_hop_keycmp(void *key, cfs_hlist_node_t *hnode)
+static int lu_obj_hop_keycmp(const void *key, cfs_hlist_node_t *hnode)
 {
         struct lu_object_header *h;
 
@@ -1626,24 +1675,25 @@ static void lu_site_stats_get(cfs_hash_t *hs,
 }
 
 #ifdef __KERNEL__
-static int lu_cache_shrink(int nr, unsigned int gfp_mask)
+static int lu_cache_shrink(SHRINKER_FIRST_ARG int nr_to_scan,
+                           unsigned int gfp_mask)
 {
         lu_site_stats_t stats;
         struct lu_site *s;
         struct lu_site *tmp;
         int cached = 0;
-        int remain = nr;
+        int remain = nr_to_scan;
         CFS_LIST_HEAD(splice);
 
-        if (nr != 0) {
+        if (nr_to_scan != 0) {
                 if (!(gfp_mask & __GFP_FS))
                         return -1;
-                CDEBUG(D_INODE, "Shrink %d objects\n", nr);
+                CDEBUG(D_INODE, "Shrink %d objects\n", nr_to_scan);
         }
 
         cfs_down(&lu_sites_guard);
         cfs_list_for_each_entry_safe(s, tmp, &lu_sites, ls_linkage) {
-                if (nr != 0) {
+                if (nr_to_scan != 0) {
                         remain = lu_site_purge(&lu_shrink_env, s, remain);
                         /*
                          * Move just shrunk site to the tail of site list to
@@ -1655,14 +1705,14 @@ static int lu_cache_shrink(int nr, unsigned int gfp_mask)
                 memset(&stats, 0, sizeof(stats));
                 lu_site_stats_get(s->ls_obj_hash, &stats, 0);
                 cached += stats.lss_total - stats.lss_busy;
-                if (nr && remain <= 0)
+                if (nr_to_scan && remain <= 0)
                         break;
         }
         cfs_list_splice(&splice, lu_sites.prev);
         cfs_up(&lu_sites_guard);
 
         cached = (cached / 100) * sysctl_vfs_cache_pressure;
-        if (nr == 0)
+        if (nr_to_scan == 0)
                 CDEBUG(D_INODE, "%d objects cached\n", cached);
         return cached;
 }
@@ -1740,7 +1790,7 @@ int lu_global_init(void)
 {
         int result;
 
-        CDEBUG(D_CONSOLE, "Lustre LU module (%p).\n", &lu_keys);
+        CDEBUG(D_INFO, "Lustre LU module (%p).\n", &lu_keys);
 
         result = lu_ref_global_init();
         if (result != 0)