Commit cd115ecf authored by Mateusz Kozlowski's avatar Mateusz Kozlowski Committed by Jim Harris
Browse files

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: default avatarMateusz Kozlowski <mateusz.kozlowski@intel.com>
Change-Id: Ic0229e39109460f3541c31e1cbf2a485efe408c6
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/460504


Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Reviewed-by: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 7a867c4f
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -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);
+52 −0
Original line number Diff line number Diff line
@@ -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
+29 −1
Original line number Diff line number Diff line
@@ -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):
+5 −10
Original line number Diff line number Diff line
@@ -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)