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