From ec98d93ff50ca43f137db01261bf1ab55a1d5e53 Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Wed, 23 Apr 2014 13:11:22 -0700 Subject: [PATCH] LU-4793 clio: Reduce memory overhead of per-page allocation 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 Change-Id: I54d7ed7b64d5987ddaafbf16edafa5cdf491b0a1 Reviewed-on: http://review.whamcloud.com/10070 Reviewed-by: Andreas Dilger Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Bobi Jam --- lustre/include/cl_object.h | 40 +++++++++++----------------------------- lustre/include/lclient.h | 28 ++++++++++++++-------------- lustre/lov/lov_cl_internal.h | 4 ++-- lustre/lov/lov_io.c | 6 ++---- lustre/lov/lov_page.c | 1 + lustre/obdclass/cl_io.c | 10 +--------- lustre/obdclass/cl_page.c | 13 ++----------- lustre/osc/osc_internal.h | 1 - lustre/osc/osc_io.c | 7 ++++++- lustre/osc/osc_request.c | 6 ------ 10 files changed, 39 insertions(+), 77 deletions(-) diff --git a/lustre/include/cl_object.h b/lustre/include/cl_object.h index 286ecfa..5ad0067 100644 --- a/lustre/include/cl_object.h +++ b/lustre/include/cl_object.h @@ -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, diff --git a/lustre/include/lclient.h b/lustre/include/lclient.h index 4f42eea..cf852f5 100644 --- a/lustre/include/lclient.h +++ b/lustre/include/lclient.h @@ -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) diff --git a/lustre/lov/lov_cl_internal.h b/lustre/lov/lov_cl_internal.h index 9c96ac0..9635e99 100644 --- a/lustre/lov/lov_cl_internal.h +++ b/lustre/lov/lov_cl_internal.h @@ -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 */ }; /* diff --git a/lustre/lov/lov_io.c b/lustre/lov/lov_io.c index de85706..bdb8140 100644 --- a/lustre/lov/lov_io.c +++ b/lustre/lov/lov_io.c @@ -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, diff --git a/lustre/lov/lov_page.c b/lustre/lov/lov_page.c index 95366c1..77cae6f 100644 --- a/lustre/lov/lov_page.c +++ b/lustre/lov/lov_page.c @@ -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); diff --git a/lustre/obdclass/cl_io.c b/lustre/obdclass/cl_io.c index 1887381..d0d2ac4 100644 --- a/lustre/obdclass/cl_io.c +++ b/lustre/obdclass/cl_io.c @@ -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, diff --git a/lustre/obdclass/cl_page.c b/lustre/obdclass/cl_page.c index 4dfc98a..96c5295 100644 --- a/lustre/obdclass/cl_page.c +++ b/lustre/obdclass/cl_page.c @@ -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); diff --git a/lustre/osc/osc_internal.h b/lustre/osc/osc_internal.h index 7c93137..483ac5f 100644 --- a/lustre/osc/osc_internal.h +++ b/lustre/osc/osc_internal.h @@ -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; }; diff --git a/lustre/osc/osc_io.c b/lustre/osc/osc_io.c index 696bf99f..b2e54a9 100644 --- a/lustre/osc/osc_io.c +++ b/lustre/osc/osc_io.c @@ -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, diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index ece4142..b93af0a 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -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) { -- 1.8.3.1