eal/windows: add missing SPDX license tag
[dpdk.git] / lib / librte_eal / common / eal_common_memory.c
index 194904b..0e99986 100644 (file)
@@ -50,6 +50,8 @@ eal_get_virtual_area(void *requested_addr, size_t *size,
        uint64_t map_sz;
        void *mapped_addr, *aligned_addr;
        uint8_t try = 0;
+       struct internal_config *internal_conf =
+               eal_get_internal_configuration();
 
        if (system_page_sz == 0)
                system_page_sz = rte_mem_page_size();
@@ -60,12 +62,12 @@ eal_get_virtual_area(void *requested_addr, size_t *size,
        allow_shrink = (flags & EAL_VIRTUAL_AREA_ALLOW_SHRINK) > 0;
        unmap = (flags & EAL_VIRTUAL_AREA_UNMAP) > 0;
 
-       if (next_baseaddr == NULL && internal_config.base_virtaddr != 0 &&
+       if (next_baseaddr == NULL && internal_conf->base_virtaddr != 0 &&
                        rte_eal_process_type() == RTE_PROC_PRIMARY)
-               next_baseaddr = (void *) internal_config.base_virtaddr;
+               next_baseaddr = (void *) internal_conf->base_virtaddr;
 
 #ifdef RTE_ARCH_64
-       if (next_baseaddr == NULL && internal_config.base_virtaddr == 0 &&
+       if (next_baseaddr == NULL && internal_conf->base_virtaddr == 0 &&
                        rte_eal_process_type() == RTE_PROC_PRIMARY)
                next_baseaddr = (void *) eal_get_baseaddr();
 #endif
@@ -364,6 +366,8 @@ void *
 rte_mem_iova2virt(rte_iova_t iova)
 {
        struct virtiova vi;
+       const struct internal_config *internal_conf =
+               eal_get_internal_configuration();
 
        memset(&vi, 0, sizeof(vi));
 
@@ -371,7 +375,7 @@ rte_mem_iova2virt(rte_iova_t iova)
        /* for legacy mem, we can get away with scanning VA-contiguous segments,
         * as we know they are PA-contiguous as well
         */
-       if (internal_config.legacy_mem)
+       if (internal_conf->legacy_mem)
                rte_memseg_contig_walk(find_virt_legacy, &vi);
        else
                rte_memseg_walk(find_virt, &vi);
@@ -452,8 +456,11 @@ int
 rte_mem_event_callback_register(const char *name, rte_mem_event_callback_t clb,
                void *arg)
 {
+       const struct internal_config *internal_conf =
+               eal_get_internal_configuration();
+
        /* FreeBSD boots with legacy mem enabled by default */
-       if (internal_config.legacy_mem) {
+       if (internal_conf->legacy_mem) {
                RTE_LOG(DEBUG, EAL, "Registering mem event callbacks not supported\n");
                rte_errno = ENOTSUP;
                return -1;
@@ -464,8 +471,11 @@ rte_mem_event_callback_register(const char *name, rte_mem_event_callback_t clb,
 int
 rte_mem_event_callback_unregister(const char *name, void *arg)
 {
+       const struct internal_config *internal_conf =
+               eal_get_internal_configuration();
+
        /* FreeBSD boots with legacy mem enabled by default */
-       if (internal_config.legacy_mem) {
+       if (internal_conf->legacy_mem) {
                RTE_LOG(DEBUG, EAL, "Registering mem event callbacks not supported\n");
                rte_errno = ENOTSUP;
                return -1;
@@ -477,8 +487,11 @@ int
 rte_mem_alloc_validator_register(const char *name,
                rte_mem_alloc_validator_t clb, int socket_id, size_t limit)
 {
+       const struct internal_config *internal_conf =
+               eal_get_internal_configuration();
+
        /* FreeBSD boots with legacy mem enabled by default */
-       if (internal_config.legacy_mem) {
+       if (internal_conf->legacy_mem) {
                RTE_LOG(DEBUG, EAL, "Registering mem alloc validators not supported\n");
                rte_errno = ENOTSUP;
                return -1;
@@ -490,8 +503,11 @@ rte_mem_alloc_validator_register(const char *name,
 int
 rte_mem_alloc_validator_unregister(const char *name, int socket_id)
 {
+       const struct internal_config *internal_conf =
+               eal_get_internal_configuration();
+
        /* FreeBSD boots with legacy mem enabled by default */
-       if (internal_config.legacy_mem) {
+       if (internal_conf->legacy_mem) {
                RTE_LOG(DEBUG, EAL, "Registering mem alloc validators not supported\n");
                rte_errno = ENOTSUP;
                return -1;
@@ -613,13 +629,15 @@ static int
 rte_eal_memdevice_init(void)
 {
        struct rte_config *config;
+       const struct internal_config *internal_conf;
 
        if (rte_eal_process_type() == RTE_PROC_SECONDARY)
                return 0;
 
+       internal_conf = eal_get_internal_configuration();
        config = rte_eal_get_configuration();
-       config->mem_config->nchannel = internal_config.force_nchannel;
-       config->mem_config->nrank = internal_config.force_nrank;
+       config->mem_config->nchannel = internal_conf->force_nchannel;
+       config->mem_config->nrank = internal_conf->force_nrank;
 
        return 0;
 }
@@ -984,11 +1002,68 @@ rte_extmem_detach(void *va_addr, size_t len)
        return sync_memory(va_addr, len, false);
 }
 
+/* detach all EAL memory */
+int
+rte_eal_memory_detach(void)
+{
+       struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+       size_t page_sz = rte_mem_page_size();
+       unsigned int i;
+
+       rte_rwlock_write_lock(&mcfg->memory_hotplug_lock);
+
+       /* detach internal memory subsystem data first */
+       if (eal_memalloc_cleanup())
+               RTE_LOG(ERR, EAL, "Could not release memory subsystem data\n");
+
+       for (i = 0; i < RTE_DIM(mcfg->memsegs); i++) {
+               struct rte_memseg_list *msl = &mcfg->memsegs[i];
+
+               /* skip uninitialized segments */
+               if (msl->base_va == NULL)
+                       continue;
+               /*
+                * external segments are supposed to be detached at this point,
+                * but if they aren't, we can't really do anything about it,
+                * because if we skip them here, they'll become invalid after
+                * we unmap the memconfig anyway. however, if this is externally
+                * referenced memory, we have no business unmapping it.
+                */
+               if (!msl->external)
+                       if (rte_mem_unmap(msl->base_va, msl->len) != 0)
+                               RTE_LOG(ERR, EAL, "Could not unmap memory: %s\n",
+                                               strerror(errno));
+
+               /*
+                * we are detaching the fbarray rather than destroying because
+                * other processes might still reference this fbarray, and we
+                * have no way of knowing if they still do.
+                */
+               if (rte_fbarray_detach(&msl->memseg_arr))
+                       RTE_LOG(ERR, EAL, "Could not detach fbarray: %s\n",
+                                       rte_strerror(rte_errno));
+       }
+       rte_rwlock_write_unlock(&mcfg->memory_hotplug_lock);
+
+       /*
+        * we've detached the memseg lists, so we can unmap the shared mem
+        * config - we can't zero it out because it might still be referenced
+        * by other processes.
+        */
+       rte_mem_unmap(mcfg, RTE_ALIGN(sizeof(*mcfg), page_sz));
+       rte_eal_get_configuration()->mem_config = NULL;
+
+       return 0;
+}
+
 /* init memory subsystem */
 int
 rte_eal_memory_init(void)
 {
        struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+       const struct internal_config *internal_conf =
+               eal_get_internal_configuration();
+
        int retval;
        RTE_LOG(DEBUG, EAL, "Setting up physically contiguous memory...\n");
 
@@ -1010,7 +1085,7 @@ rte_eal_memory_init(void)
        if (retval < 0)
                goto fail;
 
-       if (internal_config.no_shconf == 0 && rte_eal_memdevice_init() < 0)
+       if (internal_conf->no_shconf == 0 && rte_eal_memdevice_init() < 0)
                goto fail;
 
        return 0;