Whamcloud - gitweb
LU-4793 clio: Reduce memory overhead of per-page allocation 70/10070/5
authorJinshan Xiong <jinshan.xiong@intel.com>
Wed, 23 Apr 2014 20:11:22 +0000 (13:11 -0700)
committerOleg Drokin <oleg.drokin@intel.com>
Wed, 11 Jun 2014 02:44:16 +0000 (02:44 +0000)
A page in clio used to occupy 584 bytes, which will use size-1024
slab cache. This patch reduces the per-page overhead to 512 bytes
so it can use size-512 instead.

Signed-off-by: Jinshan Xiong <jinshan.xiong@intel.com>
Change-Id: I54d7ed7b64d5987ddaafbf16edafa5cdf491b0a1
Reviewed-on: http://review.whamcloud.com/10070
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Bobi Jam <bobijam@gmail.com>
lustre/include/cl_object.h
lustre/include/lclient.h
lustre/lov/lov_cl_internal.h
lustre/lov/lov_io.c
lustre/lov/lov_page.c
lustre/obdclass/cl_io.c
lustre/obdclass/cl_page.c
lustre/osc/osc_internal.h
lustre/osc/osc_io.c
lustre/osc/osc_request.c

index 286ecfa..5ad0067 100644 (file)
@@ -701,17 +701,6 @@ enum cl_page_type {
 };
 
 /**
- * Flags maintained for every cl_page.
- */
-enum cl_page_flags {
-        /**
-         * Set when pagein completes. Used for debugging (read completes at
-         * most once for a page).
-         */
-        CPF_READ_COMPLETED = 1 << 0
-};
-
-/**
  * Fields are protected by the lock on struct page, except for atomics and
  * immutables.
  *
@@ -722,26 +711,24 @@ enum cl_page_flags {
  */
 struct cl_page {
        /** Reference counter. */
-       atomic_t                cp_ref;
+       atomic_t                 cp_ref;
+       /** Transfer error. */
+       int                      cp_error;
        /** An object this page is a part of. Immutable after creation. */
        struct cl_object        *cp_obj;
-       /** List of slices. Immutable after creation. */
-       cfs_list_t              cp_layers;
+       /** vmpage */
        struct page             *cp_vmpage;
+       /** Linkage of pages within group. Pages must be owned */
+       struct list_head         cp_batch;
+       /** List of slices. Immutable after creation. */
+       struct list_head         cp_layers;
+       /** Linkage of pages within cl_req. */
+       struct list_head         cp_flight;
        /**
         * Page state. This field is const to avoid accidental update, it is
         * modified only internally within cl_page.c. Protected by a VM lock.
         */
        const enum cl_page_state cp_state;
-       /** Linkage of pages within group. Protected by cl_page::cp_mutex. */
-       cfs_list_t              cp_batch;
-       /** Mutex serializing membership of a page in a batch. */
-       struct mutex            cp_mutex;
-        /** Linkage of pages within cl_req. */
-        cfs_list_t               cp_flight;
-        /** Transfer error. */
-        int                      cp_error;
-
         /**
          * Page type. Only CPT_TRANSIENT is used so far. Immutable after
          * creation.
@@ -754,10 +741,6 @@ struct cl_page {
          */
         struct cl_io            *cp_owner;
         /**
-         * Debug information, the task is owning the page.
-         */
-       struct task_struct      *cp_task;
-        /**
          * Owning IO request in cl_page_state::CPS_PAGEOUT and
          * cl_page_state::CPS_PAGEIN states. This field is maintained only in
          * the top-level pages. Protected by a VM lock.
@@ -769,8 +752,6 @@ struct cl_page {
        struct lu_ref_link       cp_obj_ref;
        /** Link to a queue, for debugging. */
        struct lu_ref_link       cp_queue_ref;
-       /** Per-page flags from enum cl_page_flags. Protected by a VM lock. */
-       unsigned                 cp_flags;
        /** Assigned if doing a sync_io */
        struct cl_sync_io       *cp_sync_io;
 };
