aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosep Puigdemont <josep.puigdemont@linaro.org>2018-09-06 13:06:09 +0200
committerMaxim Uvarov <maxim.uvarov@linaro.org>2018-09-12 17:37:25 +0300
commitc5789c8633254aca7e1d978d1e1f0ad7077e7e2c (patch)
treeeb38cc8e59c7eca8f1d9f6280ec3df5959f896b3
parentc46f54d8c708d6335b0288ff4a5aad3a3b93e41c (diff)
linux-gen: ishm: make huge page cache size dynamic
Signed-off-by: Josep Puigdemont <josep.puigdemont@linaro.org> Reviewed-and-tested-by: Matias Elo <matias.elo@nokia.com> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
-rw-r--r--config/odp-linux-generic.conf16
-rw-r--r--platform/linux-generic/odp_ishm.c73
2 files changed, 56 insertions, 33 deletions
diff --git a/config/odp-linux-generic.conf b/config/odp-linux-generic.conf
index 0dd2a6c13..bddc92dd4 100644
--- a/config/odp-linux-generic.conf
+++ b/config/odp-linux-generic.conf
@@ -18,14 +18,20 @@
odp_implementation = "linux-generic"
config_file_version = "0.0.1"
-# Internal shared memory allocator
+# Shared memory options
shm: {
- # ODP will try to reserve as many huge pages as the number indicated
- # here, up to 64. A zero value means that no pages should be reserved.
+ # Number of cached default size huge pages. These pages are allocated
+ # during odp_init_global() and freed back to the kernel in
+ # odp_term_global(). A value of zero means no pages are cached.
+ # No negative values should be used here, they are reserved for future
+ # implementations.
+ #
+ # ODP will reserve as many huge pages as possible, which may be less
+ # than requested here if the system does not have enough huge pages
+ # available.
+ #
# When using process mode threads, this value should be set to 0
# because the current implementation won't work properly otherwise.
- # These pages will only be freed when the application calls
- # odp_term_global().
num_cached_hp = 0
}
diff --git a/platform/linux-generic/odp_ishm.c b/platform/linux-generic/odp_ishm.c
index 4879b7b25..80423ace3 100644
--- a/platform/linux-generic/odp_ishm.c
+++ b/platform/linux-generic/odp_ishm.c
@@ -239,15 +239,15 @@ typedef struct {
} ishm_ftable_t;
static ishm_ftable_t *ishm_ftbl;
-#define HP_CACHE_SIZE 64
struct huge_page_cache {
uint64_t len;
+ int max_fds; /* maximum amount requested of pre-allocated huge pages */
int total; /* amount of actually pre-allocated huge pages */
int idx; /* retrieve fd[idx] to get a free file descriptor */
- int fd[HP_CACHE_SIZE]; /* list of file descriptors */
+ int fd[]; /* list of file descriptors */
};
-static struct huge_page_cache hpc;
+static struct huge_page_cache *hpc;
#ifndef MAP_ANONYMOUS
#define MAP_ANONYMOUS MAP_ANON
@@ -301,19 +301,14 @@ static void hp_init(void)
char filename[ISHM_FILENAME_MAXLEN];
char dir[ISHM_FILENAME_MAXLEN];
int count;
-
- hpc.total = 0;
- hpc.idx = -1;
- hpc.len = odp_sys_huge_page_size();
+ void *addr;
if (!_odp_libconfig_lookup_ext_int("shm", NULL, "num_cached_hp",
&count)) {
return;
}
- if (count > HP_CACHE_SIZE)
- count = HP_CACHE_SIZE;
- else if (count <= 0)
+ if (count <= 0)
return;
ODP_DBG("Init HP cache with up to %d pages\n", count);
@@ -339,55 +334,77 @@ static void hp_init(void)
dir,
odp_global_data.main_pid);
+ addr = mmap(NULL,
+ sizeof(struct huge_page_cache) + sizeof(int) * count,
+ PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ if (addr == MAP_FAILED) {
+ ODP_ERR("Unable to mmap memory for huge page cache\n.");
+ return;
+ }
+
+ hpc = addr;
+
+ hpc->max_fds = count;
+ hpc->total = 0;
+ hpc->idx = -1;
+ hpc->len = odp_sys_huge_page_size();
+
for (int i = 0; i < count; ++i) {
int fd;
- fd = hp_create_file(hpc.len, filename);
- if (fd == -1)
+ fd = hp_create_file(hpc->len, filename);
+ if (fd == -1) {
+ do {
+ hpc->fd[i++] = -1;
+ } while (i < count);
break;
- hpc.total++;
- hpc.fd[i] = fd;
+ }
+ hpc->total++;
+ hpc->fd[i] = fd;
}
- hpc.idx = hpc.total - 1;
+ hpc->idx = hpc->total - 1;
ODP_DBG("HP cache has %d huge pages of size 0x%08" PRIx64 "\n",
- hpc.total, hpc.len);
+ hpc->total, hpc->len);
}
static void hp_term(void)
{
- for (int i = 0; i < hpc.total; i++) {
- if (hpc.fd[i] != -1)
- close(hpc.fd[i]);
+ if (NULL == hpc)
+ return;
+
+ for (int i = 0; i < hpc->total; i++) {
+ if (hpc->fd[i] != -1)
+ close(hpc->fd[i]);
}
- hpc.total = 0;
- hpc.idx = -1;
- hpc.len = 0;
+ hpc->total = 0;
+ hpc->idx = -1;
+ hpc->len = 0;
}
static int hp_get_cached(uint64_t len)
{
int fd;
- if (hpc.idx < 0 || len != hpc.len)
+ if (NULL == hpc || hpc->idx < 0 || len != hpc->len)
return -1;
- fd = hpc.fd[hpc.idx];
- hpc.fd[hpc.idx--] = -1;
+ fd = hpc->fd[hpc->idx];
+ hpc->fd[hpc->idx--] = -1;
return fd;
}
static int hp_put_cached(int fd)
{
- if (odp_unlikely(++hpc.idx >= hpc.total)) {
- hpc.idx--;
+ if (NULL == hpc || odp_unlikely(++hpc->idx >= hpc->total)) {
+ hpc->idx--;
ODP_ERR("Trying to put more FD than allowed: %d\n", fd);
return -1;
}
- hpc.fd[hpc.idx] = fd;
+ hpc->fd[hpc->idx] = fd;
return 0;
}