diff options
Diffstat (limited to 'lib/librte_ivshmem/rte_ivshmem.c')
-rw-r--r-- | lib/librte_ivshmem/rte_ivshmem.c | 919 |
1 files changed, 0 insertions, 919 deletions
diff --git a/lib/librte_ivshmem/rte_ivshmem.c b/lib/librte_ivshmem/rte_ivshmem.c deleted file mode 100644 index c26edb61..00000000 --- a/lib/librte_ivshmem/rte_ivshmem.c +++ /dev/null @@ -1,919 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 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 - * OWNER 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. - */ -#include <fcntl.h> -#include <limits.h> -#include <unistd.h> -#include <sys/mman.h> -#include <string.h> -#include <stdio.h> - -#include <rte_eal_memconfig.h> -#include <rte_memory.h> -#include <rte_ivshmem.h> -#include <rte_string_fns.h> -#include <rte_common.h> -#include <rte_log.h> -#include <rte_debug.h> -#include <rte_spinlock.h> -#include <rte_common.h> -#include <rte_malloc.h> - -#include "rte_ivshmem.h" - -#define IVSHMEM_CONFIG_FILE_FMT "/var/run/.dpdk_ivshmem_metadata_%s" -#define IVSHMEM_QEMU_CMD_LINE_HEADER_FMT "-device ivshmem,size=%" PRIu64 "M,shm=fd%s" -#define IVSHMEM_QEMU_CMD_FD_FMT ":%s:0x%" PRIx64 ":0x%" PRIx64 -#define IVSHMEM_QEMU_CMDLINE_BUFSIZE 1024 -#define IVSHMEM_MAX_PAGES (1 << 12) -#define adjacent(x,y) (((x).phys_addr+(x).len)==(y).phys_addr) -#define METADATA_SIZE_ALIGNED \ - (RTE_ALIGN_CEIL(sizeof(struct rte_ivshmem_metadata),pagesz)) - -#define GET_PAGEMAP_ADDR(in,addr,dlm,err) \ -{ \ - char *end; \ - errno = 0; \ - addr = strtoull((in), &end, 16); \ - if (errno != 0 || *end != (dlm)) { \ - RTE_LOG(ERR, EAL, err); \ - goto error; \ - } \ - (in) = end + 1; \ -} - -static int pagesz; - -struct memseg_cache_entry { - char filepath[PATH_MAX]; - uint64_t offset; - uint64_t len; -}; - -struct ivshmem_config { - struct rte_ivshmem_metadata * metadata; - struct memseg_cache_entry memseg_cache[IVSHMEM_MAX_PAGES]; - /**< account for multiple files per segment case */ - struct flock lock; - rte_spinlock_t sl; -}; - -static struct ivshmem_config -ivshmem_global_config[RTE_LIBRTE_IVSHMEM_MAX_METADATA_FILES]; - -static rte_spinlock_t global_cfg_sl; - -static struct ivshmem_config * -get_config_by_name(const char * name) -{ - struct rte_ivshmem_metadata * config; - unsigned i; - - for (i = 0; i < RTE_DIM(ivshmem_global_config); i++) { - config = ivshmem_global_config[i].metadata; - if (config == NULL) - return NULL; - if (strncmp(name, config->name, IVSHMEM_NAME_LEN) == 0) - return &ivshmem_global_config[i]; - } - - return NULL; -} - -static int -overlap(const struct rte_memzone * s1, const struct rte_memzone * s2) -{ - uint64_t start1, end1, start2, end2; - - start1 = s1->addr_64; - end1 = s1->addr_64 + s1->len; - start2 = s2->addr_64; - end2 = s2->addr_64 + s2->len; - - if (start1 >= start2 && start1 < end2) - return 1; - if (start2 >= start1 && start2 < end1) - return 1; - - return 0; -} - -static struct rte_memzone * -get_memzone_by_addr(const void * addr) -{ - struct rte_memzone * tmp, * mz; - struct rte_mem_config * mcfg; - int i; - - mcfg = rte_eal_get_configuration()->mem_config; - mz = NULL; - - /* find memzone for the ring */ - for (i = 0; i < RTE_MAX_MEMZONE; i++) { - tmp = &mcfg->memzone[i]; - - if (tmp->addr_64 == (uint64_t) addr) { - mz = tmp; - break; - } - } - - return mz; -} - -static int -entry_compare(const void * a, const void * b) -{ - const struct rte_ivshmem_metadata_entry * e1 = - (const struct rte_ivshmem_metadata_entry*) a; - const struct rte_ivshmem_metadata_entry * e2 = - (const struct rte_ivshmem_metadata_entry*) b; - - /* move unallocated zones to the end */ - if (e1->mz.addr == NULL && e2->mz.addr == NULL) - return 0; - if (e1->mz.addr == 0) - return 1; - if (e2->mz.addr == 0) - return -1; - - return e1->mz.phys_addr > e2->mz.phys_addr; -} - -/* fills hugepage cache entry for a given start virt_addr */ -static int -get_hugefile_by_virt_addr(uint64_t virt_addr, struct memseg_cache_entry * e) -{ - uint64_t start_addr, end_addr; - char *start,*path_end; - char buf[PATH_MAX*2]; - FILE *f; - - start = NULL; - path_end = NULL; - start_addr = 0; - - memset(e->filepath, 0, sizeof(e->filepath)); - - /* open /proc/self/maps */ - f = fopen("/proc/self/maps", "r"); - if (f == NULL) { - RTE_LOG(ERR, EAL, "cannot open /proc/self/maps!\n"); - return -1; - } - - /* parse maps */ - while (fgets(buf, sizeof(buf), f) != NULL) { - - /* get endptr to end of start addr */ - start = buf; - - GET_PAGEMAP_ADDR(start,start_addr,'-', - "Cannot find start address in maps!\n"); - - /* if start address is bigger than our address, skip */ - if (start_addr > virt_addr) - continue; - - GET_PAGEMAP_ADDR(start,end_addr,' ', - "Cannot find end address in maps!\n"); - - /* if end address is less than our address, skip */ - if (end_addr <= virt_addr) - continue; - - /* find where the path starts */ - start = strstr(start, "/"); - - if (start == NULL) - continue; - - /* at this point, we know that this is our map. - * now let's find the file */ - path_end = strstr(start, "\n"); - break; - } - - if (path_end == NULL) { - RTE_LOG(ERR, EAL, "Hugefile path not found!\n"); - goto error; - } - - /* calculate offset and copy the file path */ - snprintf(e->filepath, RTE_PTR_DIFF(path_end, start) + 1, "%s", start); - - e->offset = virt_addr - start_addr; - - fclose(f); - - return 0; -error: - fclose(f); - return -1; -} - -/* - * This is a complex function. What it does is the following: - * 1. Goes through metadata and gets list of hugepages involved - * 2. Sorts the hugepages by size (1G first) - * 3. Goes through metadata again and writes correct offsets - * 4. Goes through pages and finds out their filenames, offsets etc. - */ -static int -build_config(struct rte_ivshmem_metadata * metadata) -{ - struct rte_ivshmem_metadata_entry * e_local; - struct memseg_cache_entry * ms_local; - struct rte_memseg pages[IVSHMEM_MAX_PAGES]; - struct rte_ivshmem_metadata_entry *entry; - struct memseg_cache_entry * c_entry, * prev_entry; - struct ivshmem_config * config; - unsigned i, j, mz_iter, ms_iter; - uint64_t biggest_len; - int biggest_idx; - - /* return error if we try to use an unknown config file */ - config = get_config_by_name(metadata->name); - if (config == NULL) { - RTE_LOG(ERR, EAL, "Cannot find IVSHMEM config %s!\n", metadata->name); - goto fail_e; - } - - memset(pages, 0, sizeof(pages)); - - e_local = malloc(sizeof(config->metadata->entry)); - if (e_local == NULL) - goto fail_e; - ms_local = malloc(sizeof(config->memseg_cache)); - if (ms_local == NULL) - goto fail_ms; - - - /* make local copies before doing anything */ - memcpy(e_local, config->metadata->entry, sizeof(config->metadata->entry)); - memcpy(ms_local, config->memseg_cache, sizeof(config->memseg_cache)); - - qsort(e_local, RTE_DIM(config->metadata->entry), sizeof(struct rte_ivshmem_metadata_entry), - entry_compare); - - /* first pass - collect all huge pages */ - for (mz_iter = 0; mz_iter < RTE_DIM(config->metadata->entry); mz_iter++) { - - entry = &e_local[mz_iter]; - - uint64_t start_addr = RTE_ALIGN_FLOOR(entry->mz.addr_64, - entry->mz.hugepage_sz); - uint64_t offset = entry->mz.addr_64 - start_addr; - uint64_t len = RTE_ALIGN_CEIL(entry->mz.len + offset, - entry->mz.hugepage_sz); - - if (entry->mz.addr_64 == 0 || start_addr == 0 || len == 0) - continue; - - int start_page; - - /* find first unused page - mz are phys_addr sorted so we don't have to - * look out for holes */ - for (i = 0; i < RTE_DIM(pages); i++) { - - /* skip if we already have this page */ - if (pages[i].addr_64 == start_addr) { - start_addr += entry->mz.hugepage_sz; - len -= entry->mz.hugepage_sz; - continue; - } - /* we found a new page */ - else if (pages[i].addr_64 == 0) { - start_page = i; - break; - } - } - if (i == RTE_DIM(pages)) { - RTE_LOG(ERR, EAL, "Cannot find unused page!\n"); - goto fail; - } - - /* populate however many pages the memzone has */ - for (i = start_page; i < RTE_DIM(pages) && len != 0; i++) { - - pages[i].addr_64 = start_addr; - pages[i].len = entry->mz.hugepage_sz; - start_addr += entry->mz.hugepage_sz; - len -= entry->mz.hugepage_sz; - } - /* if there's still length left */ - if (len != 0) { - RTE_LOG(ERR, EAL, "Not enough space for pages!\n"); - goto fail; - } - } - - /* second pass - sort pages by size */ - for (i = 0; i < RTE_DIM(pages); i++) { - - if (pages[i].addr == NULL) - break; - - biggest_len = 0; - biggest_idx = -1; - - /* - * browse all entries starting at 'i', and find the - * entry with the smallest addr - */ - for (j=i; j< RTE_DIM(pages); j++) { - if (pages[j].addr == NULL) - break; - if (biggest_len == 0 || - pages[j].len > biggest_len) { - biggest_len = pages[j].len; - biggest_idx = j; - } - } - - /* should not happen */ - if (biggest_idx == -1) { - RTE_LOG(ERR, EAL, "Error sorting by size!\n"); - goto fail; - } - if (i != (unsigned) biggest_idx) { - struct rte_memseg tmp; - - memcpy(&tmp, &pages[biggest_idx], sizeof(struct rte_memseg)); - - /* we don't want to break contiguousness, so instead of just - * swapping segments, we move all the preceding segments to the - * right and then put the old segment @ biggest_idx in place of - * segment @ i */ - for (j = biggest_idx - 1; j >= i; j--) { - memcpy(&pages[j+1], &pages[j], sizeof(struct rte_memseg)); - memset(&pages[j], 0, sizeof(struct rte_memseg)); - if (j == 0) - break; - } - - /* put old biggest segment to its new place */ - memcpy(&pages[i], &tmp, sizeof(struct rte_memseg)); - } - } - - /* third pass - write correct offsets */ - for (mz_iter = 0; mz_iter < RTE_DIM(config->metadata->entry); mz_iter++) { - - uint64_t offset = 0; - - entry = &e_local[mz_iter]; - - if (entry->mz.addr_64 == 0) - break; - - /* find page for current memzone */ - for (i = 0; i < RTE_DIM(pages); i++) { - /* we found our page */ - if (entry->mz.addr_64 >= pages[i].addr_64 && - entry->mz.addr_64 < pages[i].addr_64 + pages[i].len) { - entry->offset = (entry->mz.addr_64 - pages[i].addr_64) + - offset; - break; - } - offset += pages[i].len; - } - if (i == RTE_DIM(pages)) { - RTE_LOG(ERR, EAL, "Page not found!\n"); - goto fail; - } - } - - ms_iter = 0; - prev_entry = NULL; - - /* fourth pass - create proper memseg cache */ - for (i = 0; i < RTE_DIM(pages) && - ms_iter <= RTE_DIM(config->memseg_cache); i++) { - if (pages[i].addr_64 == 0) - break; - - - if (ms_iter == RTE_DIM(pages)) { - RTE_LOG(ERR, EAL, "The universe has collapsed!\n"); - goto fail; - } - - c_entry = &ms_local[ms_iter]; - c_entry->len = pages[i].len; - - if (get_hugefile_by_virt_addr(pages[i].addr_64, c_entry) < 0) - goto fail; - - /* if previous entry has the same filename and is contiguous, - * clear current entry and increase previous entry's length - */ - if (prev_entry != NULL && - strncmp(c_entry->filepath, prev_entry->filepath, - sizeof(c_entry->filepath)) == 0 && - prev_entry->offset + prev_entry->len == c_entry->offset) { - prev_entry->len += pages[i].len; - memset(c_entry, 0, sizeof(struct memseg_cache_entry)); - } - else { - prev_entry = c_entry; - ms_iter++; - } - } - - /* update current configuration with new valid data */ - memcpy(config->metadata->entry, e_local, sizeof(config->metadata->entry)); - memcpy(config->memseg_cache, ms_local, sizeof(config->memseg_cache)); - - free(ms_local); - free(e_local); - - return 0; -fail: - free(ms_local); -fail_ms: - free(e_local); -fail_e: - return -1; -} - -static int -add_memzone_to_metadata(const struct rte_memzone * mz, - struct ivshmem_config * config) -{ - struct rte_ivshmem_metadata_entry * entry; - unsigned i, idx; - struct rte_mem_config *mcfg; - - if (mz->len == 0) { - RTE_LOG(ERR, EAL, "Trying to add an empty memzone\n"); - return -1; - } - - rte_spinlock_lock(&config->sl); - - mcfg = rte_eal_get_configuration()->mem_config; - - /* it prevents the memzone being freed while we add it to the metadata */ - rte_rwlock_write_lock(&mcfg->mlock); - - /* find free slot in this config */ - for (i = 0; i < RTE_DIM(config->metadata->entry); i++) { - entry = &config->metadata->entry[i]; - - if (&entry->mz.addr_64 != 0 && overlap(mz, &entry->mz)) { - RTE_LOG(ERR, EAL, "Overlapping memzones!\n"); - goto fail; - } - - /* if addr is zero, the memzone is probably free */ - if (entry->mz.addr_64 == 0) { - RTE_LOG(DEBUG, EAL, "Adding memzone '%s' at %p to metadata %s\n", - mz->name, mz->addr, config->metadata->name); - memcpy(&entry->mz, mz, sizeof(struct rte_memzone)); - - /* run config file parser */ - if (build_config(config->metadata) < 0) - goto fail; - - break; - } - } - - /* if we reached the maximum, that means we have no place in config */ - if (i == RTE_DIM(config->metadata->entry)) { - RTE_LOG(ERR, EAL, "No space left in IVSHMEM metadata %s!\n", - config->metadata->name); - goto fail; - } - - idx = ((uintptr_t)mz - (uintptr_t)mcfg->memzone); - idx = idx / sizeof(struct rte_memzone); - - /* mark the memzone not freeable */ - mcfg->memzone[idx].ioremap_addr = mz->phys_addr; - - rte_rwlock_write_unlock(&mcfg->mlock); - rte_spinlock_unlock(&config->sl); - return 0; -fail: - rte_rwlock_write_unlock(&mcfg->mlock); - rte_spinlock_unlock(&config->sl); - return -1; -} - -static int -add_ring_to_metadata(const struct rte_ring * r, - struct ivshmem_config * config) -{ - struct rte_memzone * mz; - - mz = get_memzone_by_addr(r); - - if (!mz) { - RTE_LOG(ERR, EAL, "Cannot find memzone for ring!\n"); - return -1; - } - - return add_memzone_to_metadata(mz, config); -} - -static int -add_mempool_memzone_to_metadata(const void *addr, - struct ivshmem_config *config) -{ - struct rte_memzone *mz; - - mz = get_memzone_by_addr(addr); - - if (!mz) { - RTE_LOG(ERR, EAL, "Cannot find memzone for mempool!\n"); - return -1; - } - - return add_memzone_to_metadata(mz, config); -} - -static int -add_mempool_to_metadata(const struct rte_mempool *mp, - struct ivshmem_config *config) -{ - struct rte_mempool_memhdr *memhdr; - int ret; - - ret = add_mempool_memzone_to_metadata(mp, config); - if (ret < 0) - return -1; - - STAILQ_FOREACH(memhdr, &mp->mem_list, next) { - ret = add_mempool_memzone_to_metadata(memhdr->addr, config); - if (ret < 0) - return -1; - } - - /* mempool consists of memzone and ring */ - return add_ring_to_metadata(mp->pool_data, config); -} - -int -rte_ivshmem_metadata_add_ring(const struct rte_ring * r, const char * name) -{ - struct ivshmem_config * config; - - if (name == NULL || r == NULL) - return -1; - - config = get_config_by_name(name); - - if (config == NULL) { - RTE_LOG(ERR, EAL, "Cannot find IVSHMEM config %s!\n", name); - return -1; - } - - return add_ring_to_metadata(r, config); -} - -int -rte_ivshmem_metadata_add_memzone(const struct rte_memzone * mz, const char * name) -{ - struct ivshmem_config * config; - - if (name == NULL || mz == NULL) - return -1; - - config = get_config_by_name(name); - - if (config == NULL) { - RTE_LOG(ERR, EAL, "Cannot find IVSHMEM config %s!\n", name); - return -1; - } - - return add_memzone_to_metadata(mz, config); -} - -int -rte_ivshmem_metadata_add_mempool(const struct rte_mempool * mp, const char * name) -{ - struct ivshmem_config * config; - - if (name == NULL || mp == NULL) - return -1; - - config = get_config_by_name(name); - - if (config == NULL) { - RTE_LOG(ERR, EAL, "Cannot find IVSHMEM config %s!\n", name); - return -1; - } - - return add_mempool_to_metadata(mp, config); -} - -static inline void -ivshmem_config_path(char *buffer, size_t bufflen, const char *name) -{ - snprintf(buffer, bufflen, IVSHMEM_CONFIG_FILE_FMT, name); -} - - - -static inline -void *ivshmem_metadata_create(const char *name, size_t size, - struct flock *lock) -{ - int retval, fd; - void *metadata_addr; - char pathname[PATH_MAX]; - - ivshmem_config_path(pathname, sizeof(pathname), name); - - fd = open(pathname, O_RDWR | O_CREAT, 0660); - if (fd < 0) { - RTE_LOG(ERR, EAL, "Cannot open '%s'\n", pathname); - return NULL; - } - - size = METADATA_SIZE_ALIGNED; - - retval = fcntl(fd, F_SETLK, lock); - if (retval < 0){ - close(fd); - RTE_LOG(ERR, EAL, "Cannot create lock on '%s'. Is another " - "process using it?\n", pathname); - return NULL; - } - - retval = ftruncate(fd, size); - if (retval < 0){ - close(fd); - RTE_LOG(ERR, EAL, "Cannot resize '%s'\n", pathname); - return NULL; - } - - metadata_addr = mmap(NULL, size, - PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - - if (metadata_addr == MAP_FAILED){ - RTE_LOG(ERR, EAL, "Cannot mmap memory for '%s'\n", pathname); - - /* we don't care if we can't unlock */ - fcntl(fd, F_UNLCK, lock); - close(fd); - - return NULL; - } - - return metadata_addr; -} - -int rte_ivshmem_metadata_create(const char *name) -{ - struct ivshmem_config * ivshmem_config; - unsigned index; - - if (pagesz == 0) - pagesz = getpagesize(); - - if (name == NULL) - return -1; - - rte_spinlock_lock(&global_cfg_sl); - - for (index = 0; index < RTE_DIM(ivshmem_global_config); index++) { - if (ivshmem_global_config[index].metadata == NULL) { - ivshmem_config = &ivshmem_global_config[index]; - break; - } - } - - if (index == RTE_DIM(ivshmem_global_config)) { - RTE_LOG(ERR, EAL, "Cannot create more ivshmem config files. " - "Maximum has been reached\n"); - rte_spinlock_unlock(&global_cfg_sl); - return -1; - } - - ivshmem_config->lock.l_type = F_WRLCK; - ivshmem_config->lock.l_whence = SEEK_SET; - - ivshmem_config->lock.l_start = 0; - ivshmem_config->lock.l_len = METADATA_SIZE_ALIGNED; - - ivshmem_global_config[index].metadata = ((struct rte_ivshmem_metadata *) - ivshmem_metadata_create( - name, - sizeof(struct rte_ivshmem_metadata), - &ivshmem_config->lock)); - - if (ivshmem_global_config[index].metadata == NULL) { - rte_spinlock_unlock(&global_cfg_sl); - return -1; - } - - /* Metadata setup */ - memset(ivshmem_config->metadata, 0, sizeof(struct rte_ivshmem_metadata)); - ivshmem_config->metadata->magic_number = IVSHMEM_MAGIC; - snprintf(ivshmem_config->metadata->name, - sizeof(ivshmem_config->metadata->name), "%s", name); - - rte_spinlock_unlock(&global_cfg_sl); - - return 0; -} - -int -rte_ivshmem_metadata_cmdline_generate(char *buffer, unsigned size, const char *name) -{ - const struct memseg_cache_entry * ms_cache, *entry; - struct ivshmem_config * config; - char cmdline[IVSHMEM_QEMU_CMDLINE_BUFSIZE], *cmdline_ptr; - char cfg_file_path[PATH_MAX]; - unsigned remaining_len, tmplen, iter; - uint64_t shared_mem_size, zero_size, total_size; - - if (buffer == NULL || name == NULL) - return -1; - - config = get_config_by_name(name); - - if (config == NULL) { - RTE_LOG(ERR, EAL, "Config %s not found!\n", name); - return -1; - } - - rte_spinlock_lock(&config->sl); - - /* prepare metadata file path */ - snprintf(cfg_file_path, sizeof(cfg_file_path), IVSHMEM_CONFIG_FILE_FMT, - config->metadata->name); - - ms_cache = config->memseg_cache; - - cmdline_ptr = cmdline; - remaining_len = sizeof(cmdline); - - shared_mem_size = 0; - iter = 0; - - while ((ms_cache[iter].len != 0) && (iter < RTE_DIM(config->metadata->entry))) { - - entry = &ms_cache[iter]; - - /* Offset and sizes within the current pathname */ - tmplen = snprintf(cmdline_ptr, remaining_len, IVSHMEM_QEMU_CMD_FD_FMT, - entry->filepath, entry->offset, entry->len); - - shared_mem_size += entry->len; - - cmdline_ptr = RTE_PTR_ADD(cmdline_ptr, tmplen); - remaining_len -= tmplen; - - if (remaining_len == 0) { - RTE_LOG(ERR, EAL, "Command line too long!\n"); - rte_spinlock_unlock(&config->sl); - return -1; - } - - iter++; - } - - total_size = rte_align64pow2(shared_mem_size + METADATA_SIZE_ALIGNED); - zero_size = total_size - shared_mem_size - METADATA_SIZE_ALIGNED; - - /* add /dev/zero to command-line to fill the space */ - tmplen = snprintf(cmdline_ptr, remaining_len, IVSHMEM_QEMU_CMD_FD_FMT, - "/dev/zero", - (uint64_t)0x0, - zero_size); - - cmdline_ptr = RTE_PTR_ADD(cmdline_ptr, tmplen); - remaining_len -= tmplen; - - if (remaining_len == 0) { - RTE_LOG(ERR, EAL, "Command line too long!\n"); - rte_spinlock_unlock(&config->sl); - return -1; - } - - /* add metadata file to the end of command-line */ - tmplen = snprintf(cmdline_ptr, remaining_len, IVSHMEM_QEMU_CMD_FD_FMT, - cfg_file_path, - (uint64_t)0x0, - METADATA_SIZE_ALIGNED); - - cmdline_ptr = RTE_PTR_ADD(cmdline_ptr, tmplen); - remaining_len -= tmplen; - - if (remaining_len == 0) { - RTE_LOG(ERR, EAL, "Command line too long!\n"); - rte_spinlock_unlock(&config->sl); - return -1; - } - - /* if current length of the command line is bigger than the buffer supplied - * by the user, or if command-line is bigger than what IVSHMEM accepts */ - if ((sizeof(cmdline) - remaining_len) > size) { - RTE_LOG(ERR, EAL, "Buffer is too short!\n"); - rte_spinlock_unlock(&config->sl); - return -1; - } - /* complete the command-line */ - snprintf(buffer, size, - IVSHMEM_QEMU_CMD_LINE_HEADER_FMT, - total_size >> 20, - cmdline); - - rte_spinlock_unlock(&config->sl); - - return 0; -} - -void -rte_ivshmem_metadata_dump(FILE *f, const char *name) -{ - unsigned i = 0; - struct ivshmem_config * config; - struct rte_ivshmem_metadata_entry *entry; -#ifdef RTE_LIBRTE_IVSHMEM_DEBUG - uint64_t addr; - uint64_t end, hugepage_sz; - struct memseg_cache_entry e; -#endif - - if (name == NULL) - return; - - /* return error if we try to use an unknown config file */ - config = get_config_by_name(name); - if (config == NULL) { - RTE_LOG(ERR, EAL, "Cannot find IVSHMEM config %s!\n", name); - return; - } - - rte_spinlock_lock(&config->sl); - - entry = &config->metadata->entry[0]; - - while (entry->mz.addr != NULL && i < RTE_DIM(config->metadata->entry)) { - - fprintf(f, "Entry %u: name:<%-20s>, phys:0x%-15lx, len:0x%-15lx, " - "virt:%-15p, off:0x%-15lx\n", - i, - entry->mz.name, - entry->mz.phys_addr, - entry->mz.len, - entry->mz.addr, - entry->offset); - i++; - -#ifdef RTE_LIBRTE_IVSHMEM_DEBUG - fprintf(f, "\tHugepage files:\n"); - - hugepage_sz = entry->mz.hugepage_sz; - addr = RTE_ALIGN_FLOOR(entry->mz.addr_64, hugepage_sz); - end = addr + RTE_ALIGN_CEIL(entry->mz.len + (entry->mz.addr_64 - addr), - hugepage_sz); - - for (; addr < end; addr += hugepage_sz) { - memset(&e, 0, sizeof(e)); - - get_hugefile_by_virt_addr(addr, &e); - - fprintf(f, "\t0x%"PRIx64 "-0x%" PRIx64 " offset: 0x%" PRIx64 " %s\n", - addr, addr + hugepage_sz, e.offset, e.filepath); - } -#endif - entry++; - } - - rte_spinlock_unlock(&config->sl); -} |