xref: /freebsd-14.2/sys/dev/netmap/netmap_mbq.c (revision 997b054c)
1f9790aebSLuigi Rizzo /*
217885a7bSLuigi Rizzo  * Copyright (C) 2013-2014 Vincenzo Maffione. All rights reserved.
3f9790aebSLuigi Rizzo  *
4f9790aebSLuigi Rizzo  * Redistribution and use in source and binary forms, with or without
5f9790aebSLuigi Rizzo  * modification, are permitted provided that the following conditions
6f9790aebSLuigi Rizzo  * are met:
7f9790aebSLuigi Rizzo  *   1. Redistributions of source code must retain the above copyright
8f9790aebSLuigi Rizzo  *      notice, this list of conditions and the following disclaimer.
9f9790aebSLuigi Rizzo  *   2. Redistributions in binary form must reproduce the above copyright
10f9790aebSLuigi Rizzo  *      notice, this list of conditions and the following disclaimer in the
11f9790aebSLuigi Rizzo  *      documentation and/or other materials provided with the distribution.
12f9790aebSLuigi Rizzo  *
13f9790aebSLuigi Rizzo  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14f9790aebSLuigi Rizzo  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15f9790aebSLuigi Rizzo  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16f9790aebSLuigi Rizzo  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17f9790aebSLuigi Rizzo  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18f9790aebSLuigi Rizzo  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19f9790aebSLuigi Rizzo  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20f9790aebSLuigi Rizzo  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21f9790aebSLuigi Rizzo  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22f9790aebSLuigi Rizzo  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23f9790aebSLuigi Rizzo  * SUCH DAMAGE.
24f9790aebSLuigi Rizzo  */
25f9790aebSLuigi Rizzo 
26f9790aebSLuigi Rizzo /*
27f9790aebSLuigi Rizzo  * $FreeBSD$
28f9790aebSLuigi Rizzo  */
29f9790aebSLuigi Rizzo 
30f9790aebSLuigi Rizzo 
31f9790aebSLuigi Rizzo #ifdef linux
32f9790aebSLuigi Rizzo #include "bsd_glue.h"
33f9790aebSLuigi Rizzo #else   /* __FreeBSD__ */
34f9790aebSLuigi Rizzo #include <sys/param.h>
35f9790aebSLuigi Rizzo #include <sys/lock.h>
36f9790aebSLuigi Rizzo #include <sys/mutex.h>
37f9790aebSLuigi Rizzo #include <sys/systm.h>
38f9790aebSLuigi Rizzo #include <sys/mbuf.h>
39f9790aebSLuigi Rizzo #endif  /* __FreeBSD__ */
40f9790aebSLuigi Rizzo 
41f9790aebSLuigi Rizzo #include "netmap_mbq.h"
42f9790aebSLuigi Rizzo 
43f9790aebSLuigi Rizzo 
44f9790aebSLuigi Rizzo static inline void __mbq_init(struct mbq *q)
45f9790aebSLuigi Rizzo {
46f9790aebSLuigi Rizzo     q->head = q->tail = NULL;
47f9790aebSLuigi Rizzo     q->count = 0;
48f9790aebSLuigi Rizzo }
49f9790aebSLuigi Rizzo 
5017885a7bSLuigi Rizzo 
51f9790aebSLuigi Rizzo void mbq_safe_init(struct mbq *q)
52f9790aebSLuigi Rizzo {
53f9790aebSLuigi Rizzo     mtx_init(&q->lock, "mbq", NULL, MTX_SPIN);
54f9790aebSLuigi Rizzo     __mbq_init(q);
55f9790aebSLuigi Rizzo }
56f9790aebSLuigi Rizzo 
5717885a7bSLuigi Rizzo 
58f9790aebSLuigi Rizzo void mbq_init(struct mbq *q)
59f9790aebSLuigi Rizzo {
60f9790aebSLuigi Rizzo     __mbq_init(q);
61f9790aebSLuigi Rizzo }
62f9790aebSLuigi Rizzo 
6317885a7bSLuigi Rizzo 
64f9790aebSLuigi Rizzo static inline void __mbq_enqueue(struct mbq *q, struct mbuf *m)
65f9790aebSLuigi Rizzo {
66f9790aebSLuigi Rizzo     m->m_nextpkt = NULL;
67f9790aebSLuigi Rizzo     if (q->tail) {
68f9790aebSLuigi Rizzo         q->tail->m_nextpkt = m;
69f9790aebSLuigi Rizzo         q->tail = m;
70f9790aebSLuigi Rizzo     } else {
71f9790aebSLuigi Rizzo         q->head = q->tail = m;
72f9790aebSLuigi Rizzo     }
73f9790aebSLuigi Rizzo     q->count++;
74f9790aebSLuigi Rizzo }
75f9790aebSLuigi Rizzo 
7617885a7bSLuigi Rizzo 
77f9790aebSLuigi Rizzo void mbq_safe_enqueue(struct mbq *q, struct mbuf *m)
78f9790aebSLuigi Rizzo {
79*997b054cSLuigi Rizzo     mbq_lock(q);
80f9790aebSLuigi Rizzo     __mbq_enqueue(q, m);
81*997b054cSLuigi Rizzo     mbq_unlock(q);
82f9790aebSLuigi Rizzo }
83f9790aebSLuigi Rizzo 
8417885a7bSLuigi Rizzo 
85f9790aebSLuigi Rizzo void mbq_enqueue(struct mbq *q, struct mbuf *m)
86f9790aebSLuigi Rizzo {
87f9790aebSLuigi Rizzo     __mbq_enqueue(q, m);
88f9790aebSLuigi Rizzo }
89f9790aebSLuigi Rizzo 
9017885a7bSLuigi Rizzo 
91f9790aebSLuigi Rizzo static inline struct mbuf *__mbq_dequeue(struct mbq *q)
92f9790aebSLuigi Rizzo {
93f9790aebSLuigi Rizzo     struct mbuf *ret = NULL;
94f9790aebSLuigi Rizzo 
95f9790aebSLuigi Rizzo     if (q->head) {
96f9790aebSLuigi Rizzo         ret = q->head;
97f9790aebSLuigi Rizzo         q->head = ret->m_nextpkt;
98f9790aebSLuigi Rizzo         if (q->head == NULL) {
99f9790aebSLuigi Rizzo             q->tail = NULL;
100f9790aebSLuigi Rizzo         }
101f9790aebSLuigi Rizzo         q->count--;
102f9790aebSLuigi Rizzo         ret->m_nextpkt = NULL;
103f9790aebSLuigi Rizzo     }
104f9790aebSLuigi Rizzo 
105f9790aebSLuigi Rizzo     return ret;
106f9790aebSLuigi Rizzo }
107f9790aebSLuigi Rizzo 
10817885a7bSLuigi Rizzo 
109f9790aebSLuigi Rizzo struct mbuf *mbq_safe_dequeue(struct mbq *q)
110f9790aebSLuigi Rizzo {
111f9790aebSLuigi Rizzo     struct mbuf *ret;
112f9790aebSLuigi Rizzo 
113*997b054cSLuigi Rizzo     mbq_lock(q);
114f9790aebSLuigi Rizzo     ret =  __mbq_dequeue(q);
115*997b054cSLuigi Rizzo     mbq_unlock(q);
116f9790aebSLuigi Rizzo 
117f9790aebSLuigi Rizzo     return ret;
118f9790aebSLuigi Rizzo }
119f9790aebSLuigi Rizzo 
12017885a7bSLuigi Rizzo 
121f9790aebSLuigi Rizzo struct mbuf *mbq_dequeue(struct mbq *q)
122f9790aebSLuigi Rizzo {
123f9790aebSLuigi Rizzo     return __mbq_dequeue(q);
124f9790aebSLuigi Rizzo }
125f9790aebSLuigi Rizzo 
12617885a7bSLuigi Rizzo 
127f9790aebSLuigi Rizzo /* XXX seems pointless to have a generic purge */
128f9790aebSLuigi Rizzo static void __mbq_purge(struct mbq *q, int safe)
129f9790aebSLuigi Rizzo {
130f9790aebSLuigi Rizzo     struct mbuf *m;
131f9790aebSLuigi Rizzo 
132f9790aebSLuigi Rizzo     for (;;) {
133f9790aebSLuigi Rizzo         m = safe ? mbq_safe_dequeue(q) : mbq_dequeue(q);
134f9790aebSLuigi Rizzo         if (m) {
135f9790aebSLuigi Rizzo             m_freem(m);
136f9790aebSLuigi Rizzo         } else {
137f9790aebSLuigi Rizzo             break;
138f9790aebSLuigi Rizzo         }
139f9790aebSLuigi Rizzo     }
140f9790aebSLuigi Rizzo }
141f9790aebSLuigi Rizzo 
14217885a7bSLuigi Rizzo 
143f9790aebSLuigi Rizzo void mbq_purge(struct mbq *q)
144f9790aebSLuigi Rizzo {
145f9790aebSLuigi Rizzo     __mbq_purge(q, 0);
146f9790aebSLuigi Rizzo }
147f9790aebSLuigi Rizzo 
14817885a7bSLuigi Rizzo 
149f9790aebSLuigi Rizzo void mbq_safe_purge(struct mbq *q)
150f9790aebSLuigi Rizzo {
151f9790aebSLuigi Rizzo     __mbq_purge(q, 1);
152f9790aebSLuigi Rizzo }
153f9790aebSLuigi Rizzo 
15417885a7bSLuigi Rizzo 
155f9790aebSLuigi Rizzo void mbq_safe_destroy(struct mbq *q)
156f9790aebSLuigi Rizzo {
157f9790aebSLuigi Rizzo     mtx_destroy(&q->lock);
158f9790aebSLuigi Rizzo }
159f9790aebSLuigi Rizzo 
160f9790aebSLuigi Rizzo 
161f9790aebSLuigi Rizzo void mbq_destroy(struct mbq *q)
162f9790aebSLuigi Rizzo {
163f9790aebSLuigi Rizzo }
164