perf stat: Don't report a null stalled cycles per insn metric
[linux-2.6-microblaze.git] / block / bfq-cgroup.c
index e1419ed..09b69a3 100644 (file)
@@ -332,7 +332,7 @@ static void bfqg_put(struct bfq_group *bfqg)
                kfree(bfqg);
 }
 
-static void bfqg_and_blkg_get(struct bfq_group *bfqg)
+void bfqg_and_blkg_get(struct bfq_group *bfqg)
 {
        /* see comments in bfq_bic_update_cgroup for why refcounting bfqg */
        bfqg_get(bfqg);
@@ -651,9 +651,15 @@ void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
                bfq_bfqq_expire(bfqd, bfqd->in_service_queue,
                                false, BFQQE_PREEMPTED);
 
+       /*
+        * get extra reference to prevent bfqq from being freed in
+        * next possible deactivate
+        */
+       bfqq->ref++;
+
        if (bfq_bfqq_busy(bfqq))
                bfq_deactivate_bfqq(bfqd, bfqq, false, false);
-       else if (entity->on_st)
+       else if (entity->on_st_or_in_serv)
                bfq_put_idle_entity(bfq_entity_service_tree(entity), entity);
        bfqg_and_blkg_put(bfqq_group(bfqq));
 
@@ -670,6 +676,8 @@ void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
 
        if (!bfqd->in_service_queue && !bfqd->rq_in_driver)
                bfq_schedule_dispatch(bfqd);
+       /* release extra ref taken above */
+       bfq_put_queue(bfqq);
 }
 
 /**
@@ -1398,6 +1406,10 @@ struct bfq_group *bfqq_group(struct bfq_queue *bfqq)
        return bfqq->bfqd->root_group;
 }
 
+void bfqg_and_blkg_get(struct bfq_group *bfqg) {}
+
+void bfqg_and_blkg_put(struct bfq_group *bfqg) {}
+
 struct bfq_group *bfq_create_group_hierarchy(struct bfq_data *bfqd, int node)
 {
        struct bfq_group *bfqg;