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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/netronome/nfp/bpf/cmsg.c
Extension
.c
Size
12047 bytes
Lines
482
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 (op == NFP_CCM_TYPE_BPF_MAP_GETNEXT) {
			if (i + 1 == count)
				break;

			memcpy(out_key,
			       nfp_bpf_ctrl_reply_key(bpf, reply, i + 1),
			       map->key_size);
		}

		n_entries = 0;
		goto exit_unlock;
	}
	goto exit_unlock;

exit_block:
	nfp_map->cache_blockers++;
exit_invalidate:
	dev_consume_skb_any(nfp_map->cache);
	nfp_map->cache = NULL;
exit_unlock:
	spin_unlock(&nfp_map->cache_lock);
	return n_entries;
}

static void
nfp_bpf_ctrl_op_cache_put(struct nfp_bpf_map *nfp_map, enum nfp_ccm_type op,
			  struct sk_buff *skb, u32 cache_gen)
{
	bool blocker, filler;

	blocker = nfp_bpf_ctrl_op_cache_invalidate(op);
	filler = nfp_bpf_ctrl_op_cache_fill(op);
	if (blocker || filler) {
		u64 to = 0;

		if (filler)
			to = ktime_get_ns() + NFP_BPF_MAP_CACHE_TIME_NS;

		spin_lock(&nfp_map->cache_lock);
		if (blocker) {
			nfp_map->cache_blockers--;
			nfp_map->cache_gen++;
		}
		if (filler && !nfp_map->cache_blockers &&
		    nfp_map->cache_gen == cache_gen) {
			nfp_map->cache_to = to;
			swap(nfp_map->cache, skb);
		}
		spin_unlock(&nfp_map->cache_lock);
	}

	dev_consume_skb_any(skb);
}

static int
nfp_bpf_ctrl_entry_op(struct bpf_offloaded_map *offmap, enum nfp_ccm_type op,
		      u8 *key, u8 *value, u64 flags, u8 *out_key, u8 *out_value)
{
	struct nfp_bpf_map *nfp_map = offmap->dev_priv;
	unsigned int n_entries, reply_entries, count;
	struct nfp_app_bpf *bpf = nfp_map->bpf;
	struct bpf_map *map = &offmap->map;
	struct cmsg_reply_map_op *reply;
	struct cmsg_req_map_op *req;
	struct sk_buff *skb;
	u32 cache_gen;
	int err;

	/* FW messages have no space for more than 32 bits of flags */
	if (flags >> 32)
		return -EOPNOTSUPP;

	/* Handle op cache */
	n_entries = nfp_bpf_ctrl_op_cache_get(nfp_map, op, key, out_key,
					      out_value, &cache_gen);
	if (!n_entries)
		return 0;

	skb = nfp_bpf_cmsg_map_req_alloc(bpf, 1);
	if (!skb) {
		err = -ENOMEM;
		goto err_cache_put;
	}

	req = (void *)skb->data;
	req->tid = cpu_to_be32(nfp_map->tid);
	req->count = cpu_to_be32(n_entries);
	req->flags = cpu_to_be32(flags);

	/* Copy inputs */

Annotation

Implementation Notes