Add bpfjit and enable it for amd64.

This commit is contained in:
alnsn 2012-10-27 22:36:11 +00:00
parent 742208e873
commit e8c0d6c662
11 changed files with 1935 additions and 17 deletions

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1783 2012/10/02 01:47:39 christos Exp $
# $NetBSD: mi,v 1.1784 2012/10/27 22:36:11 alnsn Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -1806,6 +1806,7 @@
./usr/include/net/bpf.h comp-c-include
./usr/include/net/bpfdesc.h comp-c-include
./usr/include/net/bpf_jit.h comp-c-include obsolete
./usr/include/net/bpfjit.h comp-c-include
./usr/include/net/dlt.h comp-c-include
./usr/include/net/ethertypes.h comp-c-include
./usr/include/net/if.h comp-c-include

@ -1,4 +1,4 @@
# $NetBSD: md.amd64,v 1.35 2012/10/13 19:42:02 alnsn Exp $
# $NetBSD: md.amd64,v 1.36 2012/10/27 22:36:13 alnsn Exp $
./@MODULEDIR@/acpiacad base-kernel-modules kmod
./@MODULEDIR@/acpiacad/acpiacad.kmod base-kernel-modules kmod
./@MODULEDIR@/acpibat base-kernel-modules kmod
@ -39,6 +39,8 @@
./@MODULEDIR@/auvitek/auvitek.kmod base-kernel-modules kmod
./@MODULEDIR@/azalia base-kernel-modules kmod
./@MODULEDIR@/azalia/azalia.kmod base-kernel-modules kmod
./@MODULEDIR@/bpfjit base-kernel-modules kmod
./@MODULEDIR@/bpfjit/bpfjit.kmod base-kernel-modules kmod
./@MODULEDIR@/compat_linux base-kernel-modules kmod
./@MODULEDIR@/compat_linux/compat_linux.kmod base-kernel-modules kmod
./@MODULEDIR@/compat_linux32 base-kernel-modules kmod

@ -1,4 +1,4 @@
# $NetBSD: files,v 1.1059 2012/10/17 20:16:59 drochner Exp $
# $NetBSD: files,v 1.1060 2012/10/27 22:36:13 alnsn Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
version 20100430
@ -186,6 +186,10 @@ include "dev/sysmon/files.sysmon"
define bpf_filter
defparam opt_bpf.h BPF_BUFSIZE
defflag opt_bpfjit.h BPFJIT
file net/bpfjit.c sljit & bpfjit
include "net80211/files.net80211"
include "netatalk/files.netatalk"
include "netbt/files.netbt"

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.112 2012/10/13 19:42:03 alnsn Exp $
# $NetBSD: Makefile,v 1.113 2012/10/27 22:36:13 alnsn Exp $
.include <bsd.own.mk>
@ -122,6 +122,7 @@ SUBDIR+= vmt
.endif
.if ${MACHINE_ARCH} == "x86_64"
SUBDIR+= bpfjit
SUBDIR+= sljit
.endif

@ -0,0 +1,14 @@
# $NetBSD: Makefile,v 1.1 2012/10/27 22:36:14 alnsn Exp $
#
.include "../Makefile.inc"
.PATH: ${S}/net
KMOD= bpfjit
SRCS= bpfjit.c
CPPFLAGS+= \
-I ${NETBSDSRCDIR}/sys/external/bsd/sljit/dist/sljit_src
.include <bsd.kmodule.mk>

@ -1,8 +1,8 @@
# $NetBSD: Makefile,v 1.31 2012/09/27 18:28:56 alnsn Exp $
# $NetBSD: Makefile,v 1.32 2012/10/27 22:36:14 alnsn Exp $
INCSDIR= /usr/include/net
INCS= bpf.h bpfdesc.h dlt.h ethertypes.h if.h if_arc.h if_arp.h \
INCS= bpf.h bpfjit.h bpfdesc.h dlt.h ethertypes.h if.h if_arc.h if_arp.h \
if_atm.h if_bridgevar.h if_dl.h if_ether.h if_etherip.h if_fddi.h if_gif.h \
if_gre.h if_hippi.h if_ieee1394.h if_llc.h if_media.h if_mpls.h \
if_pflog.h if_ppp.h if_pppoe.h if_sppp.h if_srt.h if_stf.h \

