Commit 2579d8d0 authored by Jinshan Xiong's avatar Jinshan Xiong Committed by Greg Kroah-Hartman

staging/lustre/osc: to drop LRU pages with cl_lru_work

This way we can drop it async.
Signed-off-by: default avatarJinshan Xiong <jinshan.xiong@intel.com>
Reviewed-on: http://review.whamcloud.com/7891
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3321Reviewed-by: default avatarLai Siyao <lai.siyao@intel.com>
Reviewed-by: default avatarBobi Jam <bobijam@gmail.com>
Signed-off-by: default avatarOleg Drokin <green@linuxhacker.ru>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 5196e42c
...@@ -364,6 +364,7 @@ struct client_obd { ...@@ -364,6 +364,7 @@ struct client_obd {
/* ptlrpc work for writeback in ptlrpcd context */ /* ptlrpc work for writeback in ptlrpcd context */
void *cl_writeback_work; void *cl_writeback_work;
void *cl_lru_work;
/* hash tables for osc_quota_info */ /* hash tables for osc_quota_info */
struct cfs_hash *cl_quota_hash[MAXQUOTAS]; struct cfs_hash *cl_quota_hash[MAXQUOTAS];
}; };
......
...@@ -393,6 +393,8 @@ static ssize_t ll_max_cached_mb_seq_write(struct file *file, ...@@ -393,6 +393,8 @@ static ssize_t ll_max_cached_mb_seq_write(struct file *file,
struct super_block *sb = ((struct seq_file *)file->private_data)->private; struct super_block *sb = ((struct seq_file *)file->private_data)->private;
struct ll_sb_info *sbi = ll_s2sbi(sb); struct ll_sb_info *sbi = ll_s2sbi(sb);
struct cl_client_cache *cache = &sbi->ll_cache; struct cl_client_cache *cache = &sbi->ll_cache;
struct lu_env *env;
int refcheck;
int mult, rc, pages_number; int mult, rc, pages_number;
int diff = 0; int diff = 0;
int nrpages = 0; int nrpages = 0;
...@@ -430,6 +432,10 @@ static ssize_t ll_max_cached_mb_seq_write(struct file *file, ...@@ -430,6 +432,10 @@ static ssize_t ll_max_cached_mb_seq_write(struct file *file,
goto out; goto out;
} }
env = cl_env_get(&refcheck);
if (IS_ERR(env))
return 0;
diff = -diff; diff = -diff;
while (diff > 0) { while (diff > 0) {
int tmp; int tmp;
...@@ -461,13 +467,14 @@ static ssize_t ll_max_cached_mb_seq_write(struct file *file, ...@@ -461,13 +467,14 @@ static ssize_t ll_max_cached_mb_seq_write(struct file *file,
/* difficult - have to ask OSCs to drop LRU slots. */ /* difficult - have to ask OSCs to drop LRU slots. */
tmp = diff << 1; tmp = diff << 1;
rc = obd_set_info_async(NULL, sbi->ll_dt_exp, rc = obd_set_info_async(env, sbi->ll_dt_exp,
sizeof(KEY_CACHE_LRU_SHRINK), sizeof(KEY_CACHE_LRU_SHRINK),
KEY_CACHE_LRU_SHRINK, KEY_CACHE_LRU_SHRINK,
sizeof(tmp), &tmp, NULL); sizeof(tmp), &tmp, NULL);
if (rc < 0) if (rc < 0)
break; break;
} }
cl_env_put(env, &refcheck);
out: out:
if (rc >= 0) { if (rc >= 0) {
......
...@@ -222,8 +222,16 @@ static ssize_t osc_cached_mb_seq_write(struct file *file, ...@@ -222,8 +222,16 @@ static ssize_t osc_cached_mb_seq_write(struct file *file,
return -ERANGE; return -ERANGE;
rc = atomic_read(&cli->cl_lru_in_list) - pages_number; rc = atomic_read(&cli->cl_lru_in_list) - pages_number;
if (rc > 0) if (rc > 0) {
(void)osc_lru_shrink(cli, rc, true); struct lu_env *env;
int refcheck;
env = cl_env_get(&refcheck);
if (!IS_ERR(env)) {
(void)osc_lru_shrink(env, cli, rc, true);
cl_env_put(env, &refcheck);
}
}
return count; return count;
} }
......
...@@ -457,6 +457,7 @@ int osc_cache_wait_range(const struct lu_env *env, struct osc_object *obj, ...@@ -457,6 +457,7 @@ int osc_cache_wait_range(const struct lu_env *env, struct osc_object *obj,
pgoff_t start, pgoff_t end); pgoff_t start, pgoff_t end);
void osc_io_unplug(const struct lu_env *env, struct client_obd *cli, void osc_io_unplug(const struct lu_env *env, struct client_obd *cli,
struct osc_object *osc); struct osc_object *osc);
int lru_queue_work(const struct lu_env *env, void *data);
void osc_object_set_contended (struct osc_object *obj); void osc_object_set_contended (struct osc_object *obj);
void osc_object_clear_contended(struct osc_object *obj); void osc_object_clear_contended(struct osc_object *obj);
......
...@@ -130,7 +130,8 @@ int osc_sync_base(struct obd_export *exp, struct obd_info *oinfo, ...@@ -130,7 +130,8 @@ int osc_sync_base(struct obd_export *exp, struct obd_info *oinfo,
int osc_process_config_base(struct obd_device *obd, struct lustre_cfg *cfg); int osc_process_config_base(struct obd_device *obd, struct lustre_cfg *cfg);
int osc_build_rpc(const struct lu_env *env, struct client_obd *cli, int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,
struct list_head *ext_list, int cmd); struct list_head *ext_list, int cmd);
int osc_lru_shrink(struct client_obd *cli, int target, bool force); int osc_lru_shrink(const struct lu_env *env, struct client_obd *cli,
int target, bool force);
int osc_lru_reclaim(struct client_obd *cli); int osc_lru_reclaim(struct client_obd *cli);
extern spinlock_t osc_ast_guard; extern spinlock_t osc_ast_guard;
......
...@@ -508,6 +508,18 @@ static int osc_cache_too_much(struct client_obd *cli) ...@@ -508,6 +508,18 @@ static int osc_cache_too_much(struct client_obd *cli)
return 0; return 0;
} }
int lru_queue_work(const struct lu_env *env, void *data)
{
struct client_obd *cli = data;
CDEBUG(D_CACHE, "Run LRU work for client obd %p.\n", cli);
if (osc_cache_too_much(cli))
osc_lru_shrink(env, cli, lru_shrink_max, true);
return 0;
}
void osc_lru_add_batch(struct client_obd *cli, struct list_head *plist) void osc_lru_add_batch(struct client_obd *cli, struct list_head *plist)
{ {
LIST_HEAD(lru); LIST_HEAD(lru);
...@@ -533,7 +545,8 @@ void osc_lru_add_batch(struct client_obd *cli, struct list_head *plist) ...@@ -533,7 +545,8 @@ void osc_lru_add_batch(struct client_obd *cli, struct list_head *plist)
client_obd_list_unlock(&cli->cl_lru_list_lock); client_obd_list_unlock(&cli->cl_lru_list_lock);
/* XXX: May set force to be true for better performance */ /* XXX: May set force to be true for better performance */
osc_lru_shrink(cli, osc_cache_too_much(cli), false); if (osc_cache_too_much(cli))
(void)ptlrpcd_queue_work(cli->cl_lru_work);
} }
} }
...@@ -566,7 +579,7 @@ static void osc_lru_del(struct client_obd *cli, struct osc_page *opg) ...@@ -566,7 +579,7 @@ static void osc_lru_del(struct client_obd *cli, struct osc_page *opg)
* stealing one of them. * stealing one of them.
*/ */
if (!memory_pressure_get()) if (!memory_pressure_get())
osc_lru_shrink(cli, osc_cache_too_much(cli), false); (void)ptlrpcd_queue_work(cli->cl_lru_work);
wake_up(&osc_lru_waitq); wake_up(&osc_lru_waitq);
} else { } else {
LASSERT(list_empty(&opg->ops_lru)); LASSERT(list_empty(&opg->ops_lru));
...@@ -610,10 +623,9 @@ static void discard_pagevec(const struct lu_env *env, struct cl_io *io, ...@@ -610,10 +623,9 @@ static void discard_pagevec(const struct lu_env *env, struct cl_io *io,
/** /**
* Drop @target of pages from LRU at most. * Drop @target of pages from LRU at most.
*/ */
int osc_lru_shrink(struct client_obd *cli, int target, bool force) int osc_lru_shrink(const struct lu_env *env, struct client_obd *cli,
int target, bool force)
{ {
struct cl_env_nest nest;
struct lu_env *env;
struct cl_io *io; struct cl_io *io;
struct cl_object *clobj = NULL; struct cl_object *clobj = NULL;
struct cl_page **pvec; struct cl_page **pvec;
...@@ -640,12 +652,6 @@ int osc_lru_shrink(struct client_obd *cli, int target, bool force) ...@@ -640,12 +652,6 @@ int osc_lru_shrink(struct client_obd *cli, int target, bool force)
atomic_inc(&cli->cl_lru_shrinkers); atomic_inc(&cli->cl_lru_shrinkers);
} }
env = cl_env_nested_get(&nest);
if (IS_ERR(env)) {
rc = PTR_ERR(env);
goto out;
}
pvec = osc_env_info(env)->oti_pvec; pvec = osc_env_info(env)->oti_pvec;
io = &osc_env_info(env)->oti_io; io = &osc_env_info(env)->oti_io;
...@@ -735,9 +741,7 @@ int osc_lru_shrink(struct client_obd *cli, int target, bool force) ...@@ -735,9 +741,7 @@ int osc_lru_shrink(struct client_obd *cli, int target, bool force)
cl_io_fini(env, io); cl_io_fini(env, io);
cl_object_put(env, clobj); cl_object_put(env, clobj);
} }
cl_env_nested_put(&nest, env);
out:
atomic_dec(&cli->cl_lru_shrinkers); atomic_dec(&cli->cl_lru_shrinkers);
if (count > 0) { if (count > 0) {
atomic_add(count, cli->cl_lru_left); atomic_add(count, cli->cl_lru_left);
...@@ -753,20 +757,26 @@ static inline int max_to_shrink(struct client_obd *cli) ...@@ -753,20 +757,26 @@ static inline int max_to_shrink(struct client_obd *cli)
int osc_lru_reclaim(struct client_obd *cli) int osc_lru_reclaim(struct client_obd *cli)
{ {
struct cl_env_nest nest;
struct lu_env *env;
struct cl_client_cache *cache = cli->cl_cache; struct cl_client_cache *cache = cli->cl_cache;
int max_scans; int max_scans;
int rc = 0; int rc = 0;
LASSERT(cache); LASSERT(cache);
rc = osc_lru_shrink(cli, lru_shrink_min, false); env = cl_env_nested_get(&nest);
if (IS_ERR(env))
return 0;
rc = osc_lru_shrink(env, cli, osc_cache_too_much(cli), false);
if (rc != 0) { if (rc != 0) {
if (rc == -EBUSY) if (rc == -EBUSY)
rc = 0; rc = 0;
CDEBUG(D_CACHE, "%s: Free %d pages from own LRU: %p.\n", CDEBUG(D_CACHE, "%s: Free %d pages from own LRU: %p.\n",
cli->cl_import->imp_obd->obd_name, rc, cli); cli->cl_import->imp_obd->obd_name, rc, cli);
return rc; goto out;
} }
CDEBUG(D_CACHE, "%s: cli %p no free slots, pages: %d, busy: %d.\n", CDEBUG(D_CACHE, "%s: cli %p no free slots, pages: %d, busy: %d.\n",
...@@ -797,7 +807,8 @@ int osc_lru_reclaim(struct client_obd *cli) ...@@ -797,7 +807,8 @@ int osc_lru_reclaim(struct client_obd *cli)
if (osc_cache_too_much(cli) > 0) { if (osc_cache_too_much(cli) > 0) {
spin_unlock(&cache->ccc_lru_lock); spin_unlock(&cache->ccc_lru_lock);
rc = osc_lru_shrink(cli, osc_cache_too_much(cli), true); rc = osc_lru_shrink(env, cli, osc_cache_too_much(cli),
true);
spin_lock(&cache->ccc_lru_lock); spin_lock(&cache->ccc_lru_lock);
if (rc != 0) if (rc != 0)
break; break;
...@@ -805,6 +816,8 @@ int osc_lru_reclaim(struct client_obd *cli) ...@@ -805,6 +816,8 @@ int osc_lru_reclaim(struct client_obd *cli)
} }
spin_unlock(&cache->ccc_lru_lock); spin_unlock(&cache->ccc_lru_lock);
out:
cl_env_nested_put(&nest, env);
CDEBUG(D_CACHE, "%s: cli %p freed %d pages.\n", CDEBUG(D_CACHE, "%s: cli %p freed %d pages.\n",
cli->cl_import->imp_obd->obd_name, cli, rc); cli->cl_import->imp_obd->obd_name, cli, rc);
return rc; return rc;
......
...@@ -2910,7 +2910,7 @@ static int osc_set_info_async(const struct lu_env *env, struct obd_export *exp, ...@@ -2910,7 +2910,7 @@ static int osc_set_info_async(const struct lu_env *env, struct obd_export *exp,
int nr = atomic_read(&cli->cl_lru_in_list) >> 1; int nr = atomic_read(&cli->cl_lru_in_list) >> 1;
int target = *(int *)val; int target = *(int *)val;
nr = osc_lru_shrink(cli, min(nr, target), true); nr = osc_lru_shrink(env, cli, min(nr, target), true);
*(int *)val -= nr; *(int *)val -= nr;
return 0; return 0;
} }
...@@ -3167,6 +3167,14 @@ int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg) ...@@ -3167,6 +3167,14 @@ int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
} }
cli->cl_writeback_work = handler; cli->cl_writeback_work = handler;
handler = ptlrpcd_alloc_work(cli->cl_import, lru_queue_work, cli);
if (IS_ERR(handler)) {
rc = PTR_ERR(handler);
goto out_ptlrpcd_work;
}
cli->cl_lru_work = handler;
rc = osc_quota_setup(obd); rc = osc_quota_setup(obd);
if (rc) if (rc)
goto out_ptlrpcd_work; goto out_ptlrpcd_work;
...@@ -3199,7 +3207,14 @@ int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg) ...@@ -3199,7 +3207,14 @@ int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
return rc; return rc;
out_ptlrpcd_work: out_ptlrpcd_work:
ptlrpcd_destroy_work(handler); if (cli->cl_writeback_work) {
ptlrpcd_destroy_work(cli->cl_writeback_work);
cli->cl_writeback_work = NULL;
}
if (cli->cl_lru_work) {
ptlrpcd_destroy_work(cli->cl_lru_work);
cli->cl_lru_work = NULL;
}
out_client_setup: out_client_setup:
client_obd_cleanup(obd); client_obd_cleanup(obd);
out_ptlrpcd: out_ptlrpcd:
...@@ -3238,6 +3253,10 @@ static int osc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) ...@@ -3238,6 +3253,10 @@ static int osc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
ptlrpcd_destroy_work(cli->cl_writeback_work); ptlrpcd_destroy_work(cli->cl_writeback_work);
cli->cl_writeback_work = NULL; cli->cl_writeback_work = NULL;
} }
if (cli->cl_lru_work) {
ptlrpcd_destroy_work(cli->cl_lru_work);
cli->cl_lru_work = NULL;
}
obd_cleanup_client_import(obd); obd_cleanup_client_import(obd);
ptlrpc_lprocfs_unregister_obd(obd); ptlrpc_lprocfs_unregister_obd(obd);
lprocfs_obd_cleanup(obd); lprocfs_obd_cleanup(obd);
......
...@@ -387,7 +387,8 @@ static int ptlrpcd(void *arg) ...@@ -387,7 +387,8 @@ static int ptlrpcd(void *arg)
{ {
struct ptlrpcd_ctl *pc = arg; struct ptlrpcd_ctl *pc = arg;
struct ptlrpc_request_set *set; struct ptlrpc_request_set *set;
struct lu_env env = { .le_ses = NULL }; struct lu_context ses = { 0 };
struct lu_env env = { .le_ses = &ses };
int rc = 0; int rc = 0;
int exit = 0; int exit = 0;
...@@ -416,6 +417,13 @@ static int ptlrpcd(void *arg) ...@@ -416,6 +417,13 @@ static int ptlrpcd(void *arg)
*/ */
rc = lu_context_init(&env.le_ctx, rc = lu_context_init(&env.le_ctx,
LCT_CL_THREAD|LCT_REMEMBER|LCT_NOREF); LCT_CL_THREAD|LCT_REMEMBER|LCT_NOREF);
if (rc == 0) {
rc = lu_context_init(env.le_ses,
LCT_SESSION | LCT_REMEMBER | LCT_NOREF);
if (rc != 0)
lu_context_fini(&env.le_ctx);
}
if (rc != 0) if (rc != 0)
goto failed; goto failed;
...@@ -436,9 +444,10 @@ static int ptlrpcd(void *arg) ...@@ -436,9 +444,10 @@ static int ptlrpcd(void *arg)
ptlrpc_expired_set, set); ptlrpc_expired_set, set);
lu_context_enter(&env.le_ctx); lu_context_enter(&env.le_ctx);
l_wait_event(set->set_waitq, lu_context_enter(env.le_ses);
ptlrpcd_check(&env, pc), &lwi); l_wait_event(set->set_waitq, ptlrpcd_check(&env, pc), &lwi);
lu_context_exit(&env.le_ctx); lu_context_exit(&env.le_ctx);
lu_context_exit(env.le_ses);
/* /*
* Abort inflight rpcs for forced stop case. * Abort inflight rpcs for forced stop case.
...@@ -461,6 +470,7 @@ static int ptlrpcd(void *arg) ...@@ -461,6 +470,7 @@ static int ptlrpcd(void *arg)
if (!list_empty(&set->set_requests)) if (!list_empty(&set->set_requests))
ptlrpc_set_wait(set); ptlrpc_set_wait(set);
lu_context_fini(&env.le_ctx); lu_context_fini(&env.le_ctx);
lu_context_fini(env.le_ses);
complete(&pc->pc_finishing); complete(&pc->pc_finishing);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment