+static int
+throttle_add_to_list(struct _throttle_io_info_t *info, uthread_t ut, int mylevel, boolean_t insert_tail)
+{
+ boolean_t start_timer = FALSE;
+ int level = THROTTLE_LEVEL_START;
+
+ if (TAILQ_EMPTY(&info->throttle_uthlist[mylevel])) {
+ info->throttle_start_IO_period_timestamp[mylevel] = info->throttle_last_IO_timestamp[mylevel];
+ start_timer = TRUE;
+ }
+
+ if (insert_tail == TRUE)
+ TAILQ_INSERT_TAIL(&info->throttle_uthlist[mylevel], ut, uu_throttlelist);
+ else
+ TAILQ_INSERT_HEAD(&info->throttle_uthlist[mylevel], ut, uu_throttlelist);
+
+ ut->uu_on_throttlelist = mylevel;
+
+ if (start_timer == TRUE) {
+ /* we may need to start or rearm the timer */
+ level = throttle_timer_start(info, FALSE, THROTTLE_LEVEL_START);
+
+ if (level == THROTTLE_LEVEL_END) {
+ if (ut->uu_on_throttlelist >= THROTTLE_LEVEL_THROTTLED) {
+ TAILQ_REMOVE(&info->throttle_uthlist[ut->uu_on_throttlelist], ut, uu_throttlelist);
+
+ ut->uu_on_throttlelist = THROTTLE_LEVEL_NONE;
+ }
+ }
+ }
+ return (level);
+}
+
+static void
+throttle_init_throttle_window(void)
+{
+ int throttle_window_size;
+
+ /*
+ * The hierarchy of throttle window values is as follows:
+ * - Global defaults
+ * - Device tree properties
+ * - Boot-args
+ * All values are specified in msecs.
+ */
+
+ /* Override global values with device-tree properties */
+ if (PE_get_default("kern.io_throttle_window_tier1", &throttle_window_size, sizeof(throttle_window_size)))
+ throttle_windows_msecs[THROTTLE_LEVEL_TIER1] = throttle_window_size;
+
+ if (PE_get_default("kern.io_throttle_window_tier2", &throttle_window_size, sizeof(throttle_window_size)))
+ throttle_windows_msecs[THROTTLE_LEVEL_TIER2] = throttle_window_size;
+
+ if (PE_get_default("kern.io_throttle_window_tier3", &throttle_window_size, sizeof(throttle_window_size)))
+ throttle_windows_msecs[THROTTLE_LEVEL_TIER3] = throttle_window_size;
+
+ /* Override with boot-args */
+ if (PE_parse_boot_argn("io_throttle_window_tier1", &throttle_window_size, sizeof(throttle_window_size)))
+ throttle_windows_msecs[THROTTLE_LEVEL_TIER1] = throttle_window_size;
+
+ if (PE_parse_boot_argn("io_throttle_window_tier2", &throttle_window_size, sizeof(throttle_window_size)))
+ throttle_windows_msecs[THROTTLE_LEVEL_TIER2] = throttle_window_size;
+
+ if (PE_parse_boot_argn("io_throttle_window_tier3", &throttle_window_size, sizeof(throttle_window_size)))
+ throttle_windows_msecs[THROTTLE_LEVEL_TIER3] = throttle_window_size;
+}
+
+static void
+throttle_init_throttle_period(struct _throttle_io_info_t *info, boolean_t isssd)
+{
+ int throttle_period_size;
+
+ /*
+ * The hierarchy of throttle period values is as follows:
+ * - Global defaults
+ * - Device tree properties
+ * - Boot-args
+ * All values are specified in msecs.
+ */
+
+ /* Assign global defaults */
+ if ((isssd == TRUE) && (info->throttle_is_fusion_with_priority == 0))
+ info->throttle_io_periods = &throttle_io_period_ssd_msecs[0];
+ else
+ info->throttle_io_periods = &throttle_io_period_msecs[0];
+
+ /* Override global values with device-tree properties */
+ if (PE_get_default("kern.io_throttle_period_tier1", &throttle_period_size, sizeof(throttle_period_size)))
+ info->throttle_io_periods[THROTTLE_LEVEL_TIER1] = throttle_period_size;
+
+ if (PE_get_default("kern.io_throttle_period_tier2", &throttle_period_size, sizeof(throttle_period_size)))
+ info->throttle_io_periods[THROTTLE_LEVEL_TIER2] = throttle_period_size;
+
+ if (PE_get_default("kern.io_throttle_period_tier3", &throttle_period_size, sizeof(throttle_period_size)))
+ info->throttle_io_periods[THROTTLE_LEVEL_TIER3] = throttle_period_size;
+
+ /* Override with boot-args */
+ if (PE_parse_boot_argn("io_throttle_period_tier1", &throttle_period_size, sizeof(throttle_period_size)))
+ info->throttle_io_periods[THROTTLE_LEVEL_TIER1] = throttle_period_size;
+
+ if (PE_parse_boot_argn("io_throttle_period_tier2", &throttle_period_size, sizeof(throttle_period_size)))
+ info->throttle_io_periods[THROTTLE_LEVEL_TIER2] = throttle_period_size;
+
+ if (PE_parse_boot_argn("io_throttle_period_tier3", &throttle_period_size, sizeof(throttle_period_size)))
+ info->throttle_io_periods[THROTTLE_LEVEL_TIER3] = throttle_period_size;
+
+}
+
+#if CONFIG_IOSCHED
+extern void vm_io_reprioritize_init(void);
+int iosched_enabled = 1;
+#endif
+