]> git.proxmox.com Git - mirror_ovs.git/blame - lib/netdev-afxdp-pool.c
cirrus: Use FreeBSD 12.2.
[mirror_ovs.git] / lib / netdev-afxdp-pool.c
CommitLineData
0de1b425
WT
1/*
2 * Copyright (c) 2018, 2019 Nicira, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include <config.h>
17
18#include "dp-packet.h"
19#include "netdev-afxdp-pool.h"
20#include "openvswitch/util.h"
21
22/* Note:
23 * umem_elem_push* shouldn't overflow because we always pop
24 * elem first, then push back to the stack.
25 */
26static inline void
27umem_elem_push_n__(struct umem_pool *umemp, int n, void **addrs)
28{
29 void *ptr;
30
31 ovs_assert(umemp->index + n <= umemp->size);
32
33 ptr = &umemp->array[umemp->index];
34 memcpy(ptr, addrs, n * sizeof(void *));
35 umemp->index += n;
36}
37
38void umem_elem_push_n(struct umem_pool *umemp, int n, void **addrs)
39{
40 ovs_spin_lock(&umemp->lock);
41 umem_elem_push_n__(umemp, n, addrs);
42 ovs_spin_unlock(&umemp->lock);
43}
44
45static inline void
46umem_elem_push__(struct umem_pool *umemp, void *addr)
47{
48 ovs_assert(umemp->index + 1 <= umemp->size);
49
50 umemp->array[umemp->index++] = addr;
51}
52
53void
54umem_elem_push(struct umem_pool *umemp, void *addr)
55{
56 ovs_spin_lock(&umemp->lock);
57 umem_elem_push__(umemp, addr);
58 ovs_spin_unlock(&umemp->lock);
59}
60
61static inline int
62umem_elem_pop_n__(struct umem_pool *umemp, int n, void **addrs)
63{
64 void *ptr;
65
66 if (OVS_UNLIKELY(umemp->index - n < 0)) {
67 return -ENOMEM;
68 }
69
70 umemp->index -= n;
71 ptr = &umemp->array[umemp->index];
72 memcpy(addrs, ptr, n * sizeof(void *));
73
74 return 0;
75}
76
77int
78umem_elem_pop_n(struct umem_pool *umemp, int n, void **addrs)
79{
80 int ret;
81
82 ovs_spin_lock(&umemp->lock);
83 ret = umem_elem_pop_n__(umemp, n, addrs);
84 ovs_spin_unlock(&umemp->lock);
85
86 return ret;
87}
88
89static inline void *
90umem_elem_pop__(struct umem_pool *umemp)
91{
92 if (OVS_UNLIKELY(umemp->index - 1 < 0)) {
93 return NULL;
94 }
95
96 return umemp->array[--umemp->index];
97}
98
99void *
100umem_elem_pop(struct umem_pool *umemp)
101{
102 void *ptr;
103
104 ovs_spin_lock(&umemp->lock);
105 ptr = umem_elem_pop__(umemp);
106 ovs_spin_unlock(&umemp->lock);
107
108 return ptr;
109}
110
111static void **
112umem_pool_alloc__(unsigned int size)
113{
114 void **bufs;
115
116 bufs = xmalloc_pagealign(size * sizeof *bufs);
117 memset(bufs, 0, size * sizeof *bufs);
118
119 return bufs;
120}
121
122int
123umem_pool_init(struct umem_pool *umemp, unsigned int size)
124{
125 umemp->array = umem_pool_alloc__(size);
126 if (!umemp->array) {
127 return -ENOMEM;
128 }
129
130 umemp->size = size;
131 umemp->index = 0;
132 ovs_spin_init(&umemp->lock);
133 return 0;
134}
135
136void
137umem_pool_cleanup(struct umem_pool *umemp)
138{
139 free_pagealign(umemp->array);
140 umemp->array = NULL;
141 ovs_spin_destroy(&umemp->lock);
142}
143
144unsigned int
145umem_pool_count(struct umem_pool *umemp)
146{
147 return umemp->index;
148}
149
150/* AF_XDP metadata init/destroy. */
151int
152xpacket_pool_init(struct xpacket_pool *xp, unsigned int size)
153{
154 xp->array = xmalloc_pagealign(size * sizeof *xp->array);
155 xp->size = size;
156
157 memset(xp->array, 0, size * sizeof *xp->array);
158
159 return 0;
160}
161
162void
163xpacket_pool_cleanup(struct xpacket_pool *xp)
164{
165 free_pagealign(xp->array);
166 xp->array = NULL;
167}