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

Commit cad6fafa authored by Bobi Jam's avatar Bobi Jam Committed by Greg Kroah-Hartman
Browse files

staging/lustre/osc: some cleanup to reduce stack overflow chance

ptlrpcd_add_req() will wake_up other process, do not hold a spinlock
before calling ptlrpcd_queue_work()->ptlrpcd_add_req().

If current process is allocating memory, memory shrinker could get to
osc_lru_del(), don't call osc_lru_shrink() further since it could
lead a long calling chain.

Use static string OES_STRINGS in OSC_EXTENT_DUMP() to reduce stack
footprint.

Alloc crattr on heap for osc_build_rpc() to reduce stack footprint.

Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3281
Lustre-change: http://review.whamcloud.com/6270


Signed-off-by: default avatarBobi Jam <bobijam.xu@intel.com>
Reviewed-by: default avatarJinshan Xiong <jinshan.xiong@intel.com>
Reviewed-by: default avatarKeith Mannthey <keith.mannthey@intel.com>
Reviewed-by: default avatarAndreas Dilger <andreas.dilger@intel.com>
Signed-off-by: default avatarPeng Tao <tao.peng@emc.com>
Signed-off-by: default avatarAndreas Dilger <andreas.dilger@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent bc969176
Loading
Loading
Loading
Loading
+21 −23
Original line number Diff line number Diff line
@@ -99,10 +99,11 @@ static inline char list_empty_marker(struct list_head *list)

#define EXTSTR       "[%lu -> %lu/%lu]"
#define EXTPARA(ext) (ext)->oe_start, (ext)->oe_end, (ext)->oe_max_end
static const char *oes_strings[] = {
	"inv", "active", "cache", "locking", "lockdone", "rpc", "trunc", NULL };

#define OSC_EXTENT_DUMP(lvl, extent, fmt, ...) do {			      \
	struct osc_extent *__ext = (extent);				      \
	const char *__str[] = OES_STRINGS;				      \
	char __buf[16];							      \
									      \
	CDEBUG(lvl,							      \
@@ -114,7 +115,7 @@ static inline char list_empty_marker(struct list_head *list)
		atomic_read(&__ext->oe_refc),			      \
		atomic_read(&__ext->oe_users),			      \
		list_empty_marker(&__ext->oe_link),			      \
		__str[__ext->oe_state], ext_flags(__ext, __buf),	      \
		oes_strings[__ext->oe_state], ext_flags(__ext, __buf),	      \
		__ext->oe_obj,						      \
		/* ----- part 2 ----- */				      \
		__ext->oe_grants, __ext->oe_nr_pages,			      \
@@ -2125,27 +2126,24 @@ static void osc_check_rpcs(const struct lu_env *env, struct client_obd *cli,
static int osc_io_unplug0(const struct lu_env *env, struct client_obd *cli,
			  struct osc_object *osc, pdl_policy_t pol, int async)
{
	int has_rpcs = 1;
	int rc = 0;

	client_obd_list_lock(&cli->cl_loi_list_lock);
	if (osc != NULL)
		has_rpcs = __osc_list_maint(cli, osc);
	if (has_rpcs) {
	if (osc != NULL && osc_list_maint(cli, osc) == 0)
		return 0;

	if (!async) {
		/* disable osc_lru_shrink() temporarily to avoid
		 * potential stack overrun problem. LU-2859 */
		atomic_inc(&cli->cl_lru_shrinkers);
		client_obd_list_lock(&cli->cl_loi_list_lock);
		osc_check_rpcs(env, cli, pol);
		client_obd_list_unlock(&cli->cl_loi_list_lock);
		atomic_dec(&cli->cl_lru_shrinkers);
	} else {
			CDEBUG(D_CACHE, "Queue writeback work for client %p.\n",
			       cli);
		CDEBUG(D_CACHE, "Queue writeback work for client %p.\n", cli);
		LASSERT(cli->cl_writeback_work != NULL);
		rc = ptlrpcd_queue_work(cli->cl_writeback_work);
	}
	}
	client_obd_list_unlock(&cli->cl_loi_list_lock);
	return rc;
}

+0 −2
Original line number Diff line number Diff line
@@ -584,8 +584,6 @@ enum osc_extent_state {
	OES_TRUNC     = 6, /** being truncated */
	OES_STATE_MAX
};
#define OES_STRINGS { "inv", "active", "cache", "locking", "lockdone", "rpc", \
		      "trunc", NULL }

/**
 * osc_extent data to manage dirty pages.
+2 −1
Original line number Diff line number Diff line
@@ -806,7 +806,8 @@ 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 (atomic_read(&cli->cl_lru_shrinkers) == 0)
			if (atomic_read(&cli->cl_lru_shrinkers) == 0 &&
			    !memory_pressure_get())
				osc_lru_shrink(cli, osc_cache_too_much(cli));
			wake_up(&osc_lru_waitq);
		}
+36 −26
Original line number Diff line number Diff line
@@ -2043,19 +2043,24 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,
{
	struct ptlrpc_request		*req = NULL;
	struct osc_extent		*ext;
	LIST_HEAD(rpc_list);
	struct brw_page			**pga = NULL;
	struct osc_brw_async_args	*aa = NULL;
	struct obdo			*oa = NULL;
	struct osc_async_page		*oap;
	struct osc_async_page		*tmp;
	struct cl_req			*clerq = NULL;
	enum cl_req_type crt = (cmd & OBD_BRW_WRITE) ? CRT_WRITE : CRT_READ;
	enum cl_req_type		crt = (cmd & OBD_BRW_WRITE) ? CRT_WRITE :
								      CRT_READ;
	struct ldlm_lock		*lock = NULL;
	struct cl_req_attr crattr;
	struct cl_req_attr		*crattr = NULL;
	obd_off				starting_offset = OBD_OBJECT_EOF;
	obd_off				ending_offset = 0;
	int i, rc, mpflag = 0, mem_tight = 0, page_count = 0;
	int				mpflag = 0;
	int				mem_tight = 0;
	int				page_count = 0;
	int				i;
	int				rc;
	LIST_HEAD(rpc_list);

	ENTRY;
	LASSERT(!list_empty(ext_list));
@@ -2083,7 +2088,10 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,
	if (mem_tight)
		mpflag = cfs_memory_pressure_get_and_set();

	memset(&crattr, 0, sizeof crattr);
	OBD_ALLOC(crattr, sizeof(*crattr));
	if (crattr == NULL)
		GOTO(out, rc = -ENOMEM);

	OBD_ALLOC(pga, sizeof(*pga) * page_count);
	if (pga == NULL)
		GOTO(out, rc = -ENOMEM);
@@ -2097,8 +2105,7 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,
		struct cl_page *page = oap2cl_page(oap);
		if (clerq == NULL) {
			clerq = cl_req_alloc(env, page, crt,
					     1 /* only 1-object rpcs for
						* now */);
					     1 /* only 1-object rpcs for now */);
			if (IS_ERR(clerq))
				GOTO(out, rc = PTR_ERR(clerq));
			lock = oap->oap_ldlm_lock;
