/* * cpudl_clear - remove a cpu from the cpudl max-heap * @cp: the cpudl max-heap context * @cpu: the target cpu * * Notes: assumes cpu_rq(cpu)->lock is locked * * Returns: (void) */ void cpudl_clear(struct cpudl *cp, int cpu) { int old_idx, new_cpu; unsigned long flags; WARN_ON(!cpu_present(cpu)); raw_spin_lock_irqsave(&cp->lock, flags); old_idx = cp->elements[cpu].idx; if (old_idx == IDX_INVALID) { /* * Nothing to remove if old_idx was invalid. * This could happen if a rq_offline_dl is * called for a CPU without -dl tasks running. */ } else { new_cpu = cp->elements[cp->size - 1].cpu; cp->elements[old_idx].dl = cp->elements[cp->size - 1].dl; cp->elements[old_idx].cpu = new_cpu; cp->size--; cp->elements[new_cpu].idx = old_idx; cp->elements[cpu].idx = IDX_INVALID; cpudl_heapify(cp, old_idx); cpumask_set_cpu(cpu, cp->free_cpus); } raw_spin_unlock_irqrestore(&cp->lock, flags); }
/* * cpudl_set - update the cpudl max-heap * @cp: the cpudl max-heap context * @cpu: the target cpu * @dl: the new earliest deadline for this cpu * * Notes: assumes cpu_rq(cpu)->lock is locked * * Returns: (void) */ void cpudl_set(struct cpudl *cp, int cpu, u64 dl, int is_valid) { int old_idx, new_cpu; unsigned long flags; WARN_ON(!cpu_present(cpu)); raw_spin_lock_irqsave(&cp->lock, flags); old_idx = cp->cpu_to_idx[cpu]; if (!is_valid) { /* remove item */ if (old_idx == IDX_INVALID) { /* * Nothing to remove if old_idx was invalid. * This could happen if a rq_offline_dl is * called for a CPU without -dl tasks running. */ goto out; } new_cpu = cp->elements[cp->size - 1].cpu; cp->elements[old_idx].dl = cp->elements[cp->size - 1].dl; cp->elements[old_idx].cpu = new_cpu; cp->size--; cp->cpu_to_idx[new_cpu] = old_idx; cp->cpu_to_idx[cpu] = IDX_INVALID; while (old_idx > 0 && dl_time_before( cp->elements[parent(old_idx)].dl, cp->elements[old_idx].dl)) { cpudl_exchange(cp, old_idx, parent(old_idx)); old_idx = parent(old_idx); } cpumask_set_cpu(cpu, cp->free_cpus); cpudl_heapify(cp, old_idx); goto out; } if (old_idx == IDX_INVALID) { cp->size++; cp->elements[cp->size - 1].dl = 0; cp->elements[cp->size - 1].cpu = cpu; cp->cpu_to_idx[cpu] = cp->size - 1; cpudl_change_key(cp, cp->size - 1, dl); cpumask_clear_cpu(cpu, cp->free_cpus); } else { cpudl_change_key(cp, old_idx, dl); } out: raw_spin_unlock_irqrestore(&cp->lock, flags); }
static void cpudl_change_key(struct cpudl *cp, int idx, u64 new_dl) { WARN_ON(idx == IDX_INVALID || !cpu_present(idx)); if (dl_time_before(new_dl, cp->elements[idx].dl)) { cp->elements[idx].dl = new_dl; cpudl_heapify(cp, idx); } else { cp->elements[idx].dl = new_dl; while (idx > 0 && dl_time_before(cp->elements[parent(idx)].dl, cp->elements[idx].dl)) { cpudl_exchange(cp, idx, parent(idx)); idx = parent(idx); } } }
/* * cpudl_set - update the cpudl max-heap * @cp: the cpudl max-heap context * @cpu: the target cpu * @dl: the new earliest deadline for this cpu * * Notes: assumes cpu_rq(cpu)->lock is locked * * Returns: (void) */ void cpudl_set(struct cpudl *cp, int cpu, u64 dl) { int old_idx; unsigned long flags; WARN_ON(!cpu_present(cpu)); raw_spin_lock_irqsave(&cp->lock, flags); old_idx = cp->elements[cpu].idx; if (old_idx == IDX_INVALID) { int new_idx = cp->size++; cp->elements[new_idx].dl = dl; cp->elements[new_idx].cpu = cpu; cp->elements[cpu].idx = new_idx; cpudl_heapify_up(cp, new_idx); cpumask_clear_cpu(cpu, cp->free_cpus); } else { cp->elements[old_idx].dl = dl; cpudl_heapify(cp, old_idx); } raw_spin_unlock_irqrestore(&cp->lock, flags); }