Commit bbc73f27 authored by Philippe Gerum's avatar Philippe Gerum
Browse files

evl/control: add query for CPU state



A practical LART is to know beforehand when some out-of-band work is
about to run on a non-isolated CPU, so that the application may warn
the user about the potentially higher latency figures induced by
higher rates of cache and TLB misses which may be caused by heavy
in-band load running on the same core.

The control device now accepts the
[oob_]ioctl(EVL_CTLIOC_GET_CPUSTATE) request, which queries the
current state of a CPU:

- EVL_CPU_ISOL if it does not belong to housekeeping set of the
  in-band kernel, i.e. not mentioned in isolcpus= for the scheduling
  domain.

- EVL_CPU_OOB if it is part of the out-of-band set EVL manages.

- EVL_CPU_OFFLINE if currently off.

Signed-off-by: Philippe Gerum's avatarPhilippe Gerum <rpm@xenomai.org>
parent 8b313f9f
......@@ -10,7 +10,7 @@
#include <linux/types.h>
#include <uapi/evl/sched.h>
#define EVL_ABI_LEVEL 7
#define EVL_ABI_LEVEL 8
#define EVL_CONTROL_DEV "/dev/evl/control"
......@@ -20,9 +20,15 @@ struct evl_core_info {
__u64 shm_size;
};
struct evl_cpu_state {
__u32 cpu;
__u32 *state;
};
#define EVL_CONTROL_IOCBASE 'C'
#define EVL_CTLIOC_GET_COREINFO _IOR(EVL_CONTROL_IOCBASE, 0, struct evl_core_info)
#define EVL_CTLIOC_SCHEDCTL _IOWR(EVL_CONTROL_IOCBASE, 1, struct evl_sched_ctlreq)
#define EVL_CTLIOC_GET_CPUSTATE _IOR(EVL_CONTROL_IOCBASE, 2, struct evl_cpu_state)
#endif /* !_EVL_UAPI_CONTROL_H */
......@@ -10,6 +10,10 @@
#include <linux/types.h>
#define EVL_CPU_OOB (1 << 0)
#define EVL_CPU_ISOL (1 << 1)
#define EVL_CPU_OFFLINE (1 << 2)
#define SCHED_WEAK 43
#define sched_rr_quantum sched_u.rr.__sched_rr_quantum
......
......@@ -6,6 +6,7 @@
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/sched/isolation.h>
#include <evl/memory.h>
#include <evl/thread.h>
#include <evl/factory.h>
......@@ -200,10 +201,32 @@ static int do_sched_control(struct evl_sched_ctlreq *ctl)
return ret;
}
static int do_cpu_state(struct evl_cpu_state *cpst)
{
int cpu = cpst->cpu;
__u32 state = 0;
if (cpst->cpu >= num_possible_cpus() || !cpu_present(cpu))
return -EINVAL;
if (!cpu_online(cpu))
state |= EVL_CPU_OFFLINE;
if (is_evl_cpu(cpu))
state |= EVL_CPU_OOB;
if (!housekeeping_cpu(cpu, HK_FLAG_DOMAIN))
state |= EVL_CPU_ISOL;
return raw_copy_to_user(cpst->state, &state, sizeof(state)) ?
-EFAULT : 0;
}
static long control_common_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct evl_sched_ctlreq ctl, __user *u_ctl;
struct evl_cpu_state cpst, __user *u_cpst;
long ret;
switch (cmd) {
......@@ -214,6 +237,13 @@ static long control_common_ioctl(struct file *filp, unsigned int cmd,
return -EFAULT;
ret = do_sched_control(&ctl);
break;
case EVL_CTLIOC_GET_CPUSTATE:
u_cpst = (typeof(u_cpst))arg;
ret = raw_copy_from_user(&cpst, u_cpst, sizeof(cpst));
if (ret)
return -EFAULT;
ret = do_cpu_state(&cpst);
break;
default:
ret = -ENOTTY;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment