aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-generic/odp_packet_vector.c
blob: b3edbf84b481de26f2ead37015052cd1283e701c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* Copyright (c) 2020-2021, Nokia
 * All rights reserved.
 *
 * SPDX-License-Identifier:     BSD-3-Clause
 */

#include <odp/api/align.h>
#include <odp/api/hints.h>
#include <odp/api/packet.h>
#include <odp/api/pool.h>
#include <odp/api/plat/packet_vector_inlines.h>
#include <odp/api/plat/strong_types.h>

#include <odp_debug_internal.h>
#include <odp_event_vector_internal.h>
#include <odp_pool_internal.h>

#include <inttypes.h>
#include <stdint.h>

#include <odp/visibility_begin.h>

/* Packet vector header field offsets for inline functions */
const _odp_event_vector_inline_offset_t _odp_event_vector_inline ODP_ALIGNED_CACHE = {
	.packet    = offsetof(odp_event_vector_hdr_t, packet),
	.pool      = offsetof(odp_event_vector_hdr_t, event_hdr.pool),
	.size      = offsetof(odp_event_vector_hdr_t, size),
	.uarea_addr = offsetof(odp_event_vector_hdr_t, uarea_addr),
	.flags     = offsetof(odp_event_vector_hdr_t, flags)
};

#include <odp/visibility_end.h>

static inline odp_event_vector_hdr_t *event_vector_hdr_from_event(odp_event_t event)
{
	return (odp_event_vector_hdr_t *)(uintptr_t)event;
}

odp_packet_vector_t odp_packet_vector_alloc(odp_pool_t pool_hdl)
{
	odp_event_t event;
	pool_t *pool;

	ODP_ASSERT(pool_hdl != ODP_POOL_INVALID);

	pool = _odp_pool_entry(pool_hdl);

	ODP_ASSERT(pool->type == ODP_POOL_VECTOR);

	event = _odp_event_alloc(pool);
	if (odp_unlikely(event == ODP_EVENT_INVALID))
		return ODP_PACKET_VECTOR_INVALID;

	ODP_ASSERT(event_vector_hdr_from_event(event)->size == 0);

	return odp_packet_vector_from_event(event);
}

void odp_packet_vector_free(odp_packet_vector_t pktv)
{
	odp_event_vector_hdr_t *pktv_hdr = _odp_packet_vector_hdr(pktv);

	pktv_hdr->size = 0;
	pktv_hdr->flags.all_flags = 0;

	_odp_event_free(odp_packet_vector_to_event(pktv));
}

int odp_packet_vector_valid(odp_packet_vector_t pktv)
{
	odp_event_vector_hdr_t *pktv_hdr;
	odp_event_t ev;
	pool_t *pool;
	uint32_t i;

	if (odp_unlikely(pktv == ODP_PACKET_VECTOR_INVALID))
		return 0;

	ev = odp_packet_vector_to_event(pktv);

	if (_odp_event_is_valid(ev) == 0)
		return 0;

	if (odp_event_type(ev) != ODP_EVENT_PACKET_VECTOR)
		return 0;

	pktv_hdr = _odp_packet_vector_hdr(pktv);
	pool = _odp_pool_entry(pktv_hdr->event_hdr.pool);

	if (odp_unlikely(pktv_hdr->size > pool->params.vector.max_size))
		return 0;

	for (i = 0; i < pktv_hdr->size; i++) {
		if (pktv_hdr->packet[i] == ODP_PACKET_INVALID)
			return 0;
	}

	return 1;
}

void odp_packet_vector_print(odp_packet_vector_t pktv)
{
	int max_len = 4096;
	char str[max_len];
	int len = 0;
	int n = max_len - 1;
	uint32_t i;
	odp_event_vector_hdr_t *pktv_hdr = _odp_packet_vector_hdr(pktv);

	len += snprintf(&str[len], n - len, "Packet Vector\n");
	len += snprintf(&str[len], n - len,
			"  handle %p\n", (void *)pktv);
	len += snprintf(&str[len], n - len,
			"  size   %" PRIu32 "\n", pktv_hdr->size);

	for (i = 0; i < pktv_hdr->size; i++) {
		odp_packet_t pkt = pktv_hdr->packet[i];
		char seg_str[max_len];
		int str_len;

		str_len = snprintf(seg_str, max_len,
				   "    packet     %p  len %" PRIu32 "\n",
				   (void *)pkt, odp_packet_len(pkt));

		/* Prevent print buffer overflow */
		if (n - len - str_len < 10) {
			len += snprintf(&str[len], n - len, "    ...\n");
			break;
		}
		len += snprintf(&str[len], n - len, "%s", seg_str);
	}

	ODP_PRINT("%s\n", str);
}

uint64_t odp_packet_vector_to_u64(odp_packet_vector_t pktv)
{
	return _odp_pri(pktv);
}