Deleted Added
full compact
ng_base.c (149881) ng_base.c (151238)
1/*
2 * ng_base.c
3 */
4
5/*-
6 * Copyright (c) 1996-1999 Whistle Communications, Inc.
7 * All rights reserved.
8 *

--- 24 unchanged lines hidden (view full) ---

33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
36 * OF SUCH DAMAGE.
37 *
38 * Authors: Julian Elischer <julian@freebsd.org>
39 * Archie Cobbs <archie@freebsd.org>
40 *
1/*
2 * ng_base.c
3 */
4
5/*-
6 * Copyright (c) 1996-1999 Whistle Communications, Inc.
7 * All rights reserved.
8 *

--- 24 unchanged lines hidden (view full) ---

33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
36 * OF SUCH DAMAGE.
37 *
38 * Authors: Julian Elischer <julian@freebsd.org>
39 * Archie Cobbs <archie@freebsd.org>
40 *
41 * $FreeBSD: head/sys/netgraph/ng_base.c 149881 2005-09-08 14:32:19Z glebius $
41 * $FreeBSD: head/sys/netgraph/ng_base.c 151238 2005-10-11 13:48:38Z glebius $
42 * $Whistle: ng_base.c,v 1.39 1999/01/28 23:54:53 julian Exp $
43 */
44
45/*
46 * This file implements the base netgraph code.
47 */
48
49#include <sys/param.h>

--- 133 unchanged lines hidden (view full) ---

183
184/* Internal functions */
185static int ng_add_hook(node_p node, const char *name, hook_p * hookp);
186static int ng_generic_msg(node_p here, item_p item, hook_p lasthook);
187static ng_ID_t ng_decodeidname(const char *name);
188static int ngb_mod_event(module_t mod, int event, void *data);
189static void ng_worklist_remove(node_p node);
190static void ngintr(void);
42 * $Whistle: ng_base.c,v 1.39 1999/01/28 23:54:53 julian Exp $
43 */
44
45/*
46 * This file implements the base netgraph code.
47 */
48
49#include <sys/param.h>

--- 133 unchanged lines hidden (view full) ---

