[API-NEXT,PATCHv4,01/16] linux-gen: _ishm: create link for external memory sharing

Message ID 1477301053-35938-2-git-send-email-christophe.milard@linaro.org
State New
Headers show

Commit Message

Christophe Milard Oct. 24, 2016, 9:23 a.m.
A new flag called _ODP_ISHM_LINK is added to _ishm. When this flag is
specified at reserve() time, a link ("/tmp/odp-<pid>-shm-<blockname>"
where <pid> is the process ID of the main ODP instatiation process and
<blockname> is the block name given at reserve time) is created, linking
to the underlying block file (either in /tmp or in hugetlbfs).
This link is meant to be used by processes external to ODP willing to
share this memory.

Signed-off-by: Christophe Milard <christophe.milard@linaro.org>

---
 platform/linux-generic/_ishm.c                  | 35 +++++++++++++++++++++++--
 platform/linux-generic/include/_ishm_internal.h |  1 +
 2 files changed, 34 insertions(+), 2 deletions(-)

-- 
2.7.4

Patch

diff --git a/platform/linux-generic/_ishm.c b/platform/linux-generic/_ishm.c
index f4aa6d3..e6ceb24 100644
--- a/platform/linux-generic/_ishm.c
+++ b/platform/linux-generic/_ishm.c
@@ -99,6 +99,14 @@ 
 #define ISHM_FILENAME_NORMAL_PAGE_DIR "/tmp"
 
 /*
+ * when the memory is to be shared with an external entity (such as another
+ * ODP instance or an OS process not part of this ODP instance) then a
+ * link is created to the underlying filename: this defines the location
+ * and the format of this link name
+ */
+#define ISHM_LINKNAME_FORMAT "/tmp/odp-%d-shm-%s"
+
+/*
  * At worse case the virtual space gets so fragmented that there is
  * a unallocated fragment between each allocated fragment:
  * In that case, the number of fragments to take care of is twice the
@@ -136,6 +144,7 @@  typedef struct ishm_fragment {
 typedef struct ishm_block {
 	char name[ISHM_NAME_MAXLEN];    /* name for the ishm block (if any) */
 	char filename[ISHM_FILENAME_MAXLEN]; /* name of the .../odp-* file  */
+	char linkname[ISHM_FILENAME_MAXLEN]; /* name of the /tmp/odp-* link */
 	int  main_odpthread;     /* The thread which did the initial reserve*/
 	uint32_t user_flags;     /* any flags the user want to remember.    */
 	uint32_t flags;          /* block creation flags.                   */
@@ -380,7 +389,7 @@  static void free_fragment(ishm_fragment_t *fragmnt)
  * or /mnt/huge/odp-<pid>-<sequence_or_name> (for huge pages)
  * Return the new file descriptor, or -1 on error.
  */
-static int create_file(int block_index, int huge, uint64_t len)
+static int create_file(int block_index, int huge, uint64_t len, uint32_t flags)
 {
 	char *name;
 	int  fd;
@@ -429,6 +438,21 @@  static int create_file(int block_index, int huge, uint64_t len)
 
 	strncpy(new_block->filename, filename, ISHM_FILENAME_MAXLEN - 1);
 
+	/* if _ODP_ISHM_LINK is set, create a symbolic link for external ref: */
+	if (flags & _ODP_ISHM_LINK) {
+		snprintf(new_block->linkname, ISHM_FILENAME_MAXLEN,
+			 ISHM_LINKNAME_FORMAT,
+			 odp_global_data.main_pid,
+			 (name && name[0]) ? name : seq_string);
+		if (symlink(filename, new_block->linkname) < 0) {
+			ODP_ERR("symlink failed: err=%s.\n",
+				strerror(errno));
+			new_block->linkname[0] = 0;
+		}
+	} else {
+		new_block->linkname[0] = 0;
+	}
+
 	return fd;
 }
 
@@ -456,7 +480,7 @@  static void *do_map(int block_index, uint64_t len, uint32_t align,
 	 * unless a fd was already given
 	 */
 	if (*fd < 0) {
-		*fd = create_file(block_index, huge, len);
+		*fd = create_file(block_index, huge, len, flags);
 		if (*fd < 0)
 			return NULL;
 	} else {
@@ -472,6 +496,8 @@  static void *do_map(int block_index, uint64_t len, uint32_t align,
 				close(*fd);
 				*fd = -1;
 				unlink(new_block->filename);
+				if (new_block->linkname[0])
+					unlink(new_block->linkname);
 			}
 			return NULL;
 		}
@@ -487,6 +513,8 @@  static void *do_map(int block_index, uint64_t len, uint32_t align,
 			close(*fd);
 			*fd = -1;
 			unlink(new_block->filename);
+			if (new_block->linkname[0])
+				unlink(new_block->linkname);
 		}
 		return NULL;
 	}
@@ -870,6 +898,9 @@  static int block_free(int block_index)
 	/* remove the .../odp-* file, unless fd was external: */
 	if (block->filename[0] != 0)
 		unlink(block->filename);
+	/* also remove possible link: */
+	if (block->linkname[0] != 0)
+		unlink(block->linkname);
 
 	/* deregister the file descriptor from the file descriptor server. */
 	_odp_fdserver_deregister_fd(FD_SRV_CTX_ISHM, block_index);
diff --git a/platform/linux-generic/include/_ishm_internal.h b/platform/linux-generic/include/_ishm_internal.h
index 3231b60..4fa6d9c 100644
--- a/platform/linux-generic/include/_ishm_internal.h
+++ b/platform/linux-generic/include/_ishm_internal.h
@@ -14,6 +14,7 @@  extern "C" {
 /* flags available at ishm_reserve: */
 #define _ODP_ISHM_SINGLE_VA		1
 #define _ODP_ISHM_LOCK			2
+#define _ODP_ISHM_LINK			4 /*create soft link in /tmp */
 
 /**
  * Shared memory block info