drivers/net/ethernet/netronome/nfp/bpf/offload.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/netronome/nfp/bpf/offload.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/netronome/nfp/bpf/offload.c
Extension
.c
Size
15195 bytes
Lines
619
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (--nfp_prog->map_records[i]->count) {
			nfp_prog->map_records[i] = NULL;
			continue;
		}

		WARN_ON(rhashtable_remove_fast(&bpf->maps_neutral,
					       &nfp_prog->map_records[i]->l,
					       nfp_bpf_maps_neutral_params));
		freed = true;
	}

	if (freed) {
		synchronize_rcu();

		for (i = 0; i < nfp_prog->map_records_cnt; i++)
			if (nfp_prog->map_records[i]) {
				bpf_map_put(nfp_prog->map_records[i]->ptr);
				kfree(nfp_prog->map_records[i]);
			}
	}

	kfree(nfp_prog->map_records);
	nfp_prog->map_records = NULL;
	nfp_prog->map_records_cnt = 0;
}

static int
nfp_map_ptrs_record(struct nfp_app_bpf *bpf, struct nfp_prog *nfp_prog,
		    struct bpf_prog *prog)
{
	int i, cnt, err = 0;

	mutex_lock(&prog->aux->used_maps_mutex);

	/* Quickly count the maps we will have to remember */
	cnt = 0;
	for (i = 0; i < prog->aux->used_map_cnt; i++)
		if (bpf_map_offload_neutral(prog->aux->used_maps[i]))
			cnt++;
	if (!cnt)
		goto out;

	nfp_prog->map_records = kmalloc_objs(nfp_prog->map_records[0], cnt);
	if (!nfp_prog->map_records) {
		err = -ENOMEM;
		goto out;
	}

	for (i = 0; i < prog->aux->used_map_cnt; i++)
		if (bpf_map_offload_neutral(prog->aux->used_maps[i])) {
			err = nfp_map_ptr_record(bpf, nfp_prog,
						 prog->aux->used_maps[i]);
			if (err) {
				nfp_map_ptrs_forget(bpf, nfp_prog);
				goto out;
			}
		}
	WARN_ON(cnt != nfp_prog->map_records_cnt);

out:
	mutex_unlock(&prog->aux->used_maps_mutex);
	return err;
}

static int
nfp_prog_prepare(struct nfp_prog *nfp_prog, const struct bpf_insn *prog,
		 unsigned int cnt)
{
	struct nfp_insn_meta *meta;
	unsigned int i;

	for (i = 0; i < cnt; i++) {
		meta = kzalloc_obj(*meta);
		if (!meta)
			return -ENOMEM;

		meta->insn = prog[i];
		meta->n = i;
		if (is_mbpf_alu(meta)) {
			meta->umin_src = U64_MAX;
			meta->umin_dst = U64_MAX;
		}

		list_add_tail(&meta->l, &nfp_prog->insns);
	}
	nfp_prog->n_insns = cnt;

	nfp_bpf_jit_prepare(nfp_prog);

	return 0;

Annotation

Implementation Notes