}
 EXPORT_SYMBOL_GPL(blkiocg_update_io_remove_stats);
 
-void blkiocg_update_timeslice_used(struct blkio_group *blkg, unsigned long time)
+void blkiocg_update_timeslice_used(struct blkio_group *blkg, unsigned long time,
+                               unsigned long unaccounted_time)
 {
        unsigned long flags;
 
        spin_lock_irqsave(&blkg->stats_lock, flags);
        blkg->stats.time += time;
+       blkg->stats.unaccounted_time += unaccounted_time;
        spin_unlock_irqrestore(&blkg->stats_lock, flags);
 }
 EXPORT_SYMBOL_GPL(blkiocg_update_timeslice_used);
        if (type == BLKIO_STAT_SECTORS)
                return blkio_fill_stat(key_str, MAX_KEY_LEN - 1,
                                        blkg->stats.sectors, cb, dev);
+       if (type == BLKIO_STAT_UNACCOUNTED_TIME)
+               return blkio_fill_stat(key_str, MAX_KEY_LEN - 1,
+                                       blkg->stats.unaccounted_time, cb, dev);
 #ifdef CONFIG_DEBUG_BLK_CGROUP
        if (type == BLKIO_STAT_AVG_QUEUE_SIZE) {
                uint64_t sum = blkg->stats.avg_queue_size_sum;
                case BLKIO_PROP_sectors:
                        return blkio_read_blkg_stats(blkcg, cft, cb,
                                                BLKIO_STAT_SECTORS, 0);
+               case BLKIO_PROP_unaccounted_time:
+                       return blkio_read_blkg_stats(blkcg, cft, cb,
+                                               BLKIO_STAT_UNACCOUNTED_TIME, 0);
                case BLKIO_PROP_io_service_bytes:
                        return blkio_read_blkg_stats(blkcg, cft, cb,
                                                BLKIO_STAT_SERVICE_BYTES, 1);
                                BLKIO_PROP_sectors),
                .read_map = blkiocg_file_read_map,
        },