@@ -2108,17 +2115,16 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,
		pga[i] = &oap->oap_brw_page;
		pga[i]->off = oap->oap_obj_off + oap->oap_page_off;
		CDEBUG(0, "put page %p index %lu oap %p flg %x to pga\n",
		       pga[i]->pg, page_index(oap->oap_page), oap, pga[i]->flag);
		       pga[i]->pg, page_index(oap->oap_page), oap,
		       pga[i]->flag);
		i++;
		cl_req_page_add(env, clerq, page);
	}

	/* always get the data for the obdo for the rpc */
	LASSERT(clerq != NULL);
	crattr.cra_oa = oa;
	crattr.cra_capa = NULL;
	memset(crattr.cra_jobid, 0, JOBSTATS_JOBID_SIZE);
	cl_req_attr_set(env, clerq, &crattr, ~0ULL);
	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;
@@ -2132,7 +2138,7 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,

	sort_brw_pages(pga, page_count);
	rc = osc_brw_prep_request(cmd, cli, oa, NULL, page_count,
			pga, &req, crattr.cra_capa, 1, 0);
			pga, &req, crattr->cra_capa, 1, 0);
	if (rc != 0) {
		CERROR("prep_req failed: %d\n", rc);
		GOTO(out, rc);
@@ -2148,10 +2154,10 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,
	 * later setattr before earlier BRW (as determined by the request xid),
	 * the OST will not use BRW timestamps.  Sadly, there is no obvious
	 * way to do this in a single call.  bug 10150 */
	cl_req_attr_set(env, clerq, &crattr,
	cl_req_attr_set(env, clerq, crattr,
			OBD_MD_FLMTIME|OBD_MD_FLCTIME|OBD_MD_FLATIME);

	lustre_msg_set_jobid(req->rq_reqmsg, crattr.cra_jobid);
	lustre_msg_set_jobid(req->rq_reqmsg, crattr->cra_jobid);

	CLASSERT(sizeof(*aa) <= sizeof(req->rq_async_args));
	aa = ptlrpc_req_async_args(req);
@@ -2218,7 +2224,11 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,
	if (mem_tight != 0)
		cfs_memory_pressure_restore(mpflag);

	capa_put(crattr.cra_capa);
	if (crattr != NULL) {
		capa_put(crattr->cra_capa);
		OBD_FREE(crattr, sizeof(*crattr));
	}

	if (rc != 0) {
		LASSERT(req == NULL);