@@ -1448,14 +1448,18 @@ static int iocg_wake_fn(struct wait_queue_entry *wq_entry, unsigned mode,
{
struct iocg_wait *wait = container_of(wq_entry, struct iocg_wait, wait);
struct iocg_wake_ctx *ctx = key;
- u64 cost = abs_cost_to_cost(wait->abs_cost, ctx->hw_inuse);
- ctx->vbudget -= cost;
+ if (ctx->iocg->online) {
+ u64 cost = abs_cost_to_cost(wait->abs_cost, ctx->hw_inuse);
- if (ctx->vbudget < 0)
- return -1;
+ ctx->vbudget -= cost;
+
+ if (ctx->vbudget < 0)
+ return -1;
+
+ iocg_commit_bio(ctx->iocg, wait->bio, wait->abs_cost, cost);
+ }
- iocg_commit_bio(ctx->iocg, wait->bio, wait->abs_cost, cost);
wait->committed = true;
/*
@@ -3003,9 +3007,14 @@ static void ioc_pd_offline(struct blkg_policy_data *pd)
unsigned long flags;
if (ioc) {
- spin_lock_irqsave(&ioc->lock, flags);
+ struct iocg_wake_ctx ctx = { .iocg = iocg };
+
+ iocg_lock(iocg, true, &flags);
iocg->online = false;
- spin_unlock_irqrestore(&ioc->lock, flags);
+ iocg_unlock(iocg, true, &flags);
+
+ hrtimer_cancel(&iocg->waitq_timer);
+ __wake_up(&iocg->waitq, TASK_NORMAL, 0, &ctx);
}
}
@@ -3030,8 +3039,6 @@ static void ioc_pd_free(struct blkg_policy_data *pd)
WARN_ON_ONCE(!list_empty(&iocg->surplus_list));
spin_unlock_irqrestore(&ioc->lock, flags);
-
- hrtimer_cancel(&iocg->waitq_timer);
}
free_percpu(iocg->pcpu_stat);
kfree(iocg);