Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a763e916 authored by Jinshan Xiong's avatar Jinshan Xiong Committed by Greg Kroah-Hartman
Browse files

staging/lustre: Get rid of cl_env hash table



cl_env hash table is under heavy contention when there are lots of
processes doing IO at the same time;
reduce lock contention by replacing cl_env cache with percpu array;
remove cl_env_nested_get() and cl_env_nested_put();
remove cl_env_reenter() and cl_env_reexit();

Signed-off-by: default avatarJinshan Xiong <jinshan.xiong@intel.com>
Reviewed-on: http://review.whamcloud.com/20254
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4257


Reviewed-by: default avatarAndreas Dilger <andreas.dilger@intel.com>
Reviewed-by: default avatarBobi Jam <bobijam@hotmail.com>
Signed-off-by: default avatarOleg Drokin <green@linuxhacker.ru>
Reviewed-by: default avatarJames Simmons <jsimmons@infradead.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 2d8c919e
Loading
Loading
Loading
Loading
+0 −22
Original line number Diff line number Diff line
@@ -2640,35 +2640,13 @@ void cl_sync_io_end(const struct lu_env *env, struct cl_sync_io *anchor);
 *     - allocation and destruction of environment is amortized by caching no
 *     longer used environments instead of destroying them;
 *
 *     - there is a notion of "current" environment, attached to the kernel
 *     data structure representing current thread Top-level lustre code
 *     allocates an environment and makes it current, then calls into
 *     non-lustre code, that in turn calls lustre back. Low-level lustre
 *     code thus called can fetch environment created by the top-level code
 *     and reuse it, avoiding additional environment allocation.
 *       Right now, three interfaces can attach the cl_env to running thread:
 *       - cl_env_get
 *       - cl_env_implant
 *       - cl_env_reexit(cl_env_reenter had to be called priorly)
 *
 * \see lu_env, lu_context, lu_context_key
 * @{
 */

struct cl_env_nest {
	int   cen_refcheck;
	void *cen_cookie;
};

struct lu_env *cl_env_get(int *refcheck);
struct lu_env *cl_env_alloc(int *refcheck, __u32 tags);
struct lu_env *cl_env_nested_get(struct cl_env_nest *nest);
void cl_env_put(struct lu_env *env, int *refcheck);
void cl_env_nested_put(struct cl_env_nest *nest, struct lu_env *env);
void *cl_env_reenter(void);
void cl_env_reexit(void *cookie);
void cl_env_implant(struct lu_env *env, int *refcheck);
void cl_env_unplant(struct lu_env *env, int *refcheck);
unsigned int cl_env_cache_purge(unsigned int nr);
struct lu_env *cl_env_percpu_get(void);
void cl_env_percpu_put(struct lu_env *env);
+0 −9
Original line number Diff line number Diff line
@@ -794,7 +794,6 @@ static unsigned long ldlm_pools_count(ldlm_side_t client, gfp_t gfp_mask)
	int nr_ns;
	struct ldlm_namespace *ns;
	struct ldlm_namespace *ns_old = NULL; /* loop detection */
	void *cookie;

	if (client == LDLM_NAMESPACE_CLIENT && !(gfp_mask & __GFP_FS))
		return 0;
@@ -802,8 +801,6 @@ static unsigned long ldlm_pools_count(ldlm_side_t client, gfp_t gfp_mask)
	CDEBUG(D_DLMTRACE, "Request to count %s locks from all pools\n",
	       client == LDLM_NAMESPACE_CLIENT ? "client" : "server");

	cookie = cl_env_reenter();

	/*
	 * Find out how many resources we may release.
	 */
@@ -812,7 +809,6 @@ static unsigned long ldlm_pools_count(ldlm_side_t client, gfp_t gfp_mask)
		mutex_lock(ldlm_namespace_lock(client));
		if (list_empty(ldlm_namespace_list(client))) {
			mutex_unlock(ldlm_namespace_lock(client));
			cl_env_reexit(cookie);
			return 0;
		}
		ns = ldlm_namespace_first_locked(client);
@@ -838,7 +834,6 @@ static unsigned long ldlm_pools_count(ldlm_side_t client, gfp_t gfp_mask)
		ldlm_namespace_put(ns);
	}

	cl_env_reexit(cookie);
	return total;
}

@@ -847,13 +842,10 @@ static unsigned long ldlm_pools_scan(ldlm_side_t client, int nr, gfp_t gfp_mask)
	unsigned long freed = 0;
	int tmp, nr_ns;
	struct ldlm_namespace *ns;
	void *cookie;

	if (client == LDLM_NAMESPACE_CLIENT && !(gfp_mask & __GFP_FS))
		return -1;

	cookie = cl_env_reenter();

	/*
	 * Shrink at least ldlm_namespace_nr_read(client) namespaces.
	 */
@@ -883,7 +875,6 @@ static unsigned long ldlm_pools_scan(ldlm_side_t client, int nr, gfp_t gfp_mask)
		freed += ldlm_pool_shrink(&ns->ns_pool, cancel, gfp_mask);
		ldlm_namespace_put(ns);
	}
	cl_env_reexit(cookie);
	/*
	 * we only decrease the SLV in server pools shrinker, return
	 * SHRINK_STOP to kernel to avoid needless loop. LU-1128
+9 −9
Original line number Diff line number Diff line
@@ -1584,11 +1584,11 @@ int ll_data_version(struct inode *inode, __u64 *data_version, int flags)
 */
