Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/net Refactor BPF_COPX code. New version doesn't load buf...



details:   https://anonhg.NetBSD.org/src/rev/4ff44162399f
branches:  trunk
changeset: 330554:4ff44162399f
user:      alnsn <alnsn%NetBSD.org@localhost>
date:      Sun Jul 13 21:54:46 2014 +0000

description:
Refactor BPF_COPX code. New version doesn't load buf and buflen after copx call.

diffstat:

 sys/net/bpfjit.c |  148 +++++++++++++++++++++++++++---------------------------
 1 files changed, 74 insertions(+), 74 deletions(-)

diffs (232 lines):

diff -r 9c925bad376a -r 4ff44162399f sys/net/bpfjit.c
--- a/sys/net/bpfjit.c  Sun Jul 13 21:35:33 2014 +0000
+++ b/sys/net/bpfjit.c  Sun Jul 13 21:54:46 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bpfjit.c,v 1.27 2014/07/13 18:48:27 alnsn Exp $        */
+/*     $NetBSD: bpfjit.c,v 1.28 2014/07/13 21:54:46 alnsn Exp $        */
 
 /*-
  * Copyright (c) 2011-2014 Alexander Nasonov.
@@ -31,9 +31,9 @@
 
 #include <sys/cdefs.h>
 #ifdef _KERNEL
-__KERNEL_RCSID(0, "$NetBSD: bpfjit.c,v 1.27 2014/07/13 18:48:27 alnsn Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bpfjit.c,v 1.28 2014/07/13 21:54:46 alnsn Exp $");
 #else
-__RCSID("$NetBSD: bpfjit.c,v 1.27 2014/07/13 18:48:27 alnsn Exp $");
+__RCSID("$NetBSD: bpfjit.c,v 1.28 2014/07/13 21:54:46 alnsn Exp $");
 #endif
 
 #include <sys/types.h>
@@ -95,13 +95,6 @@
 #define BJ_XREG                SLJIT_TEMPORARY_EREG1
 #define BJ_TMP3REG     SLJIT_TEMPORARY_EREG2
 
-/*
- * EREG registers can't be used for indirect calls, reuse BJ_BUF and
- * BJ_BUFLEN registers. They can be easily restored from BJ_ARGS.
- */
-#define BJ_COPF_PTR    SLJIT_SAVED_REG1
-#define BJ_COPF_IDX    SLJIT_SAVED_REG3
-
 #ifdef _KERNEL
 #define MAX_MEMWORDS BPF_MAX_MEMWORDS
 #else
@@ -123,11 +116,12 @@
  * Optimization hints.
  */
 typedef unsigned int bpfjit_hint_t;
-#define BJ_HINT_ABS  0x01 /* packet read at absolute offset  */
-#define BJ_HINT_IND  0x02 /* packet read at variable offset  */
-#define BJ_HINT_COP  0x04 /* BPF_COP or BPF_COPX instruction */
-#define BJ_HINT_XREG 0x08 /* BJ_XREG is needed   */
-#define BJ_HINT_LDX  0x10 /* BPF_LDX instruction */
+#define BJ_HINT_ABS  0x01 /* packet read at absolute offset   */
+#define BJ_HINT_IND  0x02 /* packet read at variable offset   */
+#define BJ_HINT_COP  0x04 /* BPF_COP or BPF_COPX instruction  */
+#define BJ_HINT_COPX 0x08 /* BPF_COPX instruction             */
+#define BJ_HINT_XREG 0x10 /* BJ_XREG is needed                */
+#define BJ_HINT_LDX  0x20 /* BPF_LDX instruction              */
 #define BJ_HINT_PKT  (BJ_HINT_ABS|BJ_HINT_IND) /* packet read */
 
 /*
@@ -271,6 +265,9 @@
                rv = 5; /* uses BJ_TMP3REG */
 #endif
 
+       if (hints & BJ_HINT_COPX)
+               rv = 5; /* uses BJ_TMP3REG */
+
        return rv;
 }
 
@@ -649,26 +646,31 @@
  * Emit code for BPF_COP and BPF_COPX instructions.
  */
 static int
