|
@@ -187,3 +187,131 @@ struct cfqg_stats {
|
|
|
struct blkg_rwstat queued;
|
|
|
/* total sectors transferred */
|
|
|
struct blkg_stat sectors;
|
|
|
+ /* total disk time and nr sectors dispatched by this group */
|
|
|
+ struct blkg_stat time;
|
|
|
+#ifdef CONFIG_DEBUG_BLK_CGROUP
|
|
|
+ /* time not charged to this cgroup */
|
|
|
+ struct blkg_stat unaccounted_time;
|
|
|
+ /* sum of number of ios queued across all samples */
|
|
|
+ struct blkg_stat avg_queue_size_sum;
|
|
|
+ /* count of samples taken for average */
|
|
|
+ struct blkg_stat avg_queue_size_samples;
|
|
|
+ /* how many times this group has been removed from service tree */
|
|
|
+ struct blkg_stat dequeue;
|
|
|
+ /* total time spent waiting for it to be assigned a timeslice. */
|
|
|
+ struct blkg_stat group_wait_time;
|
|
|
+ /* time spent idling for this blkcg_gq */
|
|
|
+ struct blkg_stat idle_time;
|
|
|
+ /* total time with empty current active q with other requests queued */
|
|
|
+ struct blkg_stat empty_time;
|
|
|
+ /* fields after this shouldn't be cleared on stat reset */
|
|
|
+ uint64_t start_group_wait_time;
|
|
|
+ uint64_t start_idle_time;
|
|
|
+ uint64_t start_empty_time;
|
|
|
+ uint16_t flags;
|
|
|
+#endif /* CONFIG_DEBUG_BLK_CGROUP */
|
|
|
+#endif /* CONFIG_CFQ_GROUP_IOSCHED */
|
|
|
+};
|
|
|
+
|
|
|
+/* This is per cgroup per device grouping structure */
|
|
|
+struct cfq_group {
|
|
|
+ /* must be the first member */
|
|
|
+ struct blkg_policy_data pd;
|
|
|
+
|
|
|
+ /* group service_tree member */
|
|
|
+ struct rb_node rb_node;
|
|
|
+
|
|
|
+ /* group service_tree key */
|
|
|
+ u64 vdisktime;
|
|
|
+ unsigned int weight;
|
|
|
+ unsigned int new_weight;
|
|
|
+ unsigned int dev_weight;
|
|
|
+
|
|
|
+ /* number of cfqq currently on this group */
|
|
|
+ int nr_cfqq;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Per group busy queues average. Useful for workload slice calc. We
|
|
|
+ * create the array for each prio class but at run time it is used
|
|
|
+ * only for RT and BE class and slot for IDLE class remains unused.
|
|
|
+ * This is primarily done to avoid confusion and a gcc warning.
|
|
|
+ */
|
|
|
+ unsigned int busy_queues_avg[CFQ_PRIO_NR];
|
|
|
+ /*
|
|
|
+ * rr lists of queues with requests. We maintain service trees for
|
|
|
+ * RT and BE classes. These trees are subdivided in subclasses
|
|
|
+ * of SYNC, SYNC_NOIDLE and ASYNC based on workload type. For IDLE
|
|
|
+ * class there is no subclassification and all the cfq queues go on
|
|
|
+ * a single tree service_tree_idle.
|
|
|
+ * Counts are embedded in the cfq_rb_root
|
|
|
+ */
|
|
|
+ struct cfq_rb_root service_trees[2][3];
|
|
|
+ struct cfq_rb_root service_tree_idle;
|
|
|
+
|
|
|
+ unsigned long saved_workload_slice;
|
|
|
+ enum wl_type_t saved_workload;
|
|
|
+ enum wl_prio_t saved_serving_prio;
|
|
|
+
|
|
|
+ /* number of requests that are on the dispatch list or inside driver */
|
|
|
+ int dispatched;
|
|
|
+ struct cfq_ttime ttime;
|
|
|
+ struct cfqg_stats stats;
|
|
|
+};
|
|
|
+
|
|
|
+struct cfq_io_cq {
|
|
|
+ struct io_cq icq; /* must be the first member */
|
|
|
+ struct cfq_queue *cfqq[2];
|
|
|
+ struct cfq_ttime ttime;
|
|
|
+ int ioprio; /* the current ioprio */
|
|
|
+#ifdef CONFIG_CFQ_GROUP_IOSCHED
|
|
|
+ uint64_t blkcg_id; /* the current blkcg ID */
|
|
|
+#endif
|
|
|
+};
|
|
|
+
|
|
|
+/*
|
|
|
+ * Per block device queue structure
|
|
|
+ */
|
|
|
+struct cfq_data {
|
|
|
+ struct request_queue *queue;
|
|
|
+ /* Root service tree for cfq_groups */
|
|
|
+ struct cfq_rb_root grp_service_tree;
|
|
|
+ struct cfq_group *root_group;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The priority currently being served
|
|
|
+ */
|
|
|
+ enum wl_prio_t serving_prio;
|
|
|
+ enum wl_type_t serving_type;
|
|
|
+ unsigned long workload_expires;
|
|
|
+ struct cfq_group *serving_group;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Each priority tree is sorted by next_request position. These
|
|
|
+ * trees are used when determining if two or more queues are
|
|
|
+ * interleaving requests (see cfq_close_cooperator).
|
|
|
+ */
|
|
|
+ struct rb_root prio_trees[CFQ_PRIO_LISTS];
|
|
|
+
|
|
|
+ unsigned int busy_queues;
|
|
|
+ unsigned int busy_sync_queues;
|
|
|
+
|
|
|
+ int rq_in_driver;
|
|
|
+ int rq_in_flight[2];
|
|
|
+
|
|
|
+ /*
|
|
|
+ * queue-depth detection
|
|
|
+ */
|
|
|
+ int rq_queued;
|
|
|
+ int hw_tag;
|
|
|
+ /*
|
|
|
+ * hw_tag can be
|
|
|
+ * -1 => indeterminate, (cfq will behave as if NCQ is present, to allow better detection)
|
|
|
+ * 1 => NCQ is present (hw_tag_est_depth is the estimated max depth)
|
|
|
+ * 0 => no NCQ
|
|
|
+ */
|
|
|
+ int hw_tag_est_depth;
|
|
|
+ unsigned int hw_tag_samples;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * idle window management
|
|
|
+ */
|