Make GATEWAY (fastforward) work again
With GATEWAY (fastforward), the whole forwarding processing runs in hardware interrupt context. So we cannot use rwlock for lltable and llentry in that case. This change replaces rwlock with mutex(IPL_NET) for lltable and llentry when GATEWAY is enabled. We need to tweak locking only around rtree in lltable_free. Other than that, what we need to do is to change macros for locks. I hope fastforward runs in softint some day in the future...
This commit is contained in:
parent
ad91e721ff
commit
99284d7cc5
38
sys/net/if.h
38
sys/net/if.h
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if.h,v 1.191 2015/08/31 08:02:44 ozaki-r Exp $ */
|
||||
/* $NetBSD: if.h,v 1.192 2015/09/30 07:12:32 ozaki-r Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
|
||||
|
@ -123,6 +123,7 @@
|
|||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_compat_netbsd.h"
|
||||
#include "opt_gateway.h"
|
||||
#endif
|
||||
|
||||
struct mbuf;
|
||||
|
@ -213,7 +214,11 @@ struct ifnet_lock;
|
|||
#include <sys/condvar.h>
|
||||
#include <sys/percpu.h>
|
||||
#include <sys/callout.h>
|
||||
#ifdef GATEWAY
|
||||
#include <sys/mutex.h>
|
||||
#else
|
||||
#include <sys/rwlock.h>
|
||||
#endif
|
||||
|
||||
struct ifnet_lock {
|
||||
kmutex_t il_lock; /* Protects the critical section. */
|
||||
|
@ -347,7 +352,11 @@ typedef struct ifnet {
|
|||
#ifdef _KERNEL /* XXX kvm(3) */
|
||||
struct callout *if_slowtimo_ch;
|
||||
#endif
|
||||
#ifdef GATEWAY
|
||||
struct kmutex *if_afdata_lock;
|
||||
#else
|
||||
struct krwlock *if_afdata_lock;
|
||||
#endif
|
||||
} ifnet_t;
|
||||
|
||||
#define if_mtu if_data.ifi_mtu
|
||||
|
@ -437,6 +446,31 @@ typedef struct ifnet {
|
|||
"\23TSO6" \
|
||||
"\24LRO" \
|
||||
|
||||
#ifdef GATEWAY
|
||||
#define IF_AFDATA_LOCK_INIT(ifp) \
|
||||
do { \
|
||||
(ifp)->if_afdata_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET); \
|
||||
} while (0)
|
||||
|
||||
#define IF_AFDATA_WLOCK(ifp) mutex_enter((ifp)->if_afdata_lock)
|
||||
#define IF_AFDATA_RLOCK(ifp) mutex_enter((ifp)->if_afdata_lock)
|
||||
#define IF_AFDATA_WUNLOCK(ifp) mutex_exit((ifp)->if_afdata_lock)
|
||||
#define IF_AFDATA_RUNLOCK(ifp) mutex_exit((ifp)->if_afdata_lock)
|
||||
#define IF_AFDATA_LOCK(ifp) IF_AFDATA_WLOCK(ifp)
|
||||
#define IF_AFDATA_UNLOCK(ifp) IF_AFDATA_WUNLOCK(ifp)
|
||||
#define IF_AFDATA_TRYLOCK(ifp) mutex_tryenter((ifp)->if_afdata_lock)
|
||||
#define IF_AFDATA_DESTROY(ifp) mutex_destroy((ifp)->if_afdata_lock)
|
||||
|
||||
#define IF_AFDATA_LOCK_ASSERT(ifp) \
|
||||
KASSERT(mutex_owned((ifp)->if_afdata_lock))
|
||||
#define IF_AFDATA_RLOCK_ASSERT(ifp) \
|
||||
KASSERT(mutex_owned((ifp)->if_afdata_lock))
|
||||
#define IF_AFDATA_WLOCK_ASSERT(ifp) \
|
||||
KASSERT(mutex_owned((ifp)->if_afdata_lock))
|
||||
#define IF_AFDATA_UNLOCK_ASSERT(ifp) \
|
||||
KASSERT(!mutex_owned((ifp)->if_afdata_lock))
|
||||
|
||||
#else /* GATEWAY */
|
||||
#define IF_AFDATA_LOCK_INIT(ifp) \
|
||||
do {(ifp)->if_afdata_lock = rw_obj_alloc();} while (0)
|
||||
|
||||
|
@ -457,7 +491,7 @@ typedef struct ifnet {
|
|||
KASSERT(rw_write_held((ifp)->if_afdata_lock))
|
||||
#define IF_AFDATA_UNLOCK_ASSERT(ifp) \
|
||||
KASSERT(!rw_lock_head((ifp)->if_afdata_lock))
|
||||
|
||||
#endif /* GATEWAY */
|
||||
|
||||
#define IFQ_LOCK(_ifq) if ((_ifq)->ifq_lock) mutex_enter((_ifq)->ifq_lock)
|
||||
#define IFQ_UNLOCK(_ifq) if ((_ifq)->ifq_lock) mutex_exit((_ifq)->ifq_lock)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_llatbl.c,v 1.5 2015/09/28 07:55:26 ozaki-r Exp $ */
|
||||
/* $NetBSD: if_llatbl.c,v 1.6 2015/09/30 07:12:32 ozaki-r Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2004 Luigi Rizzo, Alessandro Cerri. All rights reserved.
|
||||
* Copyright (c) 2004-2008 Qing Li. All rights reserved.
|
||||
|
@ -377,8 +377,20 @@ lltable_free(struct lltable *llt)
|
|||
LLE_REMREF(lle);
|
||||
#if defined(__NetBSD__)
|
||||
/* XXX should have callback? */
|
||||
if (lle->la_rt != NULL)
|
||||
rtfree(lle->la_rt);
|
||||
if (lle->la_rt != NULL) {
|
||||
struct rtentry *rt = lle->la_rt;
|
||||
lle->la_rt = NULL;
|
||||
#ifdef GATEWAY
|
||||
/* XXX cannot call rtfree with holding mutex(IPL_NET) */
|
||||
LLE_ADDREF(lle);
|
||||
LLE_WUNLOCK(lle);
|
||||
#endif
|
||||
rtfree(rt);
|
||||
#ifdef GATEWAY
|
||||
LLE_WLOCK(lle);
|
||||
LLE_REMREF(lle);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
llentry_free(lle);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_llatbl.h,v 1.2 2015/08/31 08:05:20 ozaki-r Exp $ */
|
||||
/* $NetBSD: if_llatbl.h,v 1.3 2015/09/30 07:12:32 ozaki-r Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2004 Luigi Rizzo, Alessandro Cerri. All rights reserved.
|
||||
* Copyright (c) 2004-2008 Qing Li. All rights reserved.
|
||||
|
@ -32,7 +32,15 @@
|
|||
#ifndef _NET_IF_LLATBL_H_
|
||||
#define _NET_IF_LLATBL_H_
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_gateway.h"
|
||||
#endif
|
||||
|
||||
#include <sys/rwlock.h>
|
||||
#ifdef GATEWAY
|
||||
#include <sys/mutex.h>
|
||||
#endif
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
struct ifnet;
|
||||
|
@ -85,7 +93,11 @@ struct llentry {
|
|||
|
||||
LIST_ENTRY(llentry) lle_chain; /* chain of deleted items */
|
||||
struct callout lle_timer;
|
||||
#ifdef GATEWAY
|
||||
kmutex_t lle_lock;
|
||||
#else
|
||||
krwlock_t lle_lock;
|
||||
#endif
|
||||
|
||||
#ifdef __NetBSD__
|
||||
#define la_timer lle_timer
|
||||
|
@ -101,6 +113,31 @@ struct llentry {
|
|||
#define LLE_LOCK_TRACE(n)
|
||||
#endif
|
||||
|
||||
#ifdef GATEWAY
|
||||
#define LLE_WLOCK(lle) do { \
|
||||
LLE_LOCK_TRACE(WL); \
|
||||
mutex_enter(&(lle)->lle_lock); \
|
||||
} while (0)
|
||||
#define LLE_RLOCK(lle) do { \
|
||||
LLE_LOCK_TRACE(RL); \
|
||||
mutex_enter(&(lle)->lle_lock); \
|
||||
} while (0)
|
||||
#define LLE_WUNLOCK(lle) do { \
|
||||
LLE_LOCK_TRACE(WU); \
|
||||
mutex_exit(&(lle)->lle_lock); \
|
||||
} while (0)
|
||||
#define LLE_RUNLOCK(lle) do { \
|
||||
LLE_LOCK_TRACE(RU); \
|
||||
mutex_exit(&(lle)->lle_lock); \
|
||||
} while (0)
|
||||
#define LLE_DOWNGRADE(lle) do {} while (0)
|
||||
#define LLE_TRY_UPGRADE(lle) do {} while (0)
|
||||
#define LLE_LOCK_INIT(lle) mutex_init(&(lle)->lle_lock, MUTEX_DEFAULT, \
|
||||
IPL_NET)
|
||||
#define LLE_LOCK_DESTROY(lle) mutex_destroy(&(lle)->lle_lock)
|
||||
#define LLE_WLOCK_ASSERT(lle) KASSERT(mutex_owned(&(lle)->lle_lock))
|
||||
|
||||
#else /* GATEWAY */
|
||||
#define LLE_WLOCK(lle) do { \
|
||||
LLE_LOCK_TRACE(WL); \
|
||||
rw_enter(&(lle)->lle_lock, RW_WRITER); \
|
||||
|
@ -126,6 +163,7 @@ struct llentry {
|
|||
#endif
|
||||
#define LLE_LOCK_DESTROY(lle) rw_destroy(&(lle)->lle_lock)
|
||||
#define LLE_WLOCK_ASSERT(lle) KASSERT(rw_write_held(&(lle)->lle_lock))
|
||||
#endif /* GATEWAY */
|
||||
|
||||
#define LLE_IS_VALID(lle) (((lle) != NULL) && ((lle) != (void *)-1))
|
||||
|
||||
|
|
Loading…
Reference in New Issue