diff options
Diffstat (limited to 'framework/src/suricata/src/util-logopenfile-tile.c')
-rw-r--r-- | framework/src/suricata/src/util-logopenfile-tile.c | 370 |
1 files changed, 0 insertions, 370 deletions
diff --git a/framework/src/suricata/src/util-logopenfile-tile.c b/framework/src/suricata/src/util-logopenfile-tile.c deleted file mode 100644 index c2414fc4..00000000 --- a/framework/src/suricata/src/util-logopenfile-tile.c +++ /dev/null @@ -1,370 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio <decanio.tom@gmail.com> - * \author Ken Steele, Tilera Corporation <suricata@tilera.com> - * - * File-like output for logging on Tilera PCIe cards (TILEncore-Gx) - * add the option to send logs across PCIe and then write the output - * files on the host system. - * - */ -#include <sys/types.h> - -#include "suricata-common.h" /* errno.h, string.h, etc. */ -#include "tm-modules.h" /* LogFileCtx */ -#include "conf.h" /* ConfNode, etc. */ -#include "util-atomic.h" -#include "util-logopenfile-tile.h" - -#ifdef __tile__ -#include <gxio/trio.h> -#include <mde-version.h> - -#if MDE_VERSION_CODE >= MDE_VERSION(4,1,0) -#include <gxpci/gxpci.h> -#else -#include <gxpci.h> -#endif - -/* - * Tilera trio (PCIe) configuration. - */ -static gxio_trio_context_t trio_context_body; -static gxio_trio_context_t* trio_context = &trio_context_body; -/* - * gxpci contexts used for log relay - */ -static gxpci_context_t gxpci_context_body; -static gxpci_context_t *gxpci_context = &gxpci_context_body; -/* The TRIO index. */ -static int trio_index = 0; - -/* The queue index of a packet queue. */ -static unsigned int queue_index = 0; - -/* The local PCIe MAC index. */ -static int loc_mac; - -/* - * Code for writing files over PCIe to host on Tilera TILEncore PCIe cards. - */ - -#define OP_OPEN 1 -#define OP_WRITE 2 -#define OP_CLOSE 3 - -/** Maximum number of commands in one PCIe function call */ -#define MAX_CMDS_BATCH 64 - -typedef struct { - uint32_t magic; - uint32_t fileno; - uint32_t op; - uint32_t seq; - uint32_t len; - uint32_t next_offset; - char buf[]; -} __attribute__((__packed__)) PcieMsg; - -static int gxpci_fileno = 0; -static int pcie_initialized = 0; -/* Allocate a Huge page of memory, registered with Trio, into which - data to be sent over PCIe is written. Each write starts at wc_pos. -*/ -static char *log_mem = NULL; -static uint64_t wr_pos; /* write position within log_mem */ - -static SCMutex raw_mutex __attribute__((aligned(64))); -static SCMutex pcie_mutex __attribute__((aligned(64))); -#define CHECK_SEQ_NUM 1 -#ifdef CHECK_SEQ_NUM -static uint32_t raw_seq = 0; -#endif -static uint32_t comps_rcvd = 0; -/* Block of memory registered with PCIe DMA engine as a source for - * PCIe data transfers. Must be <= Huge Page size (16 MB). - * Must be large enough that it can't wrap before first PCIe transfer - * has completed. - */ -#define PCIE_MEMORY_BLOCK_SIZE (4 * 1024 * 1024) - -/* Send a buffer over PCIe to Host memory. - * len must be smaller than one Packet Queue transfer block. - * TODO: Check errors - */ -static void TilePcieDMABuf(void *buf, uint32_t len) -{ - gxpci_comp_t comp[MAX_CMDS_BATCH]; - gxpci_cmd_t cmd; - int result; - int credits; - - SCMutexLock(&pcie_mutex); - -#ifdef CHECK_SEQ_NUM - ((PcieMsg *)buf)->seq = ++raw_seq; - __insn_mf(); -#endif - - /* Wait for credits to be available for more PCIe writes. */ - do { - result = gxpci_get_comps(gxpci_context, comp, 0, MAX_CMDS_BATCH); - if (result) { - if (unlikely(result == GXPCI_ERESET)) { - SCLogInfo("gxpci channel is reset"); - return; - } else { - __sync_fetch_and_add(&comps_rcvd, result); - } - } - - credits = gxpci_get_cmd_credits(gxpci_context); - if (unlikely(credits == GXPCI_ERESET)) { - SCLogInfo("gxpci channel is reset"); - return; - } - } while (credits == 0); - - cmd.buffer = buf; - /* Round transfer size up to next host cache-line. This will - * transfer more data, but is more efficient. - */ - cmd.size = (len + (CLS - 1)) & ~(CLS - 1); - - __insn_mf(); - - /* Loop until the command is sent. */ - do { - /* Send PCIe command to packet queue from tile to host. */ - result = gxpci_pq_t2h_cmd(gxpci_context, &cmd); - if (result == 0) - break; - if (result == GXPCI_ERESET) { - SCLogInfo("gxpci channel is reset"); - break; - } - /* Not enough credits to send command? */ - if (result == GXPCI_ECREDITS) - continue; - } while (1); - - SCMutexUnlock(&pcie_mutex); -} - -/* Allocate a buffer for data that can be sent over PCIe. Reserves - * space at the beginning for the Pcie msg. The buffer is allocated - * from a 4MB pool on one huge page. The allocation simply walks - * throught the buffer sequentially. This removes the need to free - * the buffers, as they simply age out. - */ -static PcieMsg *TilePcieAllocateBuffer(size_t size) -{ - size += sizeof(PcieMsg); - /* Round up to cache-line size */ - size = (size + (CLS - 1)) & ~(CLS - 1); - - PcieMsg *pmsg; - SCMutexLock(&raw_mutex); - pmsg = (PcieMsg *)&log_mem[wr_pos]; - wr_pos += size; - if (wr_pos > PCIE_MEMORY_BLOCK_SIZE) { - /* Don't have enough space at the end of the memory block, so - * wrap to the start. - */ - pmsg = (PcieMsg *)&log_mem[0]; - wr_pos = size; - - } - SCMutexUnlock(&raw_mutex); - - return pmsg; -} - -static void PcieWriteOpen(PcieFile *fp, const char *path, const char append) -{ - /* Need space for file name, file mode character and string termination */ - const int buffer_size = strlen(path) + 2; - - /* Allocate space in the PCIe output buffer */ - PcieMsg *p = TilePcieAllocateBuffer(buffer_size); - - p->magic = 5555; - p->fileno = fp->fileno; - p->op = OP_OPEN; - p->len = offsetof(PcieMsg, buf); - /* Format is one character Mode, followed by file path. */ - p->len += snprintf(p->buf, buffer_size, "%c%s", append, path); - - TilePcieDMABuf(p, p->len); -} - -static int TilePcieWrite(const char *buffer, int buffer_len, LogFileCtx *log_ctx) -{ - PcieFile *fp = log_ctx->pcie_fp; - /* Allocate space in the PCIe output buffer */ - PcieMsg *p = TilePcieAllocateBuffer(buffer_len); - - p->magic = 5555; - p->fileno = fp->fileno; - p->op = OP_WRITE; - p->len = offsetof(PcieMsg, buf); - p->len += buffer_len; - p->next_offset = 0; - - /* Can remove the need for this memcpy later. */ - memcpy(p->buf, buffer, buffer_len); - - TilePcieDMABuf(p, p->len); - - return buffer_len; -} - -static PcieFile *TileOpenPcieFpInternal(const char *path, const char append_char) -{ - int result; - PcieFile *fp; - - /* Only initialize once */ - if (SCAtomicCompareAndSwap(&pcie_initialized, 0, 1)) { - SCMutexInit(&raw_mutex, NULL); - SCMutexInit(&pcie_mutex, NULL); - - SCLogInfo("Initializing Tile-Gx PCIe index %d / %d, queue: %d", - trio_index, loc_mac, queue_index); - - result = gxio_trio_init(trio_context, trio_index); - if (result < 0) { - pcie_initialized = 0; - SCLogError(SC_ERR_PCIE_INIT_FAILED, - "gxio_trio_init() failed: %d: %s", - result, gxio_strerror(result)); - return NULL; - } - - result = gxpci_init(trio_context, gxpci_context, trio_index, loc_mac); - if (result < 0) { - pcie_initialized = 0; - SCLogError(SC_ERR_PCIE_INIT_FAILED, - "gxpci_init() failed: %d: %s", - result, gxpci_strerror(result)); - return NULL; - } - - /* - * This indicates that we need to allocate an ASID ourselves, - * instead of using one that is allocated somewhere else. - */ - int asid = GXIO_ASID_NULL; - - result = gxpci_open_queue(gxpci_context, asid, GXPCI_PQ_T2H, 0, - queue_index, 0, 0); - if (result < 0) { - pcie_initialized = 0; - SCLogError(SC_ERR_PCIE_INIT_FAILED, - "gxpci_open_queue() failed: %d: %s", - result, gxpci_strerror(result)); - return NULL; - } - - /* - * Allocate and register data buffer - */ - size_t hugepagesz = tmc_alloc_get_huge_pagesize(); - tmc_alloc_t alloc = TMC_ALLOC_INIT; - tmc_alloc_set_huge(&alloc); - tmc_alloc_set_home(&alloc, TMC_ALLOC_HOME_HASH); - tmc_alloc_set_pagesize_exact(&alloc, hugepagesz); - log_mem = tmc_alloc_map(&alloc, hugepagesz); - BUG_ON(PCIE_MEMORY_BLOCK_SIZE > hugepagesz); - - result = gxpci_iomem_register(gxpci_context, log_mem, hugepagesz); - if (result < 0) { - pcie_initialized = 0; - SCLogError(SC_ERR_PCIE_INIT_FAILED, - "gxpci_iomem_register() failed: %d: %s", - result, gxpci_strerror(result)); - return NULL; - } - } - fp = SCMalloc(sizeof(PcieFile)); - if (fp == NULL) { - SCLogError(SC_ERR_PCIE_INIT_FAILED, - "Failed to Allocate memory for PCIe file pointer"); - - return NULL; - } - - /* Sequentially allocate File descriptor numbers. Not currently ever freed */ - fp->fileno = SCAtomicFetchAndAdd(&gxpci_fileno, 1); - PcieWriteOpen(fp, path, append_char); - - return fp; -} - -/** \brief Close a PCIe file - * \param PCIe file desriptor - */ -static void TileClosePcieFp(LogFileCtx *log_ctx) -{ - SCLogInfo("Closing Tile-Gx PCIe: %s", log_ctx->filename); - - /* TODO: Need to count open files and close when reaches zero. */ - SCMutexLock(&pcie_mutex); - - if (gxpci_context) { - gxpci_destroy(gxpci_context); - gxpci_context = NULL; - } - - SCMutexUnlock(&pcie_mutex); - - free(log_ctx->pcie_fp); -} - -/** \brief open the indicated file remotely over PCIe to a host - * \param path filesystem path to open - * \param append_setting open file with O_APPEND: "yes" or "no" - * \retval FILE* on success - * \retval NULL on error - */ -PcieFile *TileOpenPcieFp(LogFileCtx *log_ctx, const char *path, - const char *append_setting) -{ - PcieFile *ret = NULL; - if (strcasecmp(append_setting, "yes") == 0) { - ret = TileOpenPcieFpInternal(path, 'a'); - } else { - ret = TileOpenPcieFpInternal(path, 'w'); - } - - /* Override the default Write and Close functions - * with PCIe Write and Close functions. - */ - log_ctx->Write = TilePcieWrite; - log_ctx->Close = TileClosePcieFp; - - if (ret == NULL) - SCLogError(SC_ERR_FOPEN, "Error opening PCIe file: \"%s\": %s", - path, strerror(errno)); - return ret; -} - -#endif /* __tilegx__ */ |