@@ -2715,6 +2696,7 @@ static inline void cl_object_page_init(struct cl_object *clob, int size)
 {
        clob->co_slice_off = cl_object_header(clob)->coh_page_bufsize;
        cl_object_header(clob)->coh_page_bufsize += cfs_size_round(size);
+       WARN_ON(cl_object_header(clob)->coh_page_bufsize > 512);
 }
 
 static inline void *cl_object_page_slice(struct cl_object *clob,
index 4f42eea..cf852f5 100644 (file)
@@ -237,20 +237,20 @@ struct ccc_object {
  * ccc-private page state.
  */
 struct ccc_page {
-        struct cl_page_slice cpg_cl;
-        int                  cpg_defer_uptodate;
-        int                  cpg_ra_used;
-        int                  cpg_write_queued;
-        /**
-         * Non-empty iff this page is already counted in
-         * ccc_object::cob_pending_list. Protected by
-         * ccc_object::cob_pending_guard. This list is only used as a flag,
-         * that is, never iterated through, only checked for list_empty(), but
-         * having a list is useful for debugging.
-         */
-        cfs_list_t           cpg_pending_linkage;
-        /** VM page */
-       struct page          *cpg_page;
+       struct cl_page_slice cpg_cl;
+       unsigned        cpg_defer_uptodate:1,
+                       cpg_ra_used:1,
+                       cpg_write_queued:1;
+       /**
+        * Non-empty iff this page is already counted in
+        * ccc_object::cob_pending_list. Protected by
+        * ccc_object::cob_pending_guard. This list is only used as a flag,
+        * that is, never iterated through, only checked for list_empty(), but
+        * having a list is useful for debugging.
+        */
+       struct list_head cpg_pending_linkage;
+       /** VM page */
+       struct page     *cpg_page;
 };
 
 static inline struct ccc_page *cl2ccc_page(const struct cl_page_slice *slice)
index 9c96ac0..9635e99 100644 (file)
@@ -369,8 +369,8 @@ struct lov_lock {
 };
 
 struct lov_page {
-        struct cl_page_slice lps_cl;
-        int                  lps_invalid;
+       struct cl_page_slice    lps_cl;
+       unsigned int            lps_stripe; /* stripe index */
 };
 
 /*
index de85706..bdb8140 100644 (file)
@@ -251,16 +251,14 @@ void lov_sub_put(struct lov_io_sub *sub)
 
 int lov_page_stripe(const struct cl_page *page)
 {
-       struct lovsub_object *subobj;
        const struct cl_page_slice *slice;
        ENTRY;
 
-       slice = cl_page_at(page, &lovsub_device_type);
+       slice = cl_page_at(page, &lov_device_type);
        LASSERT(slice != NULL);
        LASSERT(slice->cpl_obj != NULL);
 
-       subobj = cl2lovsub(slice->cpl_obj);
-       RETURN(subobj->lso_index);
+       RETURN(cl2lov_page(slice)->lps_stripe);
 }
 
 struct lov_io_sub *lov_page_subio(const struct lu_env *env, struct lov_io *lio,
index 95366c1..77cae6f 100644 (file)
@@ -137,6 +137,7 @@ int lov_page_init_raid0(const struct lu_env *env, struct cl_object *obj,
                               &suboff);
        LASSERT(rc == 0);
 
+       lpg->lps_stripe = stripe;
        cl_page_slice_add(page, &lpg->lps_cl, obj, index, &lov_raid0_page_ops);
 
        sub = lov_sub_get(env, lio, stripe);
index 1887381..d0d2ac4 100644 (file)
@@ -1011,9 +1011,6 @@ void cl_page_list_add(struct cl_page_list *plist, struct cl_page *page)
        LASSERT(page->cp_owner != NULL);
        LINVRNT(plist->pl_owner == current);
 
-       lockdep_off();
-       mutex_lock(&page->cp_mutex);
-       lockdep_on();
        LASSERT(cfs_list_empty(&page->cp_batch));
        cfs_list_add_tail(&page->cp_batch, &plist->pl_pages);
        ++plist->pl_nr;
@@ -1030,13 +1027,11 @@ void cl_page_list_del(const struct lu_env *env,
                      struct cl_page_list *plist, struct cl_page *page)
 {
        LASSERT(plist->pl_nr > 0);
+       LASSERT(cl_page_is_vmlocked(env, page));
        LINVRNT(plist->pl_owner == current);
 
        ENTRY;
        cfs_list_del_init(&page->cp_batch);
-       lockdep_off();
-       mutex_unlock(&page->cp_mutex);
-       lockdep_on();
        --plist->pl_nr;
        lu_ref_del_at(&page->cp_reference, &page->cp_queue_ref, "queue", plist);
        cl_page_put(env, page);
@@ -1121,9 +1116,6 @@ void cl_page_list_disown(const struct lu_env *env,
                LASSERT(plist->pl_nr > 0);
 
                cfs_list_del_init(&page->cp_batch);
-               lockdep_off();
-               mutex_unlock(&page->cp_mutex);
-               lockdep_on();
                --plist->pl_nr;
                /*
                 * cl_page_disown0 rather than usual cl_page_disown() is used,
index 4dfc98a..96c5295 100644 (file)
@@ -193,7 +193,6 @@ struct cl_page *cl_page_alloc(const struct lu_env *env,
                CFS_INIT_LIST_HEAD(&page->cp_layers);
                CFS_INIT_LIST_HEAD(&page->cp_batch);
                CFS_INIT_LIST_HEAD(&page->cp_flight);
-               mutex_init(&page->cp_mutex);
                lu_ref_init(&page->cp_reference);
                head = o->co_lu.lo_header;
                cfs_list_for_each_entry(o, &head->loh_layers,
@@ -546,7 +545,6 @@ static void cl_page_owner_clear(struct cl_page *page)
                LASSERT(page->cp_owner->ci_owned_nr > 0);
                page->cp_owner->ci_owned_nr--;
                page->cp_owner = NULL;
-               page->cp_task = NULL;
        }
        EXIT;
 }
@@ -638,7 +636,6 @@ static int cl_page_own0(const struct lu_env *env, struct cl_io *io,
                         PASSERT(env, pg, pg->cp_owner == NULL);
                         PASSERT(env, pg, pg->cp_req == NULL);
                        pg->cp_owner = cl_io_top(io);;
-                        pg->cp_task  = current;
                         cl_page_owner_set(pg);
                         if (pg->cp_state != CPS_FREEING) {
                                 cl_page_state_set(env, pg, CPS_OWNED);
@@ -697,7 +694,6 @@ void cl_page_assume(const struct lu_env *env,
        cl_page_invoid(env, io, pg, CL_PAGE_OP(cpo_assume));
        PASSERT(env, pg, pg->cp_owner == NULL);
        pg->cp_owner = cl_io_top(io);
-       pg->cp_task = current;
        cl_page_owner_set(pg);
        cl_page_state_set(env, pg, CPS_OWNED);
        EXIT;
@@ -956,11 +952,6 @@ void cl_page_completion(const struct lu_env *env,
 
         ENTRY;
         CL_PAGE_HEADER(D_TRACE, env, pg, "%d %d\n", crt, ioret);
-        if (crt == CRT_READ && ioret == 0) {
-                PASSERT(env, pg, !(pg->cp_flags & CPF_READ_COMPLETED));
-                pg->cp_flags |= CPF_READ_COMPLETED;
-        }
-
         cl_page_state_set(env, pg, CPS_CACHED);
        if (crt >= CRT_NR)
                return;
@@ -1091,10 +1082,10 @@ void cl_page_header_print(const struct lu_env *env, void *cookie,
                           lu_printer_t printer, const struct cl_page *pg)
 {
        (*printer)(env, cookie,
-                  "page@%p[%d %p %d %d %d %p %p %#x]\n",
+                  "page@%p[%d %p %d %d %d %p %p]\n",
                   pg, atomic_read(&pg->cp_ref), pg->cp_obj,
                   pg->cp_state, pg->cp_error, pg->cp_type,
-                  pg->cp_owner, pg->cp_req, pg->cp_flags);
+                  pg->cp_owner, pg->cp_req);
 }
 EXPORT_SYMBOL(cl_page_header_print);
 
index 7c93137..483ac5f 100644 (file)
@@ -69,7 +69,6 @@ struct osc_async_page {
         struct client_obd       *oap_cli;
        struct osc_object       *oap_obj;
 
-       struct ldlm_lock        *oap_ldlm_lock;
        spinlock_t               oap_lock;
 };
 
index 696bf99..b2e54a9 100644 (file)
@@ -167,7 +167,6 @@ static int osc_io_submit(const struct lu_env *env,
                        continue;
                 }
 
-               cl_page_list_move(qout, qin, page);
                spin_lock(&oap->oap_lock);
                oap->oap_async_flags = ASYNC_URGENT|ASYNC_READY;
                oap->oap_async_flags |= ASYNC_COUNT_STABLE;
@@ -175,6 +174,12 @@ static int osc_io_submit(const struct lu_env *env,
 
                osc_page_submit(env, opg, crt, brw_flags);
                list_add_tail(&oap->oap_pending_item, &list);
+
+               if (page->cp_sync_io != NULL)
+                       cl_page_list_move(qout, qin, page);
+               else /* async IO */
+                       cl_page_list_del(env, qin, page);
+
                if (++queued == max_pages) {
                        queued = 0;
                        result = osc_queue_sync_pages(env, osc, &list, cmd,
index ece4142..b93af0a 100644 (file)
@@ -1897,7 +1897,6 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,
        struct cl_req                   *clerq = NULL;
        enum cl_req_type                crt = (cmd & OBD_BRW_WRITE) ? CRT_WRITE :
                                                                      CRT_READ;
-       struct ldlm_lock                *lock = NULL;
        struct cl_req_attr              *crattr = NULL;
        obd_off                         starting_offset = OBD_OBJECT_EOF;
        obd_off                         ending_offset = 0;
@@ -1954,7 +1953,6 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,
                                             1 /* only 1-object rpcs for now */);
                        if (IS_ERR(clerq))
                                GOTO(out, rc = PTR_ERR(clerq));
-                       lock = oap->oap_ldlm_lock;
                }
                if (mem_tight)
                        oap->oap_brw_flags |= OBD_BRW_MEMALLOC;
@@ -1971,10 +1969,6 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,
        LASSERT(clerq != NULL);
        crattr->cra_oa = oa;
        cl_req_attr_set(env, clerq, crattr, ~0ULL);
-       if (lock) {
-               oa->o_handle = lock->l_remote_handle;
-               oa->o_valid |= OBD_MD_FLHANDLE;
-       }
 
        rc = cl_req_prep(env, clerq);
        if (rc != 0) {