@ -1,4 +1,4 @@
/* $NetBSD: bpf.c,v 1.172 2012/09/27 18:28:56 alnsn Exp $ */
/* $NetBSD: bpf.c,v 1.173 2012/10/27 22:36:14 alnsn Exp $ */
/*
* Copyright (c) 1990, 1991, 1993
@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.172 2012/09/27 18:28:56 alnsn Exp $");
__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.173 2012/10/27 22:36:14 alnsn Exp $");
#if defined(_KERNEL_OPT)
#include "opt_bpf.h"
@ -80,6 +80,7 @@ __KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.172 2012/09/27 18:28:56 alnsn Exp $");
#include <net/bpf.h>
#include <net/bpfdesc.h>
#include <net/bpfjit.h>
#include <net/if_arc.h>
#include <net/if_ether.h>
@ -107,6 +108,12 @@ __KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.172 2012/09/27 18:28:56 alnsn Exp $");
*/
int bpf_bufsize = BPF_BUFSIZE;
int bpf_maxbufsize = BPF_DFLTBUFSIZE; /* XXX set dynamically, see above */
bool bpf_jit = false;
struct bpfjit_ops bpfjit_module_ops = {
.bj_generate_code = NULL,
.bj_free_code = NULL
};
/*
* Global BPF statistics returned by net.bpf.stats sysctl.
@ -418,6 +425,7 @@ bpfopen(dev_t dev, int flag, int mode, struct lwp *l)
callout_init(&d->bd_callout, 0);
selinit(&d->bd_sel);
d->bd_sih = softint_establish(SOFTINT_CLOCK, bpf_softintr, d);
d->bd_jitcode = NULL;
mutex_enter(&bpf_mtx);
LIST_INSERT_HEAD(&bpf_list, d, bd_list);
@ -1054,9 +1062,11 @@ int
bpf_setf(struct bpf_d *d, struct bpf_program *fp)
{
struct bpf_insn *fcode, *old;
bpfjit_function_t jcode, oldj;
size_t flen, size;
int s;
jcode = NULL;
flen = fp->bf_len;
if ((fp->bf_insns == NULL && flen) || flen > BPF_MAXINSNS) {
@ -1075,6 +1085,10 @@ bpf_setf(struct bpf_d *d, struct bpf_program *fp)
free(fcode, M_DEVBUF);
return EINVAL;
}
membar_consumer();
if (bpf_jit && bpfjit_module_ops.bj_generate_code != NULL) {
jcode = bpfjit_module_ops.bj_generate_code(fcode, flen);
}
} else {
fcode = NULL;
}
@ -1082,6 +1096,8 @@ bpf_setf(struct bpf_d *d, struct bpf_program *fp)
s = splnet();
old = d->bd_filter;
d->bd_filter = fcode;
oldj = d->bd_jitcode;
d->bd_jitcode = jcode;
reset_d(d);
splx(s);
@ -1089,6 +1105,11 @@ bpf_setf(struct bpf_d *d, struct bpf_program *fp)
free(old, M_DEVBUF);
}
if (oldj != NULL) {
KASSERT(bpfjit_module_ops.bj_free_code != NULL);
bpfjit_module_ops.bj_free_code(oldj);
}
return 0;
}
@ -1358,7 +1379,11 @@ bpf_deliver(struct bpf_if *bp, void *(*cpfn)(void *, const void *, size_t),
d->bd_rcount++;
bpf_gstats.bs_recv++;
slen = bpf_filter(d->bd_filter, pkt, pktlen, buflen);
if (d->bd_jitcode != NULL)
slen = d->bd_jitcode(pkt, pktlen, buflen);
else
slen = bpf_filter(d->bd_filter, pkt, pktlen, buflen);
if (!slen) {
continue;
}
@ -1687,6 +1712,11 @@ bpf_freed(struct bpf_d *d)
}
if (d->bd_filter)
free(d->bd_filter, M_DEVBUF);
if (d->bd_jitcode != NULL) {
KASSERT(bpfjit_module_ops.bj_free_code != NULL);
bpfjit_module_ops.bj_free_code(d->bd_jitcode);
}
}
/*
@ -1858,6 +1888,36 @@ sysctl_net_bpf_maxbufsize(SYSCTLFN_ARGS)
return (0);
}
static int
sysctl_net_bpf_jit(SYSCTLFN_ARGS)
{
bool newval;
int error;
struct sysctlnode node;
node = *rnode;
node.sysctl_data = &newval;
newval = bpf_jit;
error = sysctl_lookup(SYSCTLFN_CALL(&node));
if (error != 0 || newp == NULL)
return error;
bpf_jit = newval;
/*
* Do a full sync to publish new bpf_jit value and
* update bpfjit_module_ops.bj_generate_code variable.
*/
membar_sync();
if (newval && bpfjit_module_ops.bj_generate_code == NULL) {
printf("WARNING jit activation is postponed "
"until after bpfjit module is loaded\n");
}
return 0;
}
static int
sysctl_net_bpf_peers(SYSCTLFN_ARGS)
{
@ -1948,6 +2008,12 @@ sysctl_net_bpf_setup(void)
NULL, 0, NULL, 0,
CTL_NET, CTL_CREATE, CTL_EOL);
if (node != NULL) {
sysctl_createv(&bpf_sysctllog, 0, NULL, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_BOOL, "jit",
SYSCTL_DESCR("Toggle Just-In-Time compilation"),
sysctl_net_bpf_jit, 0, &bpf_jit, 0,
CTL_NET, node->sysctl_num, CTL_CREATE, CTL_EOL);
sysctl_createv(&bpf_sysctllog, 0, NULL, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "maxbufsize",

@ -1,4 +1,4 @@
/* $NetBSD: bpf_filter.c,v 1.54 2012/09/27 18:28:56 alnsn Exp $ */
/* $NetBSD: bpf_filter.c,v 1.55 2012/10/27 22:36:14 alnsn Exp $ */
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: bpf_filter.c,v 1.54 2012/09/27 18:28:56 alnsn Exp $");
__KERNEL_RCSID(0, "$NetBSD: bpf_filter.c,v 1.55 2012/10/27 22:36:14 alnsn Exp $");
#if 0
#if !(defined(lint) || defined(KERNEL))
@ -68,10 +68,11 @@ static const char rcsid[] =
} \
}
static int m_xword (const struct mbuf *, uint32_t, int *);
static int m_xhalf (const struct mbuf *, uint32_t, int *);
uint32_t m_xword (const struct mbuf *, uint32_t, int *);
uint32_t m_xhalf (const struct mbuf *, uint32_t, int *);
uint32_t m_xbyte (const struct mbuf *, uint32_t, int *);
static int
uint32_t
m_xword(const struct mbuf *m, uint32_t k, int *err)
{
int len;
@ -101,7 +102,7 @@ m_xword(const struct mbuf *m, uint32_t k, int *err)
}
}
static int
uint32_t
m_xhalf(const struct mbuf *m, uint32_t k, int *err)
{
int len;
@ -121,6 +122,16 @@ m_xhalf(const struct mbuf *m, uint32_t k, int *err)
*err = 0;
return (cp[0] << 8) | mtod(m0, u_char *)[0];
}
uint32_t
m_xbyte(const struct mbuf *m, uint32_t k, int *err)
{
int len;
*err = 0;
MINDEX(len, m, k);
return mtod(m, u_char *)[k];
}
#else /* _KERNEL */
#include <stdlib.h>
#endif /* !_KERNEL */

