static int sfb_change(struct Qdisc *sch, struct nlattr *opt,
		      struct netlink_ext_ack *extack)
{
	struct sfb_sched_data *q = qdisc_priv(sch);
	struct Qdisc *child, *old;
	struct nlattr *tb[TCA_SFB_MAX + 1];
	const struct tc_sfb_qopt *ctl = &sfb_default_ops;
	u32 limit;
	int err;

	if (opt) {
		err = nla_parse_nested_deprecated(tb, TCA_SFB_MAX, opt,
						  sfb_policy, NULL);
		if (err < 0)
			return -EINVAL;

		if (tb[TCA_SFB_PARMS] == NULL)
			return -EINVAL;

		ctl = nla_data(tb[TCA_SFB_PARMS]);
	}

	limit = ctl->limit;
	if (limit == 0)
		limit = qdisc_dev(sch)->tx_queue_len;

	child = fifo_create_dflt(sch, &pfifo_qdisc_ops, limit, extack);
	if (IS_ERR(child))
		return PTR_ERR(child);

	if (child != &noop_qdisc)
		qdisc_hash_add(child, true);
	sch_tree_lock(sch);

	qdisc_purge_queue(q->qdisc);
	old = q->qdisc;
	q->qdisc = child;

	q->rehash_interval = msecs_to_jiffies(ctl->rehash_interval);
	q->warmup_time = msecs_to_jiffies(ctl->warmup_time);
	q->rehash_time = jiffies;
	q->limit = limit;
	q->increment = ctl->increment;
	q->decrement = ctl->decrement;
	q->max = ctl->max;
	q->bin_size = ctl->bin_size;
	q->penalty_rate = ctl->penalty_rate;
	q->penalty_burst = ctl->penalty_burst;
	q->tokens_avail = ctl->penalty_burst;
	q->token_time = jiffies;

	q->slot = 0;
	q->double_buffering = false;
	sfb_zero_all_buckets(q);
	sfb_init_perturbation(0, q);
	sfb_init_perturbation(1, q);

	sch_tree_unlock(sch);
	qdisc_put(old);

	return 0;
}
static int sfb_change(struct Qdisc *sch, struct nlattr *opt,
		      struct netlink_ext_ack *extack)
{
	struct sfb_sched_data *q = qdisc_priv(sch);
	struct Qdisc *child, *old;
	struct nlattr *tb[TCA_SFB_MAX + 1];
	const struct tc_sfb_qopt *ctl = &sfb_default_ops;
	u32 limit;
	int err;

	if (opt) {
		err = nla_parse_nested_deprecated(tb, TCA_SFB_MAX, opt,
						  sfb_policy, NULL);
		if (err < 0)
			return -EINVAL;

		if (tb[TCA_SFB_PARMS] == NULL)
			return -EINVAL;

		ctl = nla_data(tb[TCA_SFB_PARMS]);
	}

	limit = ctl->limit;
	if (limit == 0)
		limit = qdisc_dev(sch)->tx_queue_len;

	child = fifo_create_dflt(sch, &pfifo_qdisc_ops, limit, extack);
	if (IS_ERR(child))
		return PTR_ERR(child);

	if (child != &noop_qdisc)
		qdisc_hash_add(child, true);
	sch_tree_lock(sch);

	qdisc_purge_queue(q->qdisc);
	old = q->qdisc;
	q->qdisc = child;

	q->rehash_interval = msecs_to_jiffies(ctl->rehash_interval);
	q->warmup_time = msecs_to_jiffies(ctl->warmup_time);
	q->rehash_time = jiffies;
	q->limit = limit;
	q->increment = ctl->increment;
	q->decrement = ctl->decrement;
	q->max = ctl->max;
	q->bin_size = ctl->bin_size;
	q->penalty_rate = ctl->penalty_rate;
	q->penalty_burst = ctl->penalty_burst;
	q->tokens_avail = ctl->penalty_burst;
	q->token_time = jiffies;

	q->slot = 0;
	q->double_buffering = false;
	sfb_zero_all_buckets(q);
	sfb_init_perturbation(0, q);
	sfb_init_perturbation(1, q);

	sch_tree_unlock(sch);
	qdisc_put(old);

	return 0;
}