X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fosc%2Fosc_page.c;h=affd0d265e0beedeb403c60018d9b2d64428bf54;hp=df51fc5a86204625c6c2b339e204b47e1ac5bc94;hb=27815a0611a2e315a9a7696a20c2f257d48aeb7e;hpb=98060d83459ba10409f295898f0ec917f938b4d3 diff --git a/lustre/osc/osc_page.c b/lustre/osc/osc_page.c index df51fc5..affd0d2 100644 --- a/lustre/osc/osc_page.c +++ b/lustre/osc/osc_page.c @@ -63,23 +63,23 @@ static int osc_page_is_dlocked(const struct lu_env *env, const struct osc_page *opg, enum cl_lock_mode mode, int pending, int unref) { - struct cl_page *page; - struct osc_object *obj; - struct osc_thread_info *info; - struct ldlm_res_id *resname; - struct lustre_handle *lockh; - ldlm_policy_data_t *policy; - ldlm_mode_t dlmmode; - int flags; - - cfs_might_sleep(); - - info = osc_env_info(env); - resname = &info->oti_resname; - policy = &info->oti_policy; - lockh = &info->oti_handle; - page = opg->ops_cl.cpl_page; - obj = cl2osc(opg->ops_cl.cpl_obj); + struct cl_page *page; + struct osc_object *obj; + struct osc_thread_info *info; + struct ldlm_res_id *resname; + struct lustre_handle *lockh; + ldlm_policy_data_t *policy; + ldlm_mode_t dlmmode; + __u64 flags; + + might_sleep(); + + info = osc_env_info(env); + resname = &info->oti_resname; + policy = &info->oti_policy; + lockh = &info->oti_handle; + page = opg->ops_cl.cpl_page; + obj = cl2osc(opg->ops_cl.cpl_obj); flags = LDLM_FL_TEST_LOCK | LDLM_FL_BLOCK_GRANTED; if (pending) @@ -208,7 +208,7 @@ static void osc_page_transfer_add(const struct lu_env *env, spin_lock(&obj->oo_seatbelt); cfs_list_add(&opg->ops_inflight, &obj->oo_inflight[crt]); - opg->ops_submitter = cfs_current(); + opg->ops_submitter = current; spin_unlock(&obj->oo_seatbelt); } @@ -508,14 +508,14 @@ static const struct cl_page_operations osc_page_ops = { }; int osc_page_init(const struct lu_env *env, struct cl_object *obj, - struct cl_page *page, cfs_page_t *vmpage) + struct cl_page *page, struct page *vmpage) { struct osc_object *osc = cl2osc(obj); struct osc_page *opg = cl_object_page_slice(obj, page); int result; opg->ops_from = 0; - opg->ops_to = CFS_PAGE_SIZE; + opg->ops_to = PAGE_CACHE_SIZE; result = osc_prep_async_page(osc, opg, vmpage, cl_offset(obj, page->cp_index)); @@ -529,7 +529,7 @@ int osc_page_init(const struct lu_env *env, struct cl_object *obj, * Cannot assert osc_page_protected() here as read-ahead * creates temporary pages outside of a lock. */ -#ifdef INVARIANT_CHECK +#ifdef CONFIG_LUSTRE_DEBUG_EXPENSIVE_CHECK opg->ops_temp = !osc_page_protected(env, opg, CLM_READ, 1); #endif /* ops_inflight and ops_lru are the same field, but it doesn't @@ -544,6 +544,30 @@ int osc_page_init(const struct lu_env *env, struct cl_object *obj, return result; } +int osc_over_unstable_soft_limit(struct client_obd *cli) +{ + long obd_upages, obd_dpages, osc_upages; + + /* Can't check cli->cl_unstable_count, therefore, no soft limit */ + if (cli == NULL) + return 0; + + obd_upages = cfs_atomic_read(&obd_unstable_pages); + obd_dpages = cfs_atomic_read(&obd_dirty_pages); + + osc_upages = cfs_atomic_read(&cli->cl_unstable_count); + + /* obd_max_dirty_pages is the max number of (dirty + unstable) + * pages allowed at any given time. To simulate an unstable page + * only limit, we subtract the current number of dirty pages + * from this max. This difference is roughly the amount of pages + * currently available for unstable pages. Thus, the soft limit + * is half of that difference. Check osc_upages to ensure we don't + * set SOFT_SYNC for OSCs without any outstanding unstable pages. */ + return osc_upages != 0 && + obd_upages >= (obd_max_dirty_pages - obd_dpages) / 2; +} + /** * Helper function called by osc_io_submit() for every page in an immediate * transfer (i.e., transferred synchronously). @@ -567,6 +591,9 @@ void osc_page_submit(const struct lu_env *env, struct osc_page *opg, oap->oap_count = opg->ops_to - opg->ops_from; oap->oap_brw_flags = OBD_BRW_SYNC | brw_flags; + if (osc_over_unstable_soft_limit(oap->oap_cli)) + oap->oap_brw_flags |= OBD_BRW_SOFT_SYNC; + if (!client_is_remote(osc_export(obj)) && cfs_capable(CFS_CAP_SYS_RESOURCE)) { oap->oap_brw_flags |= OBD_BRW_NOQUOTA; @@ -593,9 +620,9 @@ static CFS_DECL_WAITQ(osc_lru_waitq); static cfs_atomic_t osc_lru_waiters = CFS_ATOMIC_INIT(0); /* LRU pages are freed in batch mode. OSC should at least free this * number of pages to avoid running out of LRU budget, and.. */ -static const int lru_shrink_min = 2 << (20 - CFS_PAGE_SHIFT); /* 2M */ +static const int lru_shrink_min = 2 << (20 - PAGE_CACHE_SHIFT); /* 2M */ /* free this number at most otherwise it will take too long time to finsih. */ -static const int lru_shrink_max = 32 << (20 - CFS_PAGE_SHIFT); /* 32M */ +static const int lru_shrink_max = 32 << (20 - PAGE_CACHE_SHIFT); /* 32M */ /* Check if we can free LRU slots from this OSC. If there exists LRU waiters, * we should free slots aggressively. In this way, slots are freed in a steady @@ -781,7 +808,7 @@ static void osc_lru_add(struct client_obd *cli, struct osc_page *opg) if (wakeup) { osc_lru_shrink(cli, osc_cache_too_much(cli)); - cfs_waitq_broadcast(&osc_lru_waitq); + wake_up_all(&osc_lru_waitq); } } @@ -809,9 +836,10 @@ static void osc_lru_del(struct client_obd *cli, struct osc_page *opg, bool del) * stealing one of them. * cl_lru_shrinkers is to avoid recursive call in case * we're already in the context of osc_lru_shrink(). */ - if (cfs_atomic_read(&cli->cl_lru_shrinkers) == 0) + if (cfs_atomic_read(&cli->cl_lru_shrinkers) == 0 && + !memory_pressure_get()) osc_lru_shrink(cli, osc_cache_too_much(cli)); - cfs_waitq_signal(&osc_lru_waitq); + wake_up(&osc_lru_waitq); } } else { LASSERT(cfs_list_empty(&opg->ops_lru)); @@ -899,7 +927,7 @@ static int osc_lru_reserve(const struct lu_env *env, struct osc_object *obj, if (rc > 0) continue; - cfs_cond_resched(); + cond_resched(); /* slowest case, all of caching pages are busy, notifying * other OSCs that we're lack of LRU slots. */