Commit 9de44ea0 authored by Hui Tang's avatar Hui Tang
Browse files

bpf:programmable: Add nodemask operation collection

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I9GZAQ


CVE: NA

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

Introduce the helper to process a series nodemask operations,
such as 'nodes_empty', 'node_isset' etc.

Signed-off-by: default avatarHui Tang <tanghui20@huawei.com>
parent 7743b2f7
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -2378,6 +2378,28 @@ enum cpumask_op_type {
	CPUMASK_CPULIST_PARSE
};

enum nodemask_op_type {
	NODEMASK_EMPTY,
	NODEMASK_NODE_ISSET,
	NODEMASK_NODES_CLEAR,
	NODEMASK_NODE_SET,
	NODEMASK_NODE_CLEAR,
	NODEMASK_NODELIST_PARSE,
	NODEMASK_TO_CPUMASK,
	NODEMASK_NODES_ANDNOT,
	NODEMASK_NODES_AND,
	NODEMASK_NODES_OR,
	NODEMASK_WEIGHT,
	NODEMASK_ONLINE
};

struct nodemask_op_args {
	enum nodemask_op_type op_type;
	void *arg1;
	void *arg2;
	void *arg3;
};

struct sched_migrate_ctx {
	struct task_struct *task;
	struct cpumask *select_idle_mask;
+29 −0
Original line number Diff line number Diff line
@@ -3874,6 +3874,34 @@ union bpf_attr {
 *		check src_cpu whether share cache with dst_cpu.
 *	Return
 *		yes 1, no 0.
 *
 * int bpf_nodemask_op(struct nodemask_op_args *op, int len)
 *	Description
 *		A series of nodemask-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
 *
 *		**NODEMASK_EMPTY**
 *			nodes_empty(op->arg1) returned.
 *		**NODEMASK_NODE_ISSET**
 *			node_isset(op->arg1, op->arg2) returned
 *		**NODEMASK_NODES_CLEAR**
 *			0 returned
 *		**NODEMASK_NODE_CLEAR**
 *			unset op->arg1 from op->arg2, 0 returned
 *		**NODEMASK_NODE_SET**
 *			set op->arg1 to op->arg2, 0 returned
 *		**NODEMASK_WEIGHT**
 *			nodes_weight(op->arg1) returned
 *		**NODEMASK_NODELIST_PARSE**
 *			str *op->arg1* to nodemask_t *op->arg2*,
 *			0 on success, or a negative error in case of failure.
 *		**NODEMASK_TO_CPUMASK**
 *			nodemask_t *arg1* to cpumask_t *op->arg2*, 0 returned.
 *		**NODEMASK_ONLINE**
 *			set online nodes to nodemask_t *op->arg1*, 0 returned.
 *	Return
 *		View above.
 */
#define __BPF_FUNC_MAPPER(FN)		\
	FN(unspec),			\
@@ -4046,6 +4074,7 @@ union bpf_attr {
	FN(sched_entity_to_tg),		\
	FN(cpumask_op),			\
	FN(cpus_share_cache),		\
	FN(nodemask_op),		\
	/* */

/* integer value in 'imm' field of BPF_CALL instruction selects which helper
+71 −0
Original line number Diff line number Diff line
@@ -260,6 +260,75 @@ static const struct bpf_func_proto bpf_cpumask_op_proto = {
	.arg2_type	= ARG_CONST_SIZE,
};

BPF_CALL_2(bpf_nodemask_op, struct nodemask_op_args *, op, int, len)
{
	struct cpumask *cpumask;
	nodemask_t mask;
	int nid;

	if (len != sizeof(*op) || !op->arg1)
		return -EINVAL;

	switch (op->op_type) {
	case NODEMASK_EMPTY:
		mask = *(nodemask_t *)op->arg1;
		return nodes_empty(mask);
	case NODEMASK_NODE_ISSET:
		mask = *(nodemask_t *)op->arg2;
		return node_isset(*(int *)op->arg1, mask);
	case NODEMASK_NODES_CLEAR:
		__nodes_clear((nodemask_t *)op->arg1, MAX_NUMNODES);
		break;
	case NODEMASK_NODE_CLEAR:
		__node_clear(*(int *)op->arg1, (nodemask_t *)op->arg2);
		break;
	case NODEMASK_NODE_SET:
		__node_set(*(int *)op->arg1, (nodemask_t *)op->arg2);
		break;
	case NODEMASK_NODES_AND:
		__nodes_and((nodemask_t *)op->arg1, (nodemask_t *)op->arg2,
			    (nodemask_t *)op->arg3, MAX_NUMNODES);
		break;
	case NODEMASK_NODES_ANDNOT:
		__nodes_andnot((nodemask_t *)op->arg1, (nodemask_t *)op->arg2,
			       (nodemask_t *)op->arg3, MAX_NUMNODES);
		break;
	case NODEMASK_NODES_OR:
		__nodes_or((nodemask_t *)op->arg1, (nodemask_t *)op->arg2,
			   (nodemask_t *)op->arg3, MAX_NUMNODES);
		break;
	case NODEMASK_WEIGHT:
		mask = *(nodemask_t *)op->arg1;
		return nodes_weight(mask);
	case NODEMASK_NODELIST_PARSE:
		return __nodelist_parse((const char *)op->arg1,
					(nodemask_t *)op->arg2, MAX_NUMNODES);
	case NODEMASK_TO_CPUMASK:
		mask = *(nodemask_t *)op->arg1;
		cpumask = (struct cpumask *)op->arg2;
		cpumask_clear(cpumask);
		for_each_node_mask(nid, mask) {
			cpumask_or(cpumask, cpumask, cpumask_of_node(nid));
		}
		break;
	case NODEMASK_ONLINE:
		*(nodemask_t *)op->arg1 = node_online_map;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static const struct bpf_func_proto bpf_nodemask_op_proto = {
	.func		= bpf_nodemask_op,
	.gpl_only	= false,
	.ret_type	= RET_INTEGER,
	.arg1_type	= ARG_PTR_TO_MEM,
	.arg2_type	= ARG_CONST_SIZE,
};

BPF_CALL_2(bpf_cpus_share_cache, int, src_cpu, int, dst_cpu)
{
	if ((unsigned int)src_cpu >= nr_cpu_ids ||
@@ -299,6 +368,8 @@ bpf_sched_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
		return &bpf_cpumask_op_proto;
	case BPF_FUNC_cpus_share_cache:
		return &bpf_cpus_share_cache_proto;
	case BPF_FUNC_nodemask_op:
		return &bpf_nodemask_op_proto;
	default:
		return bpf_base_func_proto(func_id);
	}
+2 −0
Original line number Diff line number Diff line
@@ -445,6 +445,7 @@ class PrinterHelpers(Printer):
            'struct sched_migrate_ctx',
            'struct sched_affine_ctx',
            'struct sched_migrate_node',
            'struct nodemask_op_args',
    ]
    known_types = {
            '...',
@@ -498,6 +499,7 @@ class PrinterHelpers(Printer):
            'struct sched_migrate_ctx',
            'struct sched_affine_ctx',
            'struct sched_migrate_node',
            'struct nodemask_op_args',
    }
    mapped_types = {
            'u8': '__u8',
+29 −0
Original line number Diff line number Diff line
@@ -3874,6 +3874,34 @@ union bpf_attr {
 *		check src_cpu whether share cache with dst_cpu.
 *	Return
 *		true yes, false no.
 *
 * int bpf_nodemask_op(struct nodemask_op_args *op, int len)
 *	Description
 *		A series of nodemask-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
 *
 *		**NODEMASK_EMPTY**
 *			nodes_empty(op->arg1) returned.
 *		**NODEMASK_NODE_ISSET**
 *			node_isset(op->arg1, op->arg2) returned
 *		**NODEMASK_NODES_CLEAR**
 *			0 returned
 *		**NODEMASK_NODE_CLEAR**
 *			unset op->arg1 from op->arg2, 0 returned
 *		**NODEMASK_NODE_SET**
 *			set op->arg1 to op->arg2, 0 returned
 *		**NODEMASK_WEIGHT**
 *			nodes_weight(op->arg1) returned
 *		**NODEMASK_NODELIST_PARSE**
 *			str *op->arg1* to nodemask_t *op->arg2*,
 *			0 on success, or a negative error in case of failure.
 *		**NODEMASK_TO_CPUMASK**
 *			nodemask_t *arg1* to cpumask_t *op->arg2*, 0 returned.
 *		**NODEMASK_ONLINE**
 *			set online nodes to nodemask_t *op->arg1*, 0 returned.
 *	Return
 *		View above.
 */
#define __BPF_FUNC_MAPPER(FN)		\
	FN(unspec),			\
@@ -4046,6 +4074,7 @@ union bpf_attr {
	FN(sched_entity_to_tg),		\
	FN(cpumask_op),			\
	FN(cpus_share_cache),		\
	FN(nodemask_op),		\
	/* */

/* integer value in 'imm' field of BPF_CALL instruction selects which helper
Loading