提交 dc85e050 编写于 作者: C Chen Hui 提交者: Zheng Zengkai

bpf:programmable: Add cpumask ops collection

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I5KUFB
CVE: NA

--------------------------------

Add cpumask ops collection, such as cpumask_empty,
cpumask_and, cpumask_andnot, cpumask_subset,
cpumask_equal, cpumask_copy.
Signed-off-by: NChen Hui <judy.chenhui@huawei.com>
Signed-off-by: NHui Tang <tanghui20@huawei.com>
上级 1bf0417b
......@@ -2217,5 +2217,28 @@ struct bpf_sched_cpu_capacity {
unsigned long capacity;
unsigned long capacity_orig;
};
struct cpumask_op_args {
unsigned int op_type;
void *arg1;
void *arg2;
void *arg3;
void *arg4;
};
enum cpumask_op_type {
CPUMASK_EMPTY,
CPUMASK_AND,
CPUMASK_ANDNOT,
CPUMASK_SUBSET,
CPUMASK_EQUAL,
CPUMASK_TEST_CPU,
CPUMASK_COPY,
CPUMASK_WEIGHT,
CPUMASK_NEXT,
CPUMASK_NEXT_WRAP,
CPUMASK_NEXT_AND,
CPUMASK_CPULIST_PARSE
};
#endif
#endif
......@@ -3858,6 +3858,48 @@ union bpf_attr {
* Get system cpus returned in *cpus*.
* Return
* 0 on success, or a negative error in case of failure.
*
* int bpf_cpumask_op(struct cpumask_op_args *op, int len)
* Description
* A series of cpumask-related operations. Perform different
* operations base on *op*->type. User also need fill other
* *op* field base on *op*->type. *op*->type is one of them
*
* **CPUMASK_EMPTY**
* *(op->arg1) == 0 returned.
* **CPUMASK_AND**
* *(op->arg1) = *(op->arg2) & *(op->arg3)
* **CPUMASK_ANDNOT**
* *(op->arg1) = *(op->arg2) & ~*(op->arg3)
* **CPUMASK_SUBSET**
* *(op->arg1) & ~*(op->arg2) == 0 returned
* **CPUMASK_EQUAL**
* *(op->arg1) == *(op->arg2) returned
* **CPUMASK_TEST_CPU**
* test for a cpu *(int)(op->arg1) in *(op->arg2)
* returns 1 if *op*->arg1 is set in *op*->arg2, else returns 0
* **CPUMASK_COPY**
* *(op->arg1) = *(op->arg2), return 0 always
* **CPUMASK_WEIGHT**
* count of bits in *(op->arg1)
* **CPUMASK_NEXT**
* get the next cpu in *(struct cpumask *)(op->arg2)
* *(int *)(op->arg1): the cpu prior to the place to search
* **CPUMASK_NEXT_WRAP**
* helper to implement for_each_cpu_wrap
* @op->arg1: the cpu prior to the place to search
* @op->arg2: the cpumask pointer
* @op->arg3: the start point of the iteration
* @op->arg4: assume @op->arg1 crossing @op->arg3 terminates the iteration
* returns >= nr_cpu_ids on completion
* **CPUMASK_NEXT_AND**
* get the next cpu in *(op->arg1) & *(op->arg2)
* **CPUMASK_CPULIST_PARSE**
* extract a cpumask from a user string of ranges.
* (char *)op->arg1 -> (struct cpumask *)(op->arg2)
* 0 on success, or a negative error in case of failure.
* Return
* View above.
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
......@@ -4034,6 +4076,7 @@ union bpf_attr {
FN(sched_cpu_capacity_of), \
FN(init_cpu_topology), \
FN(get_cpumask_info), \
FN(cpumask_op), \
/* */
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
......
......@@ -401,6 +401,90 @@ static const struct bpf_func_proto bpf_sched_cpu_capacity_of_proto = {
.arg3_type = ARG_CONST_SIZE,
};
BPF_CALL_2(bpf_cpumask_op, struct cpumask_op_args *, op, int, len)
{
int ret;
if (len != sizeof(*op) || !op->arg1)
return -EINVAL;
switch (op->op_type) {
case CPUMASK_EMPTY:
return cpumask_empty((const struct cpumask *)op->arg1);
case CPUMASK_AND:
if (!op->arg2 || !op->arg3)
return -EINVAL;
return cpumask_and((struct cpumask *)op->arg1,
(const struct cpumask *)op->arg2,
(const struct cpumask *)op->arg3);
case CPUMASK_ANDNOT:
if (!op->arg2 || !op->arg3)
return -EINVAL;
cpumask_andnot((struct cpumask *)op->arg1,
(const struct cpumask *)op->arg2,
(const struct cpumask *)op->arg3);
break;
case CPUMASK_SUBSET:
if (!op->arg2)
return -EINVAL;
return cpumask_subset((const struct cpumask *)op->arg1,
(const struct cpumask *)op->arg2);
case CPUMASK_EQUAL:
if (!op->arg2)
return -EINVAL;
return cpumask_equal((const struct cpumask *)op->arg1,
(const struct cpumask *)op->arg2);
case CPUMASK_TEST_CPU:
if (!op->arg2)
return -EINVAL;
return cpumask_test_cpu(*(int *)op->arg1, op->arg2);
case CPUMASK_COPY:
if (!op->arg2)
return -EINVAL;
cpumask_copy((struct cpumask *)op->arg1,
(const struct cpumask *)op->arg2);
break;
case CPUMASK_WEIGHT:
return cpumask_weight((const struct cpumask *)op->arg1);
case CPUMASK_NEXT:
if (!op->arg2)
return -EINVAL;
return cpumask_next(*(int *)op->arg1,
(const struct cpumask *)op->arg2);
case CPUMASK_NEXT_WRAP:
if (!op->arg2 || !op->arg3 || !op->arg4)
return -EINVAL;
return cpumask_next_wrap(*(int *)op->arg1,
(const struct cpumask *)op->arg2,
*(int *)op->arg3, *(int *)op->arg4);
case CPUMASK_NEXT_AND:
if (!op->arg2 || !op->arg3)
return -EINVAL;
return cpumask_next_and(*(int *)op->arg1,
(const struct cpumask *)op->arg2,
(const struct cpumask *)op->arg3);
case CPUMASK_CPULIST_PARSE:
if (!op->arg2)
return -EINVAL;
op->arg1 = (void *)strstrip((void *)op->arg1);
ret = cpulist_parse((void *)op->arg1,
(struct cpumask *)op->arg2);
return ret;
default:
return -EINVAL;
}
return 0;
}
static const struct bpf_func_proto bpf_cpumask_op_proto = {
.func = bpf_cpumask_op,
.gpl_only = false,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_MEM,
.arg2_type = ARG_CONST_SIZE,
};
static const struct bpf_func_proto *
bpf_sched_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
......@@ -432,6 +516,8 @@ bpf_sched_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
return &bpf_init_cpu_topology_proto;
case BPF_FUNC_get_cpumask_info:
return &bpf_get_cpumask_info_proto;
case BPF_FUNC_cpumask_op:
return &bpf_cpumask_op_proto;
default:
return bpf_base_func_proto(func_id);
}
......
......@@ -443,6 +443,8 @@ class PrinterHelpers(Printer):
'struct bpf_sched_cpu_capacity',
'struct bpf_cpu_topology',
'struct bpf_cpumask_info',
'struct cpumask',
'struct cpumask_op_args',
]
known_types = {
'...',
......@@ -494,6 +496,8 @@ class PrinterHelpers(Printer):
'struct bpf_sched_cpu_capacity',
'struct bpf_cpu_topology',
'struct bpf_cpumask_info',
'struct cpumask',
'struct cpumask_op_args',
}
mapped_types = {
'u8': '__u8',
......
......@@ -3858,6 +3858,48 @@ union bpf_attr {
* Get system cpus returned in *cpus*.
* Return
* 0 on success, or a negative error in case of failure.
*
* int bpf_cpumask_op(struct cpumask_op_args *op, int len)
* Description
* A series of cpumask-related operations. Perform different
* operations base on *op*->type. User also need fill other
* *op* field base on *op*->type. *op*->type is one of them
*
* **CPUMASK_EMPTY**
* *(op->arg1) == 0 returned.
* **CPUMASK_AND**
* *(op->arg1) = *(op->arg2) & *(op->arg3)
* **CPUMASK_ANDNOT**
* *(op->arg1) = *(op->arg2) & ~*(op->arg3)
* **CPUMASK_SUBSET**
* *(op->arg1) & ~*(op->arg2) == 0 returned
* **CPUMASK_EQUAL**
* *(op->arg1) == *(op->arg2) returned
* **CPUMASK_TEST_CPU**
* test for a cpu *(int)(op->arg1) in *(op->arg2)
* returns 1 if *op*->arg1 is set in *op*->arg2, else returns 0
* **CPUMASK_COPY**
* *(op->arg1) = *(op->arg2), return 0 always
* **CPUMASK_WEIGHT**
* count of bits in *(op->arg1)
* **CPUMASK_NEXT**
* get the next cpu in *(struct cpumask *)(op->arg2)
* *(int *)(op->arg1): the cpu prior to the place to search
* **CPUMASK_NEXT_WRAP**
* helper to implement for_each_cpu_wrap
* @op->arg1: the cpu prior to the place to search
* @op->arg2: the cpumask pointer
* @op->arg3: the start point of the iteration
* @op->arg4: assume @op->arg1 crossing @op->arg3 terminates the iteration
* returns >= nr_cpu_ids on completion
* **CPUMASK_NEXT_AND**
* get the next cpu in *(op->arg1) & *(op->arg2)
* **CPUMASK_CPULIST_PARSE**
* extract a cpumask from a user string of ranges.
* (char *)op->arg1 -> (struct cpumask *)(op->arg2)
* 0 on success, or a negative error in case of failure.
* Return
* View above.
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
......@@ -4034,6 +4076,7 @@ union bpf_attr {
FN(sched_cpu_capacity_of), \
FN(init_cpu_topology), \
FN(get_cpumask_info), \
FN(cpumask_op), \
/* */
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册