KVM: s390: Fix possible memory leak of in kvm_arch_vcpu_create()
[safe/jmp/linux-2.6] / net / sched / sch_hfsc.c
index 74226b2..b38b39c 100644 (file)
@@ -77,7 +77,7 @@
  *   The service curve parameters are converted to the internal
  *   representation. The slope values are scaled to avoid overflow.
  *   the inverse slope values as well as the y-projection of the 1st
- *   segment are kept in order to to avoid 64-bit divide operations
+ *   segment are kept in order to avoid 64-bit divide operations
  *   that are expensive on 32-bit architectures.
  */
 
@@ -116,7 +116,7 @@ struct hfsc_class
        struct Qdisc_class_common cl_common;
        unsigned int    refcnt;         /* usage count */
 
-       struct gnet_stats_basic bstats;
+       struct gnet_stats_basic_packed bstats;
        struct gnet_stats_queue qstats;
        struct gnet_stats_rate_est rate_est;
        unsigned int    level;          /* class level in hierarchy */
@@ -372,7 +372,7 @@ cftree_update(struct hfsc_class *cl)
  *     ism: (psched_us/byte) << ISM_SHIFT
  *     dx: psched_us
  *
- * The clock source resolution with ktime is 1.024us.
+ * The clock source resolution with ktime and PSCHED_SHIFT 10 is 1.024us.
  *
  * sm and ism are scaled in order to keep effective digits.
  * SM_SHIFT and ISM_SHIFT are selected to keep at least 4 effective
@@ -383,9 +383,11 @@ cftree_update(struct hfsc_class *cl)
  *  bytes/1.024us 12.8e-3    128e-3     1280e-3    12800e-3   128000e-3
  *
  *  1.024us/byte  78.125     7.8125     0.78125    0.078125   0.0078125
+ *
+ * So, for PSCHED_SHIFT 10 we need: SM_SHIFT 20, ISM_SHIFT 18.
  */
-#define        SM_SHIFT        20
-#define        ISM_SHIFT       18
+#define        SM_SHIFT        (30 - PSCHED_SHIFT)
+#define        ISM_SHIFT       (8 + PSCHED_SHIFT)
 
 #define        SM_MASK         ((1ULL << SM_SHIFT) - 1)
 #define        ISM_MASK        ((1ULL << ISM_SHIFT) - 1)
@@ -1139,8 +1141,11 @@ hfsc_delete_class(struct Qdisc *sch, unsigned long arg)
        hfsc_purge_queue(sch, cl);
        qdisc_class_hash_remove(&q->clhash, &cl->cl_common);
 
-       if (--cl->refcnt == 0)
-               hfsc_destroy_class(sch, cl);
+       BUG_ON(--cl->refcnt == 0);
+       /*
+        * This shouldn't happen: we "hold" one cops->get() when called
+        * from tc_ctl_tclass; the destroy method is done from cops->put().
+        */
 
        sch_tree_unlock(sch);
        return 0;
@@ -1198,8 +1203,6 @@ hfsc_graft_class(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
 {
        struct hfsc_class *cl = (struct hfsc_class *)arg;
 
-       if (cl == NULL)
-               return -ENOENT;
        if (cl->level > 0)
                return -EINVAL;
        if (new == NULL) {
@@ -1223,7 +1226,7 @@ hfsc_class_leaf(struct Qdisc *sch, unsigned long arg)
 {
        struct hfsc_class *cl = (struct hfsc_class *)arg;
 
-       if (cl != NULL && cl->level == 0)
+       if (cl->level == 0)
                return cl->qdisc;
 
        return NULL;
@@ -1372,7 +1375,7 @@ hfsc_dump_class_stats(struct Qdisc *sch, unsigned long arg,
        xstats.rtwork  = cl->cl_cumul;
 
        if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
-           gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 ||
+           gnet_stats_copy_rate_est(d, &cl->bstats, &cl->rate_est) < 0 ||
            gnet_stats_copy_queue(d, &cl->qstats) < 0)
                return -1;