Пример #1
0
long sys_cancel_reserve(pid_t pid) {
  struct cpumask set;
  struct pid *pid_struct;
  struct task_struct *task;
  struct task_struct *tmp;
  int i;
  int cpu_task_count[] = {0, 0, 0, 0};

  printk(KERN_ALERT "[sys_cancel_reserve] PID %u\n", pid);

  // locate the task_struct for the task required
  if (pid == 0) {
    task = current;
  } else {
    rcu_read_lock();
    pid_struct = find_get_pid(pid);
    if (!pid_struct) {
      rcu_read_unlock();
      return -ENODEV;
    }
    task = pid_task(pid_struct, PIDTYPE_PID);
    if (!task) {
      rcu_read_unlock();
      return -ENODEV;
    }
    rcu_read_unlock();
  }

  // make sure the task has a reservation
  if (task->has_reservation == 0) {
    return -EINVAL;
  }

  if (task->has_reservation || task->energymon_node) {
    cancel_reserve_hook(task);  // execute cancel reserve hook
  }

  // cancel timers if they are active
  if (hrtimer_active(&(task->T_timer))) {
    hrtimer_cancel(&(task->T_timer));
  }
  if (hrtimer_active(&(task->C_timer))) {
    hrtimer_cancel(&(task->C_timer));
  }

  // make runnable any task suspended by enforcement
  if (task->put_to_sleep) {
    task->put_to_sleep = 0;
    wake_up_process(task);
  }

  // mark as not having a reservation
  task->has_reservation = 0;

  // set process CPU to 0 because it is never offline
  cpumask_clear(&set);
  cpumask_set_cpu(0, &set);
  if (sched_setaffinity(task->pid, &set)) {
    printk(KERN_INFO "[sys_cancel_reserve] failed to set CPU affinity\n");
    return -EINVAL;
  }

  // find what cpus have tasks with reservations
  rcu_read_lock();
  for_each_process(tmp) {
    if (tmp->has_reservation) {
      cpu_task_count[task_cpu(tmp)] = 1;
    }
  }
  rcu_read_unlock();

  // Bring offline all cpus with no tasks
  for (i = 0; i < NUM_CPUS; i ++) {
    if (cpu_task_count[i] == 0) {
      if (power_cpu(i, 0) != 0) {
        printk(KERN_INFO "[sys_cancel_reserve] failed to turn off cpu %d", i);
        return -EINVAL;
      }
    } else {
      if (power_cpu(i, 1) != 0) {
        printk(KERN_INFO "[sys_cancel_reserve] failed to turn on cpu %d", i);
        return -EINVAL;
      }
    }
  }

  // set the frequency based on sysclock algorithm
  sysclock_set();

  return 0;
}
Пример #2
0
/**
* @brief 设置系统时间
* @param pclock 设置的时间值变量指针
* @return 成功时返回0, 否则返回非零值
*/
int SysClockSet(const struct sysclock *pclock)
{

	sysclock_set(pclock);
	return 0;
}
Пример #3
0
long sys_set_reserve(pid_t pid, struct timespec __user *user_C,
                     struct timespec __user *user_T, int cid) {

  struct cpumask set;
  struct timespec T, C, empty;
  struct pid *pid_struct;
  struct task_struct *task;
  struct task_struct *tmp;
  int i;
  int cpu_task_count[] = {0, 0, 0, 0};

  set_normalized_timespec(&empty, 0, 0);

  // locate the task_struct for the task required
  if (pid == 0) {
    task = current;
  } else {
    rcu_read_lock();
    pid_struct = find_get_pid(pid);
    if (!pid_struct) {
      rcu_read_unlock();
      return -ENODEV;
    }
    task = pid_task(pid_struct, PIDTYPE_PID);
    if (!task) {
      rcu_read_unlock();
      return -ENODEV;
    }
    rcu_read_unlock();
  }

  // get timespec struct info
  if (copy_from_user(&C, user_C, sizeof(struct timespec))) {
    printk(KERN_ALERT "[sys_set_reserve] failed to copy C from user\n");
    return -EFAULT;
  }

  if (copy_from_user(&T, user_T, sizeof(struct timespec))) {
    printk(KERN_ALERT "[sys_set_reserve] failed to copy T from user\n");
    return -EFAULT;
  }

  // check for timespec validity
  if ((timespec_compare(&T, &C) < 0) || !timespec_valid(&T) || !timespec_valid(&C) ||
      (cid >= NUM_CPUS)) {
    printk(KERN_ALERT "[sys_set_reserve] invalid T and C\n");
    return -EINVAL;
  }

  // do a reservation admission check
  cid = admission_check(task, C, T, cid);
  if (cid < 0) {
    return -EBUSY;
  }

  if (set_reserve_hook(task) != 0) {
    return -EFAULT;
  }

  // cancel any old timers for an updated reservation
  if (hrtimer_active(&(task->C_timer))) {
    hrtimer_cancel(&(task->C_timer));
  }
  if (hrtimer_active(&(task->T_timer))) {
    hrtimer_cancel(&(task->T_timer));
  }

  // make runnable any task suspended by enforcement
  if (task->put_to_sleep) {
    task->put_to_sleep = 0;
    wake_up_process(task);
  }

  // copy into task struct ktime values
  task->real_C_time = ktime_set(0, 0);
  task->C_time = ktime_set(C.tv_sec, C.tv_nsec);
  task->T_time = ktime_set(T.tv_sec, T.tv_nsec);

  // find what cpus have tasks on them
  rcu_read_lock();
  for_each_process(tmp) {
    if (tmp->has_reservation) {
      cpu_task_count[task_cpu(tmp)] = 1;
    }
  }
  rcu_read_unlock();

  cpu_task_count[cid] = 1;
  task->reserve_cpu = cid;
  // Bring offline all cpus with no tasks
  for (i = 0; i < NUM_CPUS; i ++) {
    if (cpu_task_count[i] == 0) {
      if (power_cpu(i, 0) != 0) {
        printk(KERN_ALERT"[sys_set_reserve] failed to turn off cpu %d\n", i);
        goto fail;
      }
      printk(KERN_ALERT"[sys_set_reserve] turned OFF CPU %d\n", i);
    } else {
      if (power_cpu(i, 1) != 0) {
        printk(KERN_ALERT"[sys_set_reserve] failed to turn on cpu %d\n", i);
        goto fail;
      }
      printk(KERN_ALERT"[sys_set_reserve] turned ON CPU %d\n", i);
    }
  }

  // set process CPU
  cpumask_clear(&set);
  cpumask_set_cpu(cid, &set);
  if (sched_setaffinity(pid, &set)) {
    printk(KERN_ALERT"[sys_set_reserve] failed to set CPU affinity\n");
    goto fail;
  }

  printk(KERN_ALERT "[sys_set_reserve] PID %d (C = %lld ms / T = %lld ms) CPU %u\n",
         pid, ktime_to_ms(task->C_time), ktime_to_ms(task->T_time), cid);

  // mark as having a reservation
  task->has_reservation = 1;

  // set the frequency based on sysclock algorithm
  sysclock_set();

  return 0;

  fail:
    if (task->has_reservation || task->energymon_node) {
      cancel_reserve_hook(task);
    }
    return -EINVAL;
}