bdev/ftl: Add defrag parameters to construct_ftl_bdev rpc
Added parsing and saving of (optional) parameters which are responsible for relocation in FTL. Changing the parameters may affect Write Amplification Factor and overall performance, especially during random write workloads. If parameters are not specified, default values will be used. Signed-off-by: Mateusz Kozlowski <mateusz.kozlowski@intel.com> Change-Id: Ic0229e39109460f3541c31e1cbf2a485efe408c6 Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/460504 Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com> Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
7a867c4fdb
commit
cd115ecfcd
@ -430,6 +430,7 @@ bdev_ftl_write_config_json(struct spdk_bdev *bdev, struct spdk_json_write_ctx *w
|
||||
{
|
||||
struct ftl_bdev *ftl_bdev = bdev->ctxt;
|
||||
struct spdk_ftl_attrs attrs;
|
||||
struct spdk_ftl_conf *conf = &attrs.conf;
|
||||
char uuid[SPDK_UUID_STRING_LEN];
|
||||
|
||||
spdk_ftl_dev_get_attrs(ftl_bdev->dev, &attrs);
|
||||
@ -441,7 +442,16 @@ bdev_ftl_write_config_json(struct spdk_bdev *bdev, struct spdk_json_write_ctx *w
|
||||
spdk_json_write_named_object_begin(w, "params");
|
||||
spdk_json_write_named_string(w, "name", ftl_bdev->bdev.name);
|
||||
|
||||
spdk_json_write_named_bool(w, "allow_open_bands", attrs.conf.allow_open_bands);
|
||||
spdk_json_write_named_bool(w, "allow_open_bands", conf->allow_open_bands);
|
||||
spdk_json_write_named_uint64(w, "overprovisioning", conf->lba_rsvd);
|
||||
spdk_json_write_named_uint64(w, "limit_crit", conf->limits[SPDK_FTL_LIMIT_CRIT].limit);
|
||||
spdk_json_write_named_uint64(w, "limit_crit_threshold", conf->limits[SPDK_FTL_LIMIT_CRIT].thld);
|
||||
spdk_json_write_named_uint64(w, "limit_high", conf->limits[SPDK_FTL_LIMIT_HIGH].limit);
|
||||
spdk_json_write_named_uint64(w, "limit_high_threshold", conf->limits[SPDK_FTL_LIMIT_HIGH].thld);
|
||||
spdk_json_write_named_uint64(w, "limit_low", conf->limits[SPDK_FTL_LIMIT_LOW].limit);
|
||||
spdk_json_write_named_uint64(w, "limit_low_threshold", conf->limits[SPDK_FTL_LIMIT_LOW].thld);
|
||||
spdk_json_write_named_uint64(w, "limit_start", conf->limits[SPDK_FTL_LIMIT_START].limit);
|
||||
spdk_json_write_named_uint64(w, "limit_start_threshold", conf->limits[SPDK_FTL_LIMIT_START].thld);
|
||||
|
||||
spdk_uuid_fmt_lower(uuid, sizeof(uuid), &attrs.uuid);
|
||||
spdk_json_write_named_string(w, "uuid", uuid);
|
||||
|
@ -71,6 +71,58 @@ static const struct spdk_json_object_decoder rpc_construct_ftl_decoders[] = {
|
||||
"allow_open_bands", offsetof(struct rpc_construct_ftl, ftl_conf) +
|
||||
offsetof(struct spdk_ftl_conf, allow_open_bands), spdk_json_decode_bool, true
|
||||
},
|
||||
{
|
||||
"overprovisioning", offsetof(struct rpc_construct_ftl, ftl_conf) +
|
||||
offsetof(struct spdk_ftl_conf, lba_rsvd), spdk_json_decode_uint64, true
|
||||
},
|
||||
{
|
||||
"limit_crit", offsetof(struct rpc_construct_ftl, ftl_conf) +
|
||||
offsetof(struct spdk_ftl_conf, limits[SPDK_FTL_LIMIT_CRIT]) +
|
||||
offsetof(struct spdk_ftl_limit, limit),
|
||||
spdk_json_decode_uint64, true
|
||||
},
|
||||
{
|
||||
"limit_crit_threshold", offsetof(struct rpc_construct_ftl, ftl_conf) +
|
||||
offsetof(struct spdk_ftl_conf, limits[SPDK_FTL_LIMIT_CRIT]) +
|
||||
offsetof(struct spdk_ftl_limit, thld),
|
||||
spdk_json_decode_uint64, true
|
||||
},
|
||||
{
|
||||
"limit_high", offsetof(struct rpc_construct_ftl, ftl_conf) +
|
||||
offsetof(struct spdk_ftl_conf, limits[SPDK_FTL_LIMIT_HIGH]) +
|
||||
offsetof(struct spdk_ftl_limit, limit),
|
||||
spdk_json_decode_uint64, true
|
||||
},
|
||||
{
|
||||
"limit_high_threshold", offsetof(struct rpc_construct_ftl, ftl_conf) +
|
||||
offsetof(struct spdk_ftl_conf, limits[SPDK_FTL_LIMIT_HIGH]) +
|
||||
offsetof(struct spdk_ftl_limit, thld),
|
||||
spdk_json_decode_uint64, true
|
||||
},
|
||||
{
|
||||
"limit_low", offsetof(struct rpc_construct_ftl, ftl_conf) +
|
||||
offsetof(struct spdk_ftl_conf, limits[SPDK_FTL_LIMIT_LOW]) +
|
||||
offsetof(struct spdk_ftl_limit, limit),
|
||||
spdk_json_decode_uint64, true
|
||||
},
|
||||
{
|
||||
"limit_low_threshold", offsetof(struct rpc_construct_ftl, ftl_conf) +
|
||||
offsetof(struct spdk_ftl_conf, limits[SPDK_FTL_LIMIT_LOW]) +
|
||||
offsetof(struct spdk_ftl_limit, thld),
|
||||
spdk_json_decode_uint64, true
|
||||
},
|
||||
{
|
||||
"limit_start", offsetof(struct rpc_construct_ftl, ftl_conf) +
|
||||
offsetof(struct spdk_ftl_conf, limits[SPDK_FTL_LIMIT_START]) +
|
||||
offsetof(struct spdk_ftl_limit, limit),
|
||||
spdk_json_decode_uint64, true
|
||||
},
|
||||
{
|
||||
"limit_start_threshold", offsetof(struct rpc_construct_ftl, ftl_conf) +
|
||||
offsetof(struct spdk_ftl_conf, limits[SPDK_FTL_LIMIT_START]) +
|
||||
offsetof(struct spdk_ftl_limit, thld),
|
||||
spdk_json_decode_uint64, true
|
||||
},
|
||||
};
|
||||
|
||||
#define FTL_RANGE_MAX_LENGTH 32
|
||||
|
@ -1299,7 +1299,24 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse
|
||||
p.set_defaults(func=destruct_split_vbdev)
|
||||
|
||||
# ftl
|
||||
ftl_valid_limits = ('crit', 'high', 'low', 'start')
|
||||
|
||||
def construct_ftl_bdev(args):
|
||||
def parse_limits(limits, arg_dict, key_suffix=''):
|
||||
for limit in limits.split(','):
|
||||
key, value = limit.split(':', 1)
|
||||
if key in ftl_valid_limits:
|
||||
arg_dict['limit_' + key + key_suffix] = int(value)
|
||||
else:
|
||||
raise ValueError('Limit {} is not supported'.format(key))
|
||||
|
||||
arg_limits = {}
|
||||
if args.limit_threshold:
|
||||
parse_limits(args.limit_threshold, arg_limits, '_threshold')
|
||||
|
||||
if args.limit:
|
||||
parse_limits(args.limit, arg_limits)
|
||||
|
||||
print_dict(rpc.bdev.construct_ftl_bdev(args.client,
|
||||
name=args.name,
|
||||
trtype=args.trtype,
|
||||
@ -1307,7 +1324,9 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse
|
||||
punits=args.punits,
|
||||
uuid=args.uuid,
|
||||
cache=args.cache,
|
||||
allow_open_bands=args.allow_open_bands))
|
||||
allow_open_bands=args.allow_open_bands,
|
||||
overprovisioning=args.overprovisioning,
|
||||
**arg_limits))
|
||||
|
||||
p = subparsers.add_parser('construct_ftl_bdev',
|
||||
help='Add FTL bdev')
|
||||
@ -1323,6 +1342,15 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse
|
||||
p.add_argument('-c', '--cache', help='Name of the bdev to be used as a write buffer cache (optional)')
|
||||
p.add_argument('-o', '--allow_open_bands', help='Restoring after dirty shutdown without cache will'
|
||||
' result in partial data recovery, instead of error', action='store_true')
|
||||
p.add_argument('--overprovisioning', help='Percentage of device used for relocation, not exposed'
|
||||
' to user (optional)', type=int)
|
||||
|
||||
limits = p.add_argument_group('Defrag limits', 'Configures defrag limits and thresholds for'
|
||||
' levels ' + str(ftl_valid_limits)[1:-1])
|
||||
limits.add_argument('--limit', help='Percentage of allowed user versus internal writes at given'
|
||||
' levels, e.g. crit:0,high:20,low:80')
|
||||
limits.add_argument('--limit-threshold', help='Number of free bands triggering a given level of'
|
||||
' write limiting e.g. crit:1,high:2,low:3,start:4')
|
||||
p.set_defaults(func=construct_ftl_bdev)
|
||||
|
||||
def delete_ftl_bdev(args):
|
||||
|
@ -596,7 +596,7 @@ def destruct_split_vbdev(client, base_bdev):
|
||||
return client.call('destruct_split_vbdev', params)
|
||||
|
||||
|
||||
def construct_ftl_bdev(client, name, trtype, traddr, punits, allow_open_bands=None, uuid=None, cache=None):
|
||||
def construct_ftl_bdev(client, name, trtype, traddr, punits, **kwargs):
|
||||
"""Construct FTL bdev
|
||||
|
||||
Args:
|
||||
@ -604,20 +604,15 @@ def construct_ftl_bdev(client, name, trtype, traddr, punits, allow_open_bands=No
|
||||
trtype: transport type
|
||||
traddr: transport address
|
||||
punit: parallel unit range
|
||||
uuid: UUID of the device
|
||||
cache: name of the write buffer bdev
|
||||
allow_open_bands: allow for partial restore after dirty shutdown
|
||||
kwargs: optional parameters
|
||||
"""
|
||||
params = {'name': name,
|
||||
'trtype': trtype,
|
||||
'traddr': traddr,
|
||||
'punits': punits}
|
||||
if uuid:
|
||||
params['uuid'] = uuid
|
||||
if cache:
|
||||
params['cache'] = cache
|
||||
if allow_open_bands:
|
||||
params['allow_open_bands'] = allow_open_bands
|
||||
for key, value in kwargs.items():
|
||||
if value is not None:
|
||||
params[key] = value
|
||||
|
||||
return client.call('construct_ftl_bdev', params)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user