/* * Init the mm_district subsystem */ int odp_mm_district_init(void) { struct odp_sys_layout *mcfg; const struct odp_mmfrag *mmfrag; unsigned i = 0; /* get pointer to global configuration */ mcfg = odp_get_configuration()->sys_layout; /* mirror the runtime mmfrags from config */ free_mmfrag = mcfg->free_mmfrag; /* secondary processes don't need to initialise anything */ if (odp_process_type() == ODP_PROC_SECONDARY) return 0; mmfrag = odp_get_physmem_layout(); if (!mmfrag) { ODP_ERR("Cannot get physical layout.\n"); return -1; } odp_rwlock_write_lock(&mcfg->mlock); /* fill in uninitialized free_mmfrags */ for (i = 0; i < ODP_MAX_MMFRAG; i++) { if (!mmfrag[i].addr) break; if (free_mmfrag[i].addr) continue; memcpy(&free_mmfrag[i], &mmfrag[i], sizeof(struct odp_mmfrag)); } mcfg->free_frag_idx = i - 1; /* make all fragments cache-aligned */ for (i = 0; i < ODP_MAX_MMFRAG; i++) { if (!free_mmfrag[i].addr) break; if (mmfrag_sanitize(&free_mmfrag[i]) < 0) { ODP_ERR("Sanity check failed\n"); odp_rwlock_write_unlock(&mcfg->mlock); return -1; } } /* delete all fragments */ mcfg->mm_district_idx = 0; memset(mcfg->mm_district, 0, sizeof(mcfg->mm_district)); odp_rwlock_write_unlock(&mcfg->mlock); return 0; }
/* * Return a pointer to a correctly filled mm_district descriptor (with a * specified alignment and boundary). * If the allocation cannot be done, return NULL. */ const struct odp_mm_district *odp_mm_district_reserve_bounded(const char *name, const char *orig_name, size_t len, int socket_id, unsigned flags, unsigned align, unsigned bound) { struct odp_sys_layout *mcfg; const struct odp_mm_district *mz = NULL; /* both sizes cannot be explicitly called for */ if (((flags & ODP_MEMZONE_1GB) && (flags & ODP_MEMZONE_2MB)) || ((flags & ODP_MEMZONE_16MB) && (flags & ODP_MEMZONE_16GB))) { odp_err = EINVAL; return NULL; } /* get pointer to global configuration */ mcfg = odp_get_configuration()->sys_layout; odp_rwlock_write_lock(&mcfg->mlock); mz = mm_district_reserve_aligned( name, orig_name, len, socket_id, flags, align, bound); odp_rwlock_write_unlock(&mcfg->mlock); return mz; }
/* should make sure the input table exists and is available */ int odph_lineartable_put_value(odph_table_t table, void *key, void *value) { odph_linear_table_imp *tbl = (odph_linear_table_imp *)table; uint32_t ikey = 0; void *entry = NULL; odp_rwlock_t *lock = NULL; if (table == NULL || key == NULL || value == NULL) return ODPH_FAIL; ikey = *(uint32_t *)key; if (ikey >= tbl->node_sum) return ODPH_FAIL; entry = (void *)((char *)tbl->value_array + ikey * tbl->value_size); lock = (odp_rwlock_t *)entry; entry = (char *)entry + sizeof(odp_rwlock_t); odp_rwlock_write_lock(lock); memcpy(entry, value, tbl->value_size - sizeof(odp_rwlock_t)); odp_rwlock_write_unlock(lock); return ODPH_SUCCESS; }
/* create the ring */ struct odp_ring *odp_ring_create(const char *name, unsigned count, int socket_id, unsigned flags) { char mz_name[ODP_MEMZONE_NAMESIZE]; struct odp_ring *r; struct odp_tailq_entry *te; const struct odp_mm_district *mz; ssize_t ring_size; int mz_flags = 0; struct odp_ring_list *ring_list = NULL; ring_list = ODP_TAILQ_CAST(odp_ring_tailq.head, odp_ring_list); ring_size = odp_ring_get_memsize(count); if (ring_size < 0) { odp_err = ring_size; return NULL; } te = malloc(sizeof(*te)); if (te == NULL) { ODP_PRINT("Cannot reserve memory for tailq\n"); odp_err = ENOMEM; return NULL; } snprintf(mz_name, sizeof(mz_name), "%s%s", ODP_RING_MZ_PREFIX, name); odp_rwlock_write_lock(ODP_TAILQ_RWLOCK); /* reserve a memory zone for this ring. If we can't get odp_config or * we are secondary process, the mm_district_reserve function will set * odp_err for us appropriately-hence no check in this this function */ mz = odp_mm_district_reserve(mz_name, mz_name, ring_size, socket_id, mz_flags); if (mz != NULL) { r = mz->addr; /* no need to check return value here, we already checked the * arguments above */ odp_ring_init(r, name, count, flags); te->data = (void *)r; TAILQ_INSERT_TAIL(ring_list, te, next); } else { r = NULL; ODP_PRINT("Cannot reserve memory\n"); free(te); } odp_rwlock_write_unlock(ODP_TAILQ_RWLOCK); return r; }
void odp_rwlock_recursive_write_unlock(odp_rwlock_recursive_t *rlock) { rlock->wr_cnt--; if (rlock->wr_cnt > 0) return; rlock->wr_owner = NO_OWNER; odp_rwlock_write_unlock(&rlock->lock); }
void odp_rwlock_recursive_write_unlock(odp_rwlock_recursive_t *rlock) { rlock->wr_cnt--; if (rlock->wr_cnt > 0) return; STORE_S32(rlock->wr_owner, NO_OWNER); odp_rwlock_write_unlock(&rlock->lock); }
const uint32_t odp_mm_district_unreserve(const char *name) { struct odp_sys_layout *mcfg; uint32_t ret; /* get pointer to global configuration */ mcfg = odp_get_configuration()->sys_layout; odp_rwlock_write_lock(&mcfg->mlock); ret = mm_district_unreserve(name); odp_rwlock_write_unlock(&mcfg->mlock); return ret; }