int ll_hsm_release(struct inode *inode)
{
	struct cl_env_nest nest;
	struct lu_env *env;
	struct obd_client_handle *och = NULL;
	__u64 data_version = 0;
	int rc;
	int refcheck;

	CDEBUG(D_INODE, "%s: Releasing file "DFID".\n",
	       ll_get_fsname(inode->i_sb, NULL, 0),
@@ -1605,14 +1605,14 @@ int ll_hsm_release(struct inode *inode)
	if (rc != 0)
		goto out;

	env = cl_env_nested_get(&nest);
	env = cl_env_get(&refcheck);
	if (IS_ERR(env)) {
		rc = PTR_ERR(env);
		goto out;
	}

	ll_merge_attr(env, inode);
	cl_env_nested_put(&nest, env);
	cl_env_put(env, &refcheck);

	/* Release the file.
	 * NB: lease lock handle is released in mdc_hsm_release_pack() because
@@ -2268,17 +2268,17 @@ static int ll_flush(struct file *file, fl_owner_t id)
int cl_sync_file_range(struct inode *inode, loff_t start, loff_t end,
		       enum cl_fsync_mode mode, int ignore_layout)
{
	struct cl_env_nest nest;
	struct lu_env *env;
	struct cl_io *io;
	struct cl_fsync_io *fio;
	int result;
	int refcheck;

	if (mode != CL_FSYNC_NONE && mode != CL_FSYNC_LOCAL &&
	    mode != CL_FSYNC_DISCARD && mode != CL_FSYNC_ALL)
		return -EINVAL;

	env = cl_env_nested_get(&nest);
	env = cl_env_get(&refcheck);
	if (IS_ERR(env))
		return PTR_ERR(env);

@@ -2301,7 +2301,7 @@ int cl_sync_file_range(struct inode *inode, loff_t start, loff_t end,
	if (result == 0)
		result = fio->fi_nr_written;
	cl_io_fini(env, io);
	cl_env_nested_put(&nest, env);
	cl_env_put(env, &refcheck);

	return result;
}
@@ -3149,14 +3149,14 @@ int ll_layout_conf(struct inode *inode, const struct cl_object_conf *conf)
{
	struct ll_inode_info *lli = ll_i2info(inode);
	struct cl_object *obj = lli->lli_clob;
	struct cl_env_nest nest;
	struct lu_env *env;
	int rc;
	int refcheck;

	if (!obj)
		return 0;

	env = cl_env_nested_get(&nest);
	env = cl_env_get(&refcheck);
	if (IS_ERR(env))
		return PTR_ERR(env);

@@ -3190,7 +3190,7 @@ int ll_layout_conf(struct inode *inode, const struct cl_object_conf *conf)
		ll_layout_version_set(lli, cl.cl_layout_gen);
	}
out:
	cl_env_nested_put(&nest, env);
	cl_env_put(env, &refcheck);
	return rc;
}

+2 −9
Original line number Diff line number Diff line
@@ -246,15 +246,11 @@ void cl_inode_fini(struct inode *inode)
	int emergency;

	if (clob) {
		void		    *cookie;

		cookie = cl_env_reenter();
		env = cl_env_get(&refcheck);
		emergency = IS_ERR(env);
		if (emergency) {
			mutex_lock(&cl_inode_fini_guard);
			LASSERT(cl_inode_fini_env);
			cl_env_implant(cl_inode_fini_env, &refcheck);
			env = cl_inode_fini_env;
		}
		/*
@@ -266,14 +262,11 @@ void cl_inode_fini(struct inode *inode)
		lu_object_ref_del(&clob->co_lu, "inode", inode);
		cl_object_put_last(env, clob);
		lli->lli_clob = NULL;
		if (emergency) {
			cl_env_unplant(cl_inode_fini_env, &refcheck);
		if (emergency)
			mutex_unlock(&cl_inode_fini_guard);
		} else {
		else
			cl_env_put(env, &refcheck);
	}
		cl_env_reexit(cookie);
	}
}

/**
+1 −7
Original line number Diff line number Diff line
@@ -162,13 +162,11 @@ int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock,
		return rc;
	}

	cg->lg_env  = cl_env_get(&refcheck);
	cg->lg_env  = env;
	cg->lg_io   = io;
	cg->lg_lock = lock;
	cg->lg_gid  = gid;
	LASSERT(cg->lg_env == env);

	cl_env_unplant(env, &refcheck);
	return 0;
}

@@ -177,14 +175,10 @@ void cl_put_grouplock(struct ll_grouplock *cg)
	struct lu_env  *env  = cg->lg_env;
	struct cl_io   *io   = cg->lg_io;
	struct cl_lock *lock = cg->lg_lock;
	int	     refcheck;

	LASSERT(cg->lg_env);
	LASSERT(cg->lg_gid);

	cl_env_implant(env, &refcheck);
	cl_env_put(env, &refcheck);

	cl_lock_release(env, lock);
	cl_io_fini(env, io);
	cl_env_put(env, NULL);
Loading