@ -1,4 +1,4 @@
/* $NetBSD: bpfdesc.h,v 1.35 2012/09/27 18:28:56 alnsn Exp $ */
/* $NetBSD: bpfdesc.h,v 1.36 2012/10/27 22:36:14 alnsn Exp $ */
/*
* Copyright (c) 1990, 1991, 1993
@ -44,6 +44,7 @@
#include <sys/callout.h>
#include <sys/selinfo.h> /* for struct selinfo */
#include <net/if.h> /* for IFNAMSIZ */
#include <net/bpfjit.h> /* for bpfjit_function_t */
/*
* Descriptor associated with each open bpf file.
@ -100,7 +101,7 @@ struct bpf_d {
#ifdef _LP64
int bd_compat32; /* 32-bit stream on LP64 system */
#endif
void *bd_dummy; /* to be replaced shortly with bd_jitcode */
bpfjit_function_t bd_jitcode;
};

1746
sys/net/bpfjit.c Normal file

File diff suppressed because it is too large Load Diff

72
sys/net/bpfjit.h Normal file

@ -0,0 +1,72 @@
/* $NetBSD: bpfjit.h,v 1.1 2012/10/27 22:36:14 alnsn Exp $ */
/*-
* Copyright (c) 2011-2012 Alexander Nasonov.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _NET_BPFJIT_H_
#define _NET_BPFJIT_H_
#ifndef _KERNEL
#include <stddef.h>
#include <stdint.h>
#endif
#include <sys/types.h>
#ifdef __linux
#include <pcap-bpf.h>
#else
#include <net/bpf.h>
#endif
/*
* RETURN value and arguments of a function generated by sljit have sljit_uw
* type which can have a greater width than arguments below. In such cases,
* we rely on the fact that calling conventions use same registers for
* smaller types.
* SLJIT_MOV_UI is passed to sljit_emit_return() to make sure that the
* return value is truncated to unsigned int.
*/
typedef unsigned int (*bpfjit_function_t)(const uint8_t *,
unsigned int, unsigned int);
bpfjit_function_t bpfjit_generate_code(struct bpf_insn *, size_t);
void bpfjit_free_code(bpfjit_function_t);
#ifdef _KERNEL
struct bpfjit_ops
{
bpfjit_function_t (*bj_generate_code)(struct bpf_insn *, size_t);
void (*bj_free_code)(bpfjit_function_t);
};
extern struct bpfjit_ops bpfjit_module_ops;
#endif
#endif /* !_NET_BPFJIT_H_ */