X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fofd%2Fofd_grant.c;h=a1819fc3bba59be1b2fbdce39566f4a8224a7ad0;hp=03b3e25f0362f04191ebb4c45c9b9941da6714cc;hb=f6dc0994f2bb5d2624e622213b634e74a1c76e3f;hpb=9fb46705ae86aa2c0ac29427f0ff24f923560eb7 diff --git a/lustre/ofd/ofd_grant.c b/lustre/ofd/ofd_grant.c index 03b3e25..a1819fc 100644 --- a/lustre/ofd/ofd_grant.c +++ b/lustre/ofd/ofd_grant.c @@ -27,7 +27,7 @@ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Whamcloud, Inc. + * Copyright (c) 2012, 2013, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -42,8 +42,11 @@ #include "ofd_internal.h" -#define OFD_GRANT_CHUNK (2ULL * PTLRPC_MAX_BRW_SIZE) -#define OFD_GRANT_SHRINK_LIMIT (16ULL * OFD_GRANT_CHUNK) +/* At least enough to send a couple of 1MB RPCs, even if not max sized */ +#define OFD_GRANT_CHUNK (2ULL * DT_MAX_BRW_SIZE) + +/* Clients typically hold 2x their max_rpcs_in_flight of grant space */ +#define OFD_GRANT_SHRINK_LIMIT(exp) (2ULL * 8 * exp_max_brw_size(exp)) static inline obd_size ofd_grant_from_cli(struct obd_export *exp, struct ofd_device *ofd, obd_size val) @@ -67,15 +70,17 @@ static inline obd_size ofd_grant_to_cli(struct obd_export *exp, static inline obd_size ofd_grant_chunk(struct obd_export *exp, struct ofd_device *ofd) { - if (exp && ofd_obd(ofd)->obd_self_export == exp) + if (ofd_obd(ofd)->obd_self_export == exp) /* Grant enough space to handle a big precreate request */ - return OST_MAX_PRECREATE * ofd->ofd_dt_conf.ddp_inodespace; + return OST_MAX_PRECREATE * ofd->ofd_dt_conf.ddp_inodespace / 2; - if (exp && ofd_grant_compat(exp, ofd)) + if (ofd_grant_compat(exp, ofd)) /* Try to grant enough space to send a full-size RPC */ - return PTLRPC_MAX_BRW_SIZE << + return exp_max_brw_size(exp) << (ofd->ofd_blockbits - COMPAT_BSIZE_SHIFT); - return OFD_GRANT_CHUNK; + + /* Try to return enough to send two full RPCs, if needed */ + return exp_max_brw_size(exp) * 2; } /** @@ -201,7 +206,8 @@ static void ofd_grant_statfs(const struct lu_env *env, struct obd_export *exp, rc = ofd_statfs_internal(env, ofd, osfs, max_age, from_cache); if (unlikely(rc)) { - *from_cache = 0; + if (from_cache) + *from_cache = 0; return; } @@ -228,7 +234,7 @@ static obd_size ofd_grant_space_left(struct obd_export *exp) obd_size unstable; ENTRY; - LASSERT_SPIN_LOCKED(&ofd->ofd_grant_lock); + assert_spin_locked(&ofd->ofd_grant_lock); spin_lock(&ofd->ofd_osfs_lock); /* get available space from cached statfs data */ @@ -244,10 +250,11 @@ static obd_size ofd_grant_space_left(struct obd_export *exp) D_ERROR : D_CACHE; CDEBUG_LIMIT(mask, "%s: cli %s/%p left "LPU64" < tot_grant " - LPU64" unstable "LPU64" pending "LPU64"\n", + LPU64" unstable "LPU64" pending "LPU64" " + "dirty "LPU64"\n", obd->obd_name, exp->exp_client_uuid.uuid, exp, left, tot_granted, unstable, - ofd->ofd_tot_pending); + ofd->ofd_tot_pending, ofd->ofd_tot_dirty); RETURN(0); } @@ -292,7 +299,7 @@ static void ofd_grant_incoming(const struct lu_env *env, struct obd_export *exp, long dirty, dropped, grant_chunk; ENTRY; - LASSERT_SPIN_LOCKED(&ofd->ofd_grant_lock); + assert_spin_locked(&ofd->ofd_grant_lock); if ((oa->o_valid & (OBD_MD_FLBLOCKS|OBD_MD_FLGRANT)) != (OBD_MD_FLBLOCKS|OBD_MD_FLGRANT)) { @@ -370,10 +377,10 @@ static void ofd_grant_shrink(struct obd_export *exp, struct obd_device *obd = exp->exp_obd; long grant_shrink; - LASSERT_SPIN_LOCKED(&ofd->ofd_grant_lock); - + assert_spin_locked(&ofd->ofd_grant_lock); + LASSERT(exp); if (left_space >= ofd->ofd_tot_granted_clients * - OFD_GRANT_SHRINK_LIMIT) + OFD_GRANT_SHRINK_LIMIT(exp)) return; grant_shrink = ofd_grant_from_cli(exp, ofd, oa->o_grant); @@ -451,7 +458,7 @@ static void ofd_grant_check(const struct lu_env *env, struct obd_export *exp, ENTRY; - LASSERT_SPIN_LOCKED(&ofd->ofd_grant_lock); + assert_spin_locked(&ofd->ofd_grant_lock); if ((oa->o_valid & OBD_MD_FLFLAGS) && (oa->o_flags & OBD_FL_RECOV_RESEND)) { @@ -580,9 +587,11 @@ static void ofd_grant_check(const struct lu_env *env, struct obd_export *exp, * \param curgrant - is the current grant claimed by the client * \param want - is how much grant space the client would like to have * \param left - is the remaining free space with granted space taken out + * \param conservative - is how server grants, if true, a certain amount, else + * server will grant as client requested. */ static long ofd_grant(struct obd_export *exp, obd_size curgrant, - obd_size want, obd_size left) + obd_size want, obd_size left, bool conservative) { struct obd_device *obd = exp->exp_obd; struct ofd_device *ofd = ofd_exp(exp); @@ -603,8 +612,8 @@ static long ofd_grant(struct obd_export *exp, obd_size curgrant, /* client not supporting OBD_CONNECT_GRANT_PARAM works with a 4KB block * size while the reality is different */ - curgrant = ofd_grant_from_cli(exp, ofd, curgrant); - want = ofd_grant_from_cli(exp, ofd, want); + curgrant = ofd_grant_from_cli(exp, ofd, curgrant); + want = ofd_grant_from_cli(exp, ofd, want); grant_chunk = ofd_grant_chunk(exp, ofd); /* Grant some fraction of the client's requested grant space so that @@ -619,20 +628,23 @@ static long ofd_grant(struct obd_export *exp, obd_size curgrant, if (curgrant >= want || curgrant >= fed->fed_grant + grant_chunk) RETURN(0); - if (!obd->obd_recovering) + if (obd->obd_recovering) + conservative = false; + + if (conservative) /* don't grant more than 1/8th of the remaining free space in * one chunk */ left >>= 3; grant = min(want, left); - /* align grant on block size */ - grant &= ~((1ULL << ofd->ofd_blockbits) - 1); + /* round grant upt to the next block size */ + grant = (grant + (1 << ofd->ofd_blockbits) - 1) & + ~((1ULL << ofd->ofd_blockbits) - 1); if (!grant) RETURN(0); - /* Allow >OFD_GRANT_CHUNK size when clients reconnect due to a - * server reboot. */ - if ((grant > grant_chunk) && (!obd->obd_recovering)) + /* Limit to ofd_grant_chunk() if not reconnect/recovery */ + if ((grant > grant_chunk) && conservative) grant = grant_chunk; ofd->ofd_tot_granted += grant; @@ -665,9 +677,12 @@ static long ofd_grant(struct obd_export *exp, obd_size curgrant, * \param env - is the lu environment provided by the caller * \param exp - is the client's export which is reconnecting * \param want - is how much the client would like to get + * \param conservative - is how server grants to client, if true server will + * only grant certain amount, else server will grant client requested + * amount. */ long ofd_grant_connect(const struct lu_env *env, struct obd_export *exp, - obd_size want) + obd_size want, bool conservative) { struct ofd_device *ofd = ofd_exp(exp); struct filter_export_data *fed = &exp->exp_filter_data; @@ -677,7 +692,7 @@ long ofd_grant_connect(const struct lu_env *env, struct obd_export *exp, int force = 0; /* can use cached data */ /* don't grant space to client with read-only access */ - if ((exp->exp_connect_flags & OBD_CONNECT_RDONLY) || + if ((exp_connect_flags(exp) & OBD_CONNECT_RDONLY) || ofd_grant_prohibit(exp, ofd)) return 0; @@ -699,7 +714,7 @@ refresh: } ofd_grant(exp, ofd_grant_to_cli(exp, ofd, (obd_size)fed->fed_grant), - want, left); + want, left, conservative); /* return to client its current grant */ grant = ofd_grant_to_cli(exp, ofd, (obd_size)fed->fed_grant); @@ -858,8 +873,7 @@ refresh: /* When close to free space exhaustion, trigger a sync to force * writeback cache to consume required space immediately and release as * much space as possible. */ - if (!obd->obd_recovering && force != 2 && - left < ofd_grant_chunk(NULL, ofd)) { + if (!obd->obd_recovering && force != 2 && left < OFD_GRANT_CHUNK) { bool from_grant = true; int i; @@ -899,7 +913,8 @@ refresh: ofd_grant_shrink(exp, oa, left); else /* grant more space back to the client if possible */ - oa->o_grant = ofd_grant(exp, oa->o_grant, oa->o_undirty, left); + oa->o_grant = ofd_grant(exp, oa->o_grant, oa->o_undirty, left, + true); spin_unlock(&ofd->ofd_grant_lock); } @@ -919,7 +934,6 @@ int ofd_grant_create(const struct lu_env *env, struct obd_export *exp, int *nr) struct filter_export_data *fed = &exp->exp_filter_data; obd_size left = 0; unsigned long wanted; - ENTRY; info->fti_used = 0; @@ -941,7 +955,7 @@ int ofd_grant_create(const struct lu_env *env, struct obd_export *exp, int *nr) (ofd->ofd_osfs.os_blocks >> 10)) { spin_unlock(&ofd->ofd_grant_lock); CDEBUG(D_RPCTRACE, "%s: not enough space for create "LPU64"\n", - ofd_obd(ofd)->obd_name, + ofd_name(ofd), ofd->ofd_osfs.os_bavail * ofd->ofd_osfs.os_blocks); RETURN(-ENOSPC); } @@ -982,9 +996,14 @@ int ofd_grant_create(const struct lu_env *env, struct obd_export *exp, int *nr) fed->fed_pending += info->fti_used; ofd->ofd_tot_pending += info->fti_used; - /* grant more space (twice as much as needed for this request) for - * precreate purpose if possible */ - ofd_grant(exp, fed->fed_grant, wanted * 2, left); + /* grant more space for precreate purpose if possible. */ + wanted = OST_MAX_PRECREATE * ofd->ofd_dt_conf.ddp_inodespace / 2; + if (wanted > fed->fed_grant) { + /* always try to book enough space to handle a large precreate + * request */ + wanted -= fed->fed_grant; + ofd_grant(exp, fed->fed_grant, wanted, left, false); + } spin_unlock(&ofd->ofd_grant_lock); RETURN(0); }