-emit_cop(struct sljit_compiler *compiler, const bpf_ctx_t *bc,
-    const struct bpf_insn *pc, struct sljit_jump **ret0_jump)
+emit_cop(struct sljit_compiler *compiler,
+    const bpf_ctx_t *bc, const struct bpf_insn *pc,
+    struct sljit_jump ***ret0, size_t *ret0_size, size_t *ret0_maxsize)
 {
-#if BJ_XREG == SLJIT_RETURN_REG   || \
-    BJ_XREG == SLJIT_SCRATCH_REG1 || \
-    BJ_XREG == SLJIT_SCRATCH_REG2 || \
-    BJ_XREG == SLJIT_SCRATCH_REG3 || \
-    BJ_COPF_PTR == BJ_ARGS        || \
-    BJ_COPF_IDX        == BJ_ARGS
+#if BJ_XREG    == SLJIT_RETURN_REG   || \
+    BJ_XREG    == SLJIT_SCRATCH_REG1 || \
+    BJ_XREG    == SLJIT_SCRATCH_REG2 || \
+    BJ_XREG    == SLJIT_SCRATCH_REG3 || \
+    BJ_TMP3REG == SLJIT_SCRATCH_REG1 || \
+    BJ_TMP3REG == SLJIT_SCRATCH_REG2 || \
+    BJ_TMP3REG == SLJIT_SCRATCH_REG3
 #error "Not supported assignment of registers."
 #endif
 
        struct sljit_jump *jump;
+       sljit_si call_reg;
+       sljit_sw call_off;
        int status;
 
-       jump = NULL;
-
        BJ_ASSERT(bc != NULL && bc->copfuncs != NULL);
 
-       if (BPF_MISCOP(pc->code) == BPF_COPX) {
+       if (BPF_MISCOP(pc->code) == BPF_COP) {
+               call_reg = SLJIT_IMM;
+               call_off = SLJIT_FUNC_OFFSET(bc->copfuncs[pc->k]);
+       } else {
                /* if (X >= bc->nfuncs) return 0; */
                jump = sljit_emit_cmp(compiler,
                    SLJIT_C_GREATER_EQUAL,
@@ -676,10 +678,46 @@
                    SLJIT_IMM, bc->nfuncs);
                if (jump == NULL)
                        return SLJIT_ERR_ALLOC_FAILED;
-       }
+               if (!append_jump(jump, ret0, ret0_size, ret0_maxsize))
+                       return SLJIT_ERR_ALLOC_FAILED;
+
+               /* tmp1 = ctx; */
+               status = sljit_emit_op1(compiler,
+                   SLJIT_MOV_P,
+                   BJ_TMP1REG, 0,
+                   SLJIT_MEM1(SLJIT_LOCALS_REG),
+                   offsetof(struct bpfjit_stack, ctx));
+               if (status != SLJIT_SUCCESS)
+                       return status;
 
-       if (jump != NULL)
-               *ret0_jump = jump;
+               /* tmp1 = ctx->copfuncs; */
+               status = sljit_emit_op1(compiler,
+                   SLJIT_MOV_P,
+                   BJ_TMP1REG, 0,
+                   SLJIT_MEM1(BJ_TMP1REG),
+                   offsetof(struct bpf_ctx, copfuncs));
+               if (status != SLJIT_SUCCESS)
+                       return status;
+
+               /* tmp2 = X; */
+               status = sljit_emit_op1(compiler,
+                   SLJIT_MOV,
+                   BJ_TMP2REG, 0,
+                   BJ_XREG, 0);
+               if (status != SLJIT_SUCCESS)
+                       return status;
+
+               /* tmp3 = ctx->copfuncs[tmp2]; */
+               call_reg = BJ_TMP3REG;
+               call_off = 0;
+               status = sljit_emit_op1(compiler,
+                   SLJIT_MOV_P,
+                   call_reg, call_off,
+                   SLJIT_MEM2(BJ_TMP1REG, BJ_TMP2REG),
+                   SLJIT_WORD_SHIFT);
+               if (status != SLJIT_SUCCESS)
+                       return status;
+       }
 
        /*
         * Copy bpf_copfunc_t arguments to registers.
@@ -708,44 +746,10 @@
        if (status != SLJIT_SUCCESS)
                return status;
 
-       if (BPF_MISCOP(pc->code) == BPF_COP) {
-               status = sljit_emit_ijump(compiler,
-                   SLJIT_CALL3,
-                   SLJIT_IMM, SLJIT_FUNC_OFFSET(bc->copfuncs[pc->k]));
-               if (status != SLJIT_SUCCESS)
-                       return status;
-       } else if (BPF_MISCOP(pc->code) == BPF_COPX) {
-               /* load ctx->copfuncs */
-               status = sljit_emit_op1(compiler,
-                   SLJIT_MOV_P,
-                   BJ_COPF_PTR, 0,
-                   SLJIT_MEM1(SLJIT_SCRATCH_REG1),
-                   offsetof(struct bpf_ctx, copfuncs));
-               if (status != SLJIT_SUCCESS)
-                       return status;
-
-               /*
-                * Load X to a register that can be used for
-                * memory addressing.
-                */
-               status = sljit_emit_op1(compiler,
-                   SLJIT_MOV,
-                   BJ_COPF_IDX, 0,
-                   BJ_XREG, 0);
-               if (status != SLJIT_SUCCESS)
-                       return status;
-
-               status = sljit_emit_ijump(compiler,
-                   SLJIT_CALL3,
-                   SLJIT_MEM2(BJ_COPF_PTR, BJ_COPF_IDX),
-                   SLJIT_WORD_SHIFT);
-               if (status != SLJIT_SUCCESS)
-                       return status;
-
-               status = load_buf_buflen(compiler);
-               if (status != SLJIT_SUCCESS)
-                       return status;
-       }
+       status = sljit_emit_ijump(compiler,
+           SLJIT_CALL3, call_reg, call_off);
+       if (status != SLJIT_SUCCESS)
+               return status;
 
 #if BJ_AREG != SLJIT_RETURN_REG
        status = sljit_emit_op1(compiler,
@@ -1328,7 +1332,7 @@
                                continue;
 
                        case BPF_COPX:
-                               *hints |= BJ_HINT_XREG;
+                               *hints |= BJ_HINT_XREG | BJ_HINT_COPX;
                                /* FALLTHROUGH */
 
                        case BPF_COP:
@@ -2019,15 +2023,11 @@
                                        goto fail;
                                }
 
-                               jump = NULL;
-                               status = emit_cop(compiler, bc, pc, &jump);
+                               status = emit_cop(compiler, bc, pc,
+                                   &ret0, &ret0_size, &ret0_maxsize);
                                if (status != SLJIT_SUCCESS)
                                        goto fail;
 
-                               if (jump != NULL && !append_jump(jump,
-                                   &ret0, &ret0_size, &ret0_maxsize))
-                                       goto fail;
-
                                continue;
                        }
 



Home | Main Index | Thread Index | Old Index