--- initial
+++ final
@@ -1,87 +1,87 @@
 static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **tca, unsigned long *arg, struct netlink_ext_ack *extack) {
   struct qfq_sched *q = qdisc_priv(sch);
   struct qfq_class *cl = (struct qfq_class *)*arg;
   bool existing = false;
   struct nlattr *tb[TCA_QFQ_MAX + 1];
   struct qfq_aggregate *new_agg = NULL;
   u32 weight, lmax, inv_w;
   int err;
   int delta_w;
   if (tca[TCA_OPTIONS] == NULL) {
     pr_notice("qfq: no options\n");
     return -EINVAL;
   }
   err = nla_parse_nested(tb, TCA_QFQ_MAX, tca[TCA_OPTIONS], qfq_policy, NULL);
   if (err < 0) return err;
   if (tb[TCA_QFQ_WEIGHT]) {
     weight = nla_get_u32(tb[TCA_QFQ_WEIGHT]);
     if (!weight || weight > (1UL << QFQ_MAX_WSHIFT)) {
       pr_notice("qfq: invalid weight %u\n", weight);
       return -EINVAL;
     }
   } else
     weight = 1;
   if (tb[TCA_QFQ_LMAX]) {
     lmax = nla_get_u32(tb[TCA_QFQ_LMAX]);
     if (lmax < QFQ_MIN_LMAX || lmax > (1UL << QFQ_MTU_SHIFT)) {
       pr_notice("qfq: invalid max length %u\n", lmax);
       return -EINVAL;
     }
   } else
     lmax = psched_mtu(qdisc_dev(sch));
   inv_w = ONE_FP / weight;
   weight = ONE_FP / inv_w;
   if (cl != NULL && lmax == cl->agg->lmax && weight == cl->agg->class_weight) return 0; /* nothing to change */
   delta_w = weight - (cl ? cl->agg->class_weight : 0);
   if (q->wsum + delta_w > QFQ_MAX_WSUM) {
     pr_notice("qfq: total weight out of range (%d + %u)\n", delta_w, q->wsum);
     return -EINVAL;
   }
   if (cl != NULL) { /* modify existing class */
     if (tca[TCA_RATE]) {
       err = gen_replace_estimator(&cl->bstats, NULL, &cl->rate_est, NULL, qdisc_root_sleeping_running(sch), tca[TCA_RATE]);
       if (err) return err;
     }
     existing = true;
     goto set_change_agg;
   }
   /* create and init new class */
   cl = kzalloc(sizeof(struct qfq_class), GFP_KERNEL);
   if (cl == NULL) return -ENOBUFS;
   cl->common.classid = classid;
   cl->deficit = lmax;
   cl->qdisc = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid, NULL);
   if (cl->qdisc == NULL) cl->qdisc = &noop_qdisc;
   if (tca[TCA_RATE]) {
     err = gen_new_estimator(&cl->bstats, NULL, &cl->rate_est, NULL, qdisc_root_sleeping_running(sch), tca[TCA_RATE]);
     if (err) goto destroy_class;
   }
   if (cl->qdisc != &noop_qdisc) qdisc_hash_add(cl->qdisc, true);
   sch_tree_lock(sch);
   qdisc_class_hash_insert(&q->clhash, &cl->common);
   sch_tree_unlock(sch);
   qdisc_class_hash_grow(sch, &q->clhash);
 set_change_agg:
   sch_tree_lock(sch);
   new_agg = qfq_find_agg(q, lmax, weight);
   if (new_agg == NULL) { /* create new aggregate */
     sch_tree_unlock(sch);
     new_agg = kzalloc(sizeof(*new_agg), GFP_KERNEL);
     if (new_agg == NULL) {
       err = -ENOBUFS;
       gen_kill_estimator(&cl->rate_est);
       goto destroy_class;
     }
     sch_tree_lock(sch);
     qfq_init_agg(q, new_agg, lmax, weight);
   }
   if (existing) qfq_deact_rm_from_agg(q, cl);
   qfq_add_to_agg(q, new_agg, cl);
   sch_tree_unlock(sch);
   *arg = (unsigned long)cl;
   return 0;
 destroy_class:
-  qdisc_destroy(cl->qdisc);
+  qdisc_put(cl->qdisc);
   kfree(cl);
   return err;
 }<sep>@@
expression old;
@@
-                               qdisc_destroy(old);
+                               qdisc_put(old);