183
184/* Internal functions */
185static int ng_add_hook(node_p node, const char *name, hook_p * hookp);
186static int ng_generic_msg(node_p here, item_p item, hook_p lasthook);
187static ng_ID_t ng_decodeidname(const char *name);
188static int ngb_mod_event(module_t mod, int event, void *data);
189static void ng_worklist_remove(node_p node);
190static void ngintr(void);
191static int ng_apply_item(node_p node, item_p item);
191static int ng_apply_item(node_p node, item_p item, int rw);
192static void ng_flush_input_queue(struct ng_queue * ngq);
193static void ng_setisr(node_p node);
194static node_p ng_ID2noderef(ng_ID_t ID);
195static int ng_con_nodes(node_p node, const char *name, node_p node2,
196 const char *name2);
197static void ng_con_part2(node_p node, hook_p hook, void *arg1, int arg2);
198static void ng_con_part3(node_p node, hook_p hook, void *arg1, int arg2);
199static int ng_mkpeer(node_p node, const char *name,

--- 1498 unchanged lines hidden (view full) ---

1698* Input queue handling.
1699* All activities are submitted to the node via the input queue
1700* which implements a multiple-reader/single-writer gate.
1701* Items which cannot be handled immeditly are queued.
1702*
1703* read-write queue locking inline functions *
1704\***************************************************************/
1705
192static void ng_flush_input_queue(struct ng_queue * ngq);
193static void ng_setisr(node_p node);
194static node_p ng_ID2noderef(ng_ID_t ID);
195static int ng_con_nodes(node_p node, const char *name, node_p node2,
196 const char *name2);
197static void ng_con_part2(node_p node, hook_p hook, void *arg1, int arg2);
198static void ng_con_part3(node_p node, hook_p hook, void *arg1, int arg2);
199static int ng_mkpeer(node_p node, const char *name,

--- 1498 unchanged lines hidden (view full) ---

1698* Input queue handling.
1699* All activities are submitted to the node via the input queue
1700* which implements a multiple-reader/single-writer gate.
1701* Items which cannot be handled immeditly are queued.
1702*
1703* read-write queue locking inline functions *
1704\***************************************************************/
1705
1706static __inline item_p ng_dequeue(struct ng_queue * ngq);
1706static __inline item_p ng_dequeue(struct ng_queue * ngq, int *rw);
1707static __inline item_p ng_acquire_read(struct ng_queue * ngq,
1708 item_p item);
1709static __inline item_p ng_acquire_write(struct ng_queue * ngq,
1710 item_p item);
1711static __inline void ng_leave_read(struct ng_queue * ngq);
1712static __inline void ng_leave_write(struct ng_queue * ngq);
1713static __inline void ng_queue_rw(struct ng_queue * ngq,
1714 item_p item, int rw);

--- 42 unchanged lines hidden (view full) ---

1757
1758/* tests to decide if we could get a read or write off the queue */
1759#define CAN_GET_READ(flag) ((flag & NGQ_RMASK) == READ_PENDING)
1760#define CAN_GET_WRITE(flag) ((flag & NGQ_WMASK) == WRITE_PENDING)
1761
1762/* Is there a chance of getting ANY work off the queue? */
1763#define CAN_GET_WORK(flag) (CAN_GET_READ(flag) || CAN_GET_WRITE(flag))
1764
1707static __inline item_p ng_acquire_read(struct ng_queue * ngq,
1708 item_p item);
1709static __inline item_p ng_acquire_write(struct ng_queue * ngq,
1710 item_p item);
1711static __inline void ng_leave_read(struct ng_queue * ngq);
1712static __inline void ng_leave_write(struct ng_queue * ngq);
1713static __inline void ng_queue_rw(struct ng_queue * ngq,
1714 item_p item, int rw);

--- 42 unchanged lines hidden (view full) ---

1757
1758/* tests to decide if we could get a read or write off the queue */
1759#define CAN_GET_READ(flag) ((flag & NGQ_RMASK) == READ_PENDING)
1760#define CAN_GET_WRITE(flag) ((flag & NGQ_WMASK) == WRITE_PENDING)
1761
1762/* Is there a chance of getting ANY work off the queue? */
1763#define CAN_GET_WORK(flag) (CAN_GET_READ(flag) || CAN_GET_WRITE(flag))
1764
1765#define NGQRW_R 0
1766#define NGQRW_W 1
1767
1765/*
1766 * Taking into account the current state of the queue and node, possibly take
1767 * the next entry off the queue and return it. Return NULL if there was
1768 * nothing we could return, either because there really was nothing there, or
1769 * because the node was in a state where it cannot yet process the next item
1770 * on the queue.
1771 *
1772 * This MUST MUST MUST be called with the mutex held.
1773 */
1774static __inline item_p
1768/*
1769 * Taking into account the current state of the queue and node, possibly take
1770 * the next entry off the queue and return it. Return NULL if there was
1771 * nothing we could return, either because there really was nothing there, or
1772 * because the node was in a state where it cannot yet process the next item
1773 * on the queue.
1774 *
1775 * This MUST MUST MUST be called with the mutex held.
1776 */
1777static __inline item_p
1775ng_dequeue(struct ng_queue *ngq)
1778ng_dequeue(struct ng_queue *ngq, int *rw)
1776{
1777 item_p item;
1778 u_int add_arg;
1779
1780 mtx_assert(&ngq->q_mtx, MA_OWNED);
1781
1782 if (CAN_GET_READ(ngq->q_flags)) {
1783 /*
1784 * Head of queue is a reader and we have no write active.
1785 * We don't care how many readers are already active.
1786 * Adjust the flags for the item we are about to dequeue.
1787 * Add the correct increment for the reader count as well.
1788 */
1789 add_arg = (READER_INCREMENT - READ_PENDING);
1779{
1780 item_p item;
1781 u_int add_arg;
1782
1783 mtx_assert(&ngq->q_mtx, MA_OWNED);
1784
1785 if (CAN_GET_READ(ngq->q_flags)) {
1786 /*
1787 * Head of queue is a reader and we have no write active.
1788 * We don't care how many readers are already active.
1789 * Adjust the flags for the item we are about to dequeue.
1790 * Add the correct increment for the reader count as well.
1791 */
1792 add_arg = (READER_INCREMENT - READ_PENDING);
1793 *rw = NGQRW_R;
1790 } else if (CAN_GET_WRITE(ngq->q_flags)) {
1791 /*
1792 * There is a pending write, no readers and no active writer.
1793 * This means we can go ahead with the pending writer. Note
1794 * the fact that we now have a writer, ready for when we take
1795 * it off the queue.
1796 *
1797 * We don't need to worry about a possible collision with the

--- 22 unchanged lines hidden (view full) ---

1820 * would arrive at this function. Usually it will have to
1821 * leave empty handed because the ACTIVE WRITER bit will be
1822 * set.
1823 *
1824 * Adjust the flags for the item we are about to dequeue
1825 * and for the new active writer.
1826 */
1827 add_arg = (WRITER_ACTIVE - WRITE_PENDING);
1794 } else if (CAN_GET_WRITE(ngq->q_flags)) {
1795 /*
1796 * There is a pending write, no readers and no active writer.
1797 * This means we can go ahead with the pending writer. Note
1798 * the fact that we now have a writer, ready for when we take
1799 * it off the queue.
1800 *
1801 * We don't need to worry about a possible collision with the

--- 22 unchanged lines hidden (view full) ---

1824 * would arrive at this function. Usually it will have to
1825 * leave empty handed because the ACTIVE WRITER bit will be
1826 * set.
1827 *
1828 * Adjust the flags for the item we are about to dequeue
1829 * and for the new active writer.
1830 */
1831 add_arg = (WRITER_ACTIVE - WRITE_PENDING);
1832 *rw = NGQRW_W;
1828 /*
1829 * We want to write "active writer, no readers " Now go make
1830 * it true. In fact there may be a number in the readers
1831 * count but we know it is not true and will be fixed soon.
1832 * We will fix the flags for the next pending entry in a
1833 * moment.
1834 */
1835 } else {

--- 27 unchanged lines hidden (view full) ---

1863 * Whatever flag was set will be cleared and
1864 * the new acive field will be set by the add as well,
1865 * so we don't need to change add_arg.
1866 * But we know we don't need to be on the work list.
1867 */
1868 atomic_add_long(&ngq->q_flags, add_arg);
1869 ng_worklist_remove(ngq->q_node);
1870 } else {
1833 /*
1834 * We want to write "active writer, no readers " Now go make
1835 * it true. In fact there may be a number in the readers
1836 * count but we know it is not true and will be fixed soon.
1837 * We will fix the flags for the next pending entry in a
1838 * moment.
1839 */
1840 } else {

--- 27 unchanged lines hidden (view full) ---

1868 * Whatever flag was set will be cleared and
1869 * the new acive field will be set by the add as well,
1870 * so we don't need to change add_arg.
1871 * But we know we don't need to be on the work list.
1872 */
1873 atomic_add_long(&ngq->q_flags, add_arg);
1874 ng_worklist_remove(ngq->q_node);
1875 } else {
1876 item_p item = ngq->queue;
1877 hook_p hook = NGI_HOOK(item);
1878 node_p node = NGI_NODE(item);
1879
1871 /*
1872 * Since there is something on the queue, note what it is
1880 /*
1881 * Since there is something on the queue, note what it is
1873 * in the flags word.
1882 * in the flags word. Don't forget about overrides, too.
1874 */
1883 */
1875 if ((ngq->queue->el_flags & NGQF_RW) == NGQF_READER) {
1884 if ((node->nd_flags & NGF_FORCE_WRITER)
1885 || (hook && (hook->hk_flags & HK_FORCE_WRITER)))
1886 add_arg += WRITE_PENDING;
1887 else if ((item->el_flags & NGQF_RW) == NGQF_READER)
1876 add_arg += READ_PENDING;
1888 add_arg += READ_PENDING;
1877 } else {
1889 else
1878 add_arg += WRITE_PENDING;
1890 add_arg += WRITE_PENDING;
1879 }
1891
1880 atomic_add_long(&ngq->q_flags, add_arg);
1881 /*
1882 * If we see more doable work, make sure we are
1883 * on the work queue.
1884 */
1885 if (CAN_GET_WORK(ngq->q_flags)) {
1886 ng_setisr(ngq->q_node);
1887 }

--- 5 unchanged lines hidden (view full) ---

1893 */
1894 return (item);
1895}
1896
1897/*
1898 * Queue a packet to be picked up by someone else.
1899 * We really don't care who, but we can't or don't want to hang around
1900 * to process it ourselves. We are probably an interrupt routine..
1892 atomic_add_long(&ngq->q_flags, add_arg);
1893 /*
1894 * If we see more doable work, make sure we are
1895 * on the work queue.
1896 */
1897 if (CAN_GET_WORK(ngq->q_flags)) {
1898 ng_setisr(ngq->q_node);
1899 }

--- 5 unchanged lines hidden (view full) ---

1905 */
1906 return (item);
1907}
1908
1909/*
1910 * Queue a packet to be picked up by someone else.
1911 * We really don't care who, but we can't or don't want to hang around
1912 * to process it ourselves. We are probably an interrupt routine..
1901 * 1 = writer, 0 = reader
1902 */
1913 */
1903#define NGQRW_R 0
1904#define NGQRW_W 1
1905static __inline void
1906ng_queue_rw(struct ng_queue * ngq, item_p item, int rw)
1907{
1908 mtx_assert(&ngq->q_mtx, MA_OWNED);
1909
1910 item->el_next = NULL; /* maybe not needed */
1911 *ngq->last = item;
1912 /*

--- 262 unchanged lines hidden (view full) ---

2175 break;
2176 default:
2177 panic("%s: invalid item flags %lx", __func__, item->el_flags);
2178 }
2179
2180 /*
2181 * If the node specifies single threading, force writer semantics.
2182 * Similarly, the node may say one hook always produces writers.
1914static __inline void
1915ng_queue_rw(struct ng_queue * ngq, item_p item, int rw)
1916{
1917 mtx_assert(&ngq->q_mtx, MA_OWNED);
1918
1919 item->el_next = NULL; /* maybe not needed */
1920 *ngq->last = item;
1921 /*

--- 262 unchanged lines hidden (view full) ---

2184 break;
2185 default:
2186 panic("%s: invalid item flags %lx", __func__, item->el_flags);
2187 }
2188
2189 /*
2190 * If the node specifies single threading, force writer semantics.
2191 * Similarly, the node may say one hook always produces writers.
2183 * These are overrides. Modify the item itself, so that if it
2184 * is queued now, it would be dequeued later with corrected
2185 * read/write flags.
2192 * These are overrides.
2186 */
2187 if ((node->nd_flags & NGF_FORCE_WRITER)
2193 */
2194 if ((node->nd_flags & NGF_FORCE_WRITER)
2188 || (hook && (hook->hk_flags & HK_FORCE_WRITER))) {
2195 || (hook && (hook->hk_flags & HK_FORCE_WRITER)))
2189 rw = NGQRW_W;
2196 rw = NGQRW_W;
2190 item->el_flags &= ~NGQF_READER;
2191 }
2192
2193 if (queue) {
2194 /* Put it on the queue for that node*/
2195#ifdef NETGRAPH_DEBUG
2196 _ngi_check(item, __FILE__, __LINE__);
2197#endif
2198 mtx_lock_spin(&(ngq->q_mtx));
2199 ng_queue_rw(ngq, item, rw);

--- 49 unchanged lines hidden (view full) ---

2249 _ngi_check(item, __FILE__, __LINE__);
2250#endif
2251 /*
2252 * Take over the reference frm the item.
2253 * Hold it until the called function returns.
2254 */
2255 NGI_GET_NODE(item, node); /* zaps stored node */
2256
2197
2198 if (queue) {
2199 /* Put it on the queue for that node*/
2200#ifdef NETGRAPH_DEBUG
2201 _ngi_check(item, __FILE__, __LINE__);
2202#endif
2203 mtx_lock_spin(&(ngq->q_mtx));
2204 ng_queue_rw(ngq, item, rw);

--- 49 unchanged lines hidden (view full) ---

2254 _ngi_check(item, __FILE__, __LINE__);
2255#endif
2256 /*
2257 * Take over the reference frm the item.
2258 * Hold it until the called function returns.
2259 */
2260 NGI_GET_NODE(item, node); /* zaps stored node */
2261
2257 ierror = ng_apply_item(node, item); /* drops r/w lock when done */
2262 ierror = ng_apply_item(node, item, rw); /* drops r/w lock when done */
2258
2259 /* only return an error if it was our initial item.. (compat hack) */
2260 if (oitem == item) {
2261 error = ierror;
2262 }
2263
2264 /*
2265 * If the node goes away when we remove the reference,

--- 13 unchanged lines hidden (view full) ---

2279}
2280
2281/*
2282 * We have an item that was possibly queued somewhere.
2283 * It should contain all the information needed
2284 * to run it on the appropriate node/hook.
2285 */
2286static int
2263
2264 /* only return an error if it was our initial item.. (compat hack) */
2265 if (oitem == item) {
2266 error = ierror;
2267 }
2268
2269 /*
2270 * If the node goes away when we remove the reference,

--- 13 unchanged lines hidden (view full) ---

2284}
2285
2286/*
2287 * We have an item that was possibly queued somewhere.
2288 * It should contain all the information needed
2289 * to run it on the appropriate node/hook.
2290 */
2291static int
2287ng_apply_item(node_p node, item_p item)
2292ng_apply_item(node_p node, item_p item, int rw)
2288{
2289 hook_p hook;
2293{
2294 hook_p hook;
2290 int was_reader = ((item->el_flags & NGQF_RW));
2291 int error = 0;
2292 ng_rcvdata_t *rcvdata;
2293 ng_rcvmsg_t *rcvmsg;
2294 ng_apply_t *apply = NULL;
2295 void *context = NULL;
2296
2297 NGI_GET_HOOK(item, hook); /* clears stored hook */
2298#ifdef NETGRAPH_DEBUG

--- 116 unchanged lines hidden (view full) ---

2415 * We held references on some of the resources
2416 * that we took from the item. Now that we have
2417 * finished doing everything, drop those references.
2418 */
2419 if (hook) {
2420 NG_HOOK_UNREF(hook);
2421 }
2422
2295 int error = 0;
2296 ng_rcvdata_t *rcvdata;
2297 ng_rcvmsg_t *rcvmsg;
2298 ng_apply_t *apply = NULL;
2299 void *context = NULL;
2300
2301 NGI_GET_HOOK(item, hook); /* clears stored hook */
2302#ifdef NETGRAPH_DEBUG

--- 116 unchanged lines hidden (view full) ---

2419 * We held references on some of the resources
2420 * that we took from the item. Now that we have
2421 * finished doing everything, drop those references.
2422 */
2423 if (hook) {
2424 NG_HOOK_UNREF(hook);
2425 }
2426
2423 if (was_reader) {
2427 if (rw == NGQRW_R) {
2424 ng_leave_read(&node->nd_input_queue);
2425 } else {
2426 ng_leave_write(&node->nd_input_queue);
2427 }
2428
2429 /* Apply callback. */
2430 if (apply != NULL)
2431 (*apply)(context, error);

--- 787 unchanged lines hidden (view full) ---

3219 * that lets us be sure that the node still exists.
3220 * Let the reference go at the last minute.
3221 * ng_dequeue will put us back on the worklist
3222 * if there is more too do. This may be of use if there
3223 * are Multiple Processors and multiple Net threads in the
3224 * future.
3225 */
3226 for (;;) {
2428 ng_leave_read(&node->nd_input_queue);
2429 } else {
2430 ng_leave_write(&node->nd_input_queue);
2431 }
2432
2433 /* Apply callback. */
2434 if (apply != NULL)
2435 (*apply)(context, error);

--- 787 unchanged lines hidden (view full) ---

3223 * that lets us be sure that the node still exists.
3224 * Let the reference go at the last minute.
3225 * ng_dequeue will put us back on the worklist
3226 * if there is more too do. This may be of use if there
3227 * are Multiple Processors and multiple Net threads in the
3228 * future.
3229 */
3230 for (;;) {
3231 int rw;
3232
3227 mtx_lock_spin(&node->nd_input_queue.q_mtx);
3233 mtx_lock_spin(&node->nd_input_queue.q_mtx);
3228 item = ng_dequeue(&node->nd_input_queue);
3234 item = ng_dequeue(&node->nd_input_queue, &rw);
3229 if (item == NULL) {
3230 mtx_unlock_spin(&node->nd_input_queue.q_mtx);
3231 break; /* go look for another node */
3232 } else {
3233 mtx_unlock_spin(&node->nd_input_queue.q_mtx);
3234 NGI_GET_NODE(item, node); /* zaps stored node */
3235 if (item == NULL) {
3236 mtx_unlock_spin(&node->nd_input_queue.q_mtx);
3237 break; /* go look for another node */
3238 } else {
3239 mtx_unlock_spin(&node->nd_input_queue.q_mtx);
3240 NGI_GET_NODE(item, node); /* zaps stored node */
3235 ng_apply_item(node, item);
3241 ng_apply_item(node, item, rw);
3236 NG_NODE_UNREF(node);
3237 }
3238 }
3239 NG_NODE_UNREF(node);
3240 }
3241}
3242
3243static void

--- 392 unchanged lines hidden ---
3242 NG_NODE_UNREF(node);
3243 }
3244 }
3245 NG_NODE_UNREF(node);
3246 }
3247}
3248
3249static void

--- 392 unchanged lines hidden ---