+       {
+               .name = "unaccounted_time",
+               .private = BLKIOFILE_PRIVATE(BLKIO_POLICY_PROP,
+                               BLKIO_PROP_unaccounted_time),
+               .read_map = blkiocg_file_read_map,
+       },
        {
                .name = "io_service_bytes",
                .private = BLKIOFILE_PRIVATE(BLKIO_POLICY_PROP,
 
        /* All the single valued stats go below this */
        BLKIO_STAT_TIME,
        BLKIO_STAT_SECTORS,
+       /* Time not charged to this cgroup */
+       BLKIO_STAT_UNACCOUNTED_TIME,
 #ifdef CONFIG_DEBUG_BLK_CGROUP
        BLKIO_STAT_AVG_QUEUE_SIZE,
        BLKIO_STAT_IDLE_TIME,
        BLKIO_PROP_io_serviced,
        BLKIO_PROP_time,
        BLKIO_PROP_sectors,
+       BLKIO_PROP_unaccounted_time,
        BLKIO_PROP_io_service_time,
        BLKIO_PROP_io_wait_time,
        BLKIO_PROP_io_merged,
        /* total disk time and nr sectors dispatched by this group */
        uint64_t time;
        uint64_t sectors;
+       /* Time not charged to this cgroup */
+       uint64_t unaccounted_time;
        uint64_t stat_arr[BLKIO_STAT_QUEUED + 1][BLKIO_STAT_TOTAL];
 #ifdef CONFIG_DEBUG_BLK_CGROUP
        /* Sum of number of IOs queued across all samples */
 extern struct blkio_group *blkiocg_lookup_group(struct blkio_cgroup *blkcg,
                                                void *key);
 void blkiocg_update_timeslice_used(struct blkio_group *blkg,
-                                       unsigned long time);
+                                       unsigned long time,
+                                       unsigned long unaccounted_time);
 void blkiocg_update_dispatch_stats(struct blkio_group *blkg, uint64_t bytes,
                                                bool direction, bool sync);
 void blkiocg_update_completion_stats(struct blkio_group *blkg,
 static inline struct blkio_group *
 blkiocg_lookup_group(struct blkio_cgroup *blkcg, void *key) { return NULL; }
 static inline void blkiocg_update_timeslice_used(struct blkio_group *blkg,
-                                               unsigned long time) {}
+                                               unsigned long time,
+                                               unsigned long unaccounted_time)
+{}
 static inline void blkiocg_update_dispatch_stats(struct blkio_group *blkg,
                                uint64_t bytes, bool direction, bool sync) {}
 static inline void blkiocg_update_completion_stats(struct blkio_group *blkg,
 
        cfq_blkiocg_update_dequeue_stats(&cfqg->blkg, 1);
 }
 
-static inline unsigned int cfq_cfqq_slice_usage(struct cfq_queue *cfqq)
+static inline unsigned int cfq_cfqq_slice_usage(struct cfq_queue *cfqq,
+                                               unsigned int *unaccounted_time)
 {
        unsigned int slice_used;
 
                                        1);
        } else {
                slice_used = jiffies - cfqq->slice_start;
-               if (slice_used > cfqq->allocated_slice)
+               if (slice_used > cfqq->allocated_slice) {
+                       *unaccounted_time = slice_used - cfqq->allocated_slice;
                        slice_used = cfqq->allocated_slice;
+               }
+               if (time_after(cfqq->slice_start, cfqq->dispatch_start))
+                       *unaccounted_time += cfqq->slice_start -
+                                       cfqq->dispatch_start;
        }
 
        return slice_used;
                                struct cfq_queue *cfqq)
 {
        struct cfq_rb_root *st = &cfqd->grp_service_tree;
-       unsigned int used_sl, charge;
+       unsigned int used_sl, charge, unaccounted_sl = 0;
        int nr_sync = cfqg->nr_cfqq - cfqg_busy_async_queues(cfqd, cfqg)
                        - cfqg->service_tree_idle.count;
 
        BUG_ON(nr_sync < 0);
-       used_sl = charge = cfq_cfqq_slice_usage(cfqq);
+       used_sl = charge = cfq_cfqq_slice_usage(cfqq, &unaccounted_sl);
 
        if (iops_mode(cfqd))
                charge = cfqq->slice_dispatch;
        cfq_log_cfqq(cfqq->cfqd, cfqq, "sl_used=%u disp=%u charge=%u iops=%u"
                        " sect=%u", used_sl, cfqq->slice_dispatch, charge,
                        iops_mode(cfqd), cfqq->nr_sectors);
-       cfq_blkiocg_update_timeslice_used(&cfqg->blkg, used_sl);
+       cfq_blkiocg_update_timeslice_used(&cfqg->blkg, used_sl,
+                                         unaccounted_sl);
        cfq_blkiocg_set_start_empty_time(&cfqg->blkg);
 }
 
        BUG_ON(!cfq_cfqq_on_rr(cfqq));
 
        cfq_service_tree_add(cfqd, cfqq, 1);
-
-       cfqq->slice_end = 0;
-       cfq_mark_cfqq_slice_new(cfqq);
+       __cfq_set_active_queue(cfqd, cfqq);
 }
 
 /*
 
 }
 
 static inline void cfq_blkiocg_update_timeslice_used(struct blkio_group *blkg,
-                       unsigned long time)
+                       unsigned long time, unsigned long unaccounted_time)
 {
-       blkiocg_update_timeslice_used(blkg, time);
+       blkiocg_update_timeslice_used(blkg, time, unaccounted_time);
 }
 
 static inline void cfq_blkiocg_set_start_empty_time(struct blkio_group *blkg)
                        unsigned long dequeue) {}
 
 static inline void cfq_blkiocg_update_timeslice_used(struct blkio_group *blkg,
-                       unsigned long time) {}
+                       unsigned long time, unsigned long unaccounted_time) {}
 static inline void cfq_blkiocg_set_start_empty_time(struct blkio_group *blkg) {}
 static inline void cfq_blkiocg_update_io_remove_stats(struct blkio_group *blkg,
                                bool direction, bool sync) {}