xref: /dpdk/lib/eal/common/eal_common_memalloc.c (revision ae67895b507bb6af22263c79ba0d5c374b396485)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright(c) 2017-2018 Intel Corporation
399a2dd95SBruce Richardson  */
499a2dd95SBruce Richardson 
572b452c5SDmitry Kozlyuk #include <stdlib.h>
699a2dd95SBruce Richardson #include <string.h>
799a2dd95SBruce Richardson 
899a2dd95SBruce Richardson #include <rte_errno.h>
999a2dd95SBruce Richardson #include <rte_fbarray.h>
1099a2dd95SBruce Richardson #include <rte_memory.h>
1199a2dd95SBruce Richardson #include <rte_string_fns.h>
1299a2dd95SBruce Richardson 
1399a2dd95SBruce Richardson #include "eal_private.h"
1499a2dd95SBruce Richardson #include "eal_internal_cfg.h"
1599a2dd95SBruce Richardson #include "eal_memalloc.h"
1699a2dd95SBruce Richardson 
1799a2dd95SBruce Richardson struct mem_event_callback_entry {
1899a2dd95SBruce Richardson 	TAILQ_ENTRY(mem_event_callback_entry) next;
1999a2dd95SBruce Richardson 	char name[RTE_MEM_EVENT_CALLBACK_NAME_LEN];
2099a2dd95SBruce Richardson 	rte_mem_event_callback_t clb;
2199a2dd95SBruce Richardson 	void *arg;
2299a2dd95SBruce Richardson };
2399a2dd95SBruce Richardson 
2499a2dd95SBruce Richardson struct mem_alloc_validator_entry {
2599a2dd95SBruce Richardson 	TAILQ_ENTRY(mem_alloc_validator_entry) next;
2699a2dd95SBruce Richardson 	char name[RTE_MEM_ALLOC_VALIDATOR_NAME_LEN];
2799a2dd95SBruce Richardson 	rte_mem_alloc_validator_t clb;
2899a2dd95SBruce Richardson 	int socket_id;
2999a2dd95SBruce Richardson 	size_t limit;
3099a2dd95SBruce Richardson };
3199a2dd95SBruce Richardson 
3299a2dd95SBruce Richardson /** Double linked list of actions. */
3399a2dd95SBruce Richardson TAILQ_HEAD(mem_event_callback_entry_list, mem_event_callback_entry);
3499a2dd95SBruce Richardson TAILQ_HEAD(mem_alloc_validator_entry_list, mem_alloc_validator_entry);
3599a2dd95SBruce Richardson 
3699a2dd95SBruce Richardson static struct mem_event_callback_entry_list mem_event_callback_list =
3799a2dd95SBruce Richardson 	TAILQ_HEAD_INITIALIZER(mem_event_callback_list);
3899a2dd95SBruce Richardson static rte_rwlock_t mem_event_rwlock = RTE_RWLOCK_INITIALIZER;
3999a2dd95SBruce Richardson 
4099a2dd95SBruce Richardson static struct mem_alloc_validator_entry_list mem_alloc_validator_list =
4199a2dd95SBruce Richardson 	TAILQ_HEAD_INITIALIZER(mem_alloc_validator_list);
4299a2dd95SBruce Richardson static rte_rwlock_t mem_alloc_validator_rwlock = RTE_RWLOCK_INITIALIZER;
4399a2dd95SBruce Richardson 
4499a2dd95SBruce Richardson static struct mem_event_callback_entry *
find_mem_event_callback(const char * name,void * arg)4599a2dd95SBruce Richardson find_mem_event_callback(const char *name, void *arg)
4699a2dd95SBruce Richardson {
4799a2dd95SBruce Richardson 	struct mem_event_callback_entry *r;
4899a2dd95SBruce Richardson 
4999a2dd95SBruce Richardson 	TAILQ_FOREACH(r, &mem_event_callback_list, next) {
5099a2dd95SBruce Richardson 		if (!strcmp(r->name, name) && r->arg == arg)
5199a2dd95SBruce Richardson 			break;
5299a2dd95SBruce Richardson 	}
5399a2dd95SBruce Richardson 	return r;
5499a2dd95SBruce Richardson }
5599a2dd95SBruce Richardson 
5699a2dd95SBruce Richardson static struct mem_alloc_validator_entry *
find_mem_alloc_validator(const char * name,int socket_id)5799a2dd95SBruce Richardson find_mem_alloc_validator(const char *name, int socket_id)
5899a2dd95SBruce Richardson {
5999a2dd95SBruce Richardson 	struct mem_alloc_validator_entry *r;
6099a2dd95SBruce Richardson 
6199a2dd95SBruce Richardson 	TAILQ_FOREACH(r, &mem_alloc_validator_list, next) {
6299a2dd95SBruce Richardson 		if (!strcmp(r->name, name) && r->socket_id == socket_id)
6399a2dd95SBruce Richardson 			break;
6499a2dd95SBruce Richardson 	}
6599a2dd95SBruce Richardson 	return r;
6699a2dd95SBruce Richardson }
6799a2dd95SBruce Richardson 
6899a2dd95SBruce Richardson bool
eal_memalloc_is_contig(const struct rte_memseg_list * msl,void * start,size_t len)6999a2dd95SBruce Richardson eal_memalloc_is_contig(const struct rte_memseg_list *msl, void *start,
7099a2dd95SBruce Richardson 		size_t len)
7199a2dd95SBruce Richardson {
7299a2dd95SBruce Richardson 	void *end, *aligned_start, *aligned_end;
7399a2dd95SBruce Richardson 	size_t pgsz = (size_t)msl->page_sz;
7499a2dd95SBruce Richardson 	const struct rte_memseg *ms;
7599a2dd95SBruce Richardson 	const struct internal_config *internal_conf =
7699a2dd95SBruce Richardson 		eal_get_internal_configuration();
7799a2dd95SBruce Richardson 
7899a2dd95SBruce Richardson 	/* for IOVA_VA, it's always contiguous */
7999a2dd95SBruce Richardson 	if (rte_eal_iova_mode() == RTE_IOVA_VA && !msl->external)
8099a2dd95SBruce Richardson 		return true;
8199a2dd95SBruce Richardson 
8299a2dd95SBruce Richardson 	/* for legacy memory, it's always contiguous */
8399a2dd95SBruce Richardson 	if (internal_conf->legacy_mem)
8499a2dd95SBruce Richardson 		return true;
8599a2dd95SBruce Richardson 
8699a2dd95SBruce Richardson 	end = RTE_PTR_ADD(start, len);
8799a2dd95SBruce Richardson 
8899a2dd95SBruce Richardson 	/* for nohuge, we check pagemap, otherwise check memseg */
8999a2dd95SBruce Richardson 	if (!rte_eal_has_hugepages()) {
9099a2dd95SBruce Richardson 		rte_iova_t cur, expected;
9199a2dd95SBruce Richardson 
9299a2dd95SBruce Richardson 		aligned_start = RTE_PTR_ALIGN_FLOOR(start, pgsz);
9399a2dd95SBruce Richardson 		aligned_end = RTE_PTR_ALIGN_CEIL(end, pgsz);
9499a2dd95SBruce Richardson 
9599a2dd95SBruce Richardson 		/* if start and end are on the same page, bail out early */
9699a2dd95SBruce Richardson 		if (RTE_PTR_DIFF(aligned_end, aligned_start) == pgsz)
9799a2dd95SBruce Richardson 			return true;
9899a2dd95SBruce Richardson 
9999a2dd95SBruce Richardson 		/* skip first iteration */
10099a2dd95SBruce Richardson 		cur = rte_mem_virt2iova(aligned_start);
10199a2dd95SBruce Richardson 		expected = cur + pgsz;
10299a2dd95SBruce Richardson 		aligned_start = RTE_PTR_ADD(aligned_start, pgsz);
10399a2dd95SBruce Richardson 
10499a2dd95SBruce Richardson 		while (aligned_start < aligned_end) {
10599a2dd95SBruce Richardson 			cur = rte_mem_virt2iova(aligned_start);
10699a2dd95SBruce Richardson 			if (cur != expected)
10799a2dd95SBruce Richardson 				return false;
10899a2dd95SBruce Richardson 			aligned_start = RTE_PTR_ADD(aligned_start, pgsz);
10999a2dd95SBruce Richardson 			expected += pgsz;
11099a2dd95SBruce Richardson 		}
11199a2dd95SBruce Richardson 	} else {
11299a2dd95SBruce Richardson 		int start_seg, end_seg, cur_seg;
11399a2dd95SBruce Richardson 		rte_iova_t cur, expected;
11499a2dd95SBruce Richardson 
11599a2dd95SBruce Richardson 		aligned_start = RTE_PTR_ALIGN_FLOOR(start, pgsz);
11699a2dd95SBruce Richardson 		aligned_end = RTE_PTR_ALIGN_CEIL(end, pgsz);
11799a2dd95SBruce Richardson 
11899a2dd95SBruce Richardson 		start_seg = RTE_PTR_DIFF(aligned_start, msl->base_va) /
11999a2dd95SBruce Richardson 				pgsz;
12099a2dd95SBruce Richardson 		end_seg = RTE_PTR_DIFF(aligned_end, msl->base_va) /
12199a2dd95SBruce Richardson 				pgsz;
12299a2dd95SBruce Richardson 
12399a2dd95SBruce Richardson 		/* if start and end are on the same page, bail out early */
12499a2dd95SBruce Richardson 		if (RTE_PTR_DIFF(aligned_end, aligned_start) == pgsz)
12599a2dd95SBruce Richardson 			return true;
12699a2dd95SBruce Richardson 
12799a2dd95SBruce Richardson 		/* skip first iteration */
12899a2dd95SBruce Richardson 		ms = rte_fbarray_get(&msl->memseg_arr, start_seg);
12999a2dd95SBruce Richardson 		cur = ms->iova;
13099a2dd95SBruce Richardson 		expected = cur + pgsz;
13199a2dd95SBruce Richardson 
13299a2dd95SBruce Richardson 		/* if we can't access IOVA addresses, assume non-contiguous */
13399a2dd95SBruce Richardson 		if (cur == RTE_BAD_IOVA)
13499a2dd95SBruce Richardson 			return false;
13599a2dd95SBruce Richardson 
13699a2dd95SBruce Richardson 		for (cur_seg = start_seg + 1; cur_seg < end_seg;
13799a2dd95SBruce Richardson 				cur_seg++, expected += pgsz) {
13899a2dd95SBruce Richardson 			ms = rte_fbarray_get(&msl->memseg_arr, cur_seg);
13999a2dd95SBruce Richardson 
14099a2dd95SBruce Richardson 			if (ms->iova != expected)
14199a2dd95SBruce Richardson 				return false;
14299a2dd95SBruce Richardson 		}
14399a2dd95SBruce Richardson 	}
14499a2dd95SBruce Richardson 	return true;
14599a2dd95SBruce Richardson }
14699a2dd95SBruce Richardson 
14799a2dd95SBruce Richardson int
eal_memalloc_mem_event_callback_register(const char * name,rte_mem_event_callback_t clb,void * arg)14899a2dd95SBruce Richardson eal_memalloc_mem_event_callback_register(const char *name,
14999a2dd95SBruce Richardson 		rte_mem_event_callback_t clb, void *arg)
15099a2dd95SBruce Richardson {
15199a2dd95SBruce Richardson 	struct mem_event_callback_entry *entry;
15299a2dd95SBruce Richardson 	int ret, len;
15399a2dd95SBruce Richardson 	if (name == NULL || clb == NULL) {
15499a2dd95SBruce Richardson 		rte_errno = EINVAL;
15599a2dd95SBruce Richardson 		return -1;
15699a2dd95SBruce Richardson 	}
15799a2dd95SBruce Richardson 	len = strnlen(name, RTE_MEM_EVENT_CALLBACK_NAME_LEN);
15899a2dd95SBruce Richardson 	if (len == 0) {
15999a2dd95SBruce Richardson 		rte_errno = EINVAL;
16099a2dd95SBruce Richardson 		return -1;
16199a2dd95SBruce Richardson 	} else if (len == RTE_MEM_EVENT_CALLBACK_NAME_LEN) {
16299a2dd95SBruce Richardson 		rte_errno = ENAMETOOLONG;
16399a2dd95SBruce Richardson 		return -1;
16499a2dd95SBruce Richardson 	}
16599a2dd95SBruce Richardson 	rte_rwlock_write_lock(&mem_event_rwlock);
16699a2dd95SBruce Richardson 
16799a2dd95SBruce Richardson 	entry = find_mem_event_callback(name, arg);
16899a2dd95SBruce Richardson 	if (entry != NULL) {
16999a2dd95SBruce Richardson 		rte_errno = EEXIST;
17099a2dd95SBruce Richardson 		ret = -1;
17199a2dd95SBruce Richardson 		goto unlock;
17299a2dd95SBruce Richardson 	}
17399a2dd95SBruce Richardson 
17499a2dd95SBruce Richardson 	entry = malloc(sizeof(*entry));
17599a2dd95SBruce Richardson 	if (entry == NULL) {
17699a2dd95SBruce Richardson 		rte_errno = ENOMEM;
17799a2dd95SBruce Richardson 		ret = -1;
17899a2dd95SBruce Richardson 		goto unlock;
17999a2dd95SBruce Richardson 	}
18099a2dd95SBruce Richardson 
18199a2dd95SBruce Richardson 	/* callback successfully created and is valid, add it to the list */
18299a2dd95SBruce Richardson 	entry->clb = clb;
18399a2dd95SBruce Richardson 	entry->arg = arg;
18499a2dd95SBruce Richardson 	strlcpy(entry->name, name, RTE_MEM_EVENT_CALLBACK_NAME_LEN);
18599a2dd95SBruce Richardson 	TAILQ_INSERT_TAIL(&mem_event_callback_list, entry, next);
18699a2dd95SBruce Richardson 
18799a2dd95SBruce Richardson 	ret = 0;
18899a2dd95SBruce Richardson 
189*ae67895bSDavid Marchand 	EAL_LOG(DEBUG, "Mem event callback '%s:%p' registered",
19099a2dd95SBruce Richardson 			name, arg);
19199a2dd95SBruce Richardson 
19299a2dd95SBruce Richardson unlock:
19399a2dd95SBruce Richardson 	rte_rwlock_write_unlock(&mem_event_rwlock);
19499a2dd95SBruce Richardson 	return ret;
19599a2dd95SBruce Richardson }
19699a2dd95SBruce Richardson 
19799a2dd95SBruce Richardson int
eal_memalloc_mem_event_callback_unregister(const char * name,void * arg)19899a2dd95SBruce Richardson eal_memalloc_mem_event_callback_unregister(const char *name, void *arg)
19999a2dd95SBruce Richardson {
20099a2dd95SBruce Richardson 	struct mem_event_callback_entry *entry;
20199a2dd95SBruce Richardson 	int ret, len;
20299a2dd95SBruce Richardson 
20399a2dd95SBruce Richardson 	if (name == NULL) {
20499a2dd95SBruce Richardson 		rte_errno = EINVAL;
20599a2dd95SBruce Richardson 		return -1;
20699a2dd95SBruce Richardson 	}
20799a2dd95SBruce Richardson 	len = strnlen(name, RTE_MEM_EVENT_CALLBACK_NAME_LEN);
20899a2dd95SBruce Richardson 	if (len == 0) {
20999a2dd95SBruce Richardson 		rte_errno = EINVAL;
21099a2dd95SBruce Richardson 		return -1;
21199a2dd95SBruce Richardson 	} else if (len == RTE_MEM_EVENT_CALLBACK_NAME_LEN) {
21299a2dd95SBruce Richardson 		rte_errno = ENAMETOOLONG;
21399a2dd95SBruce Richardson 		return -1;
21499a2dd95SBruce Richardson 	}
21599a2dd95SBruce Richardson 	rte_rwlock_write_lock(&mem_event_rwlock);
21699a2dd95SBruce Richardson 
21799a2dd95SBruce Richardson 	entry = find_mem_event_callback(name, arg);
21899a2dd95SBruce Richardson 	if (entry == NULL) {
21999a2dd95SBruce Richardson 		rte_errno = ENOENT;
22099a2dd95SBruce Richardson 		ret = -1;
22199a2dd95SBruce Richardson 		goto unlock;
22299a2dd95SBruce Richardson 	}
22399a2dd95SBruce Richardson 	TAILQ_REMOVE(&mem_event_callback_list, entry, next);
22499a2dd95SBruce Richardson 	free(entry);
22599a2dd95SBruce Richardson 
22699a2dd95SBruce Richardson 	ret = 0;
22799a2dd95SBruce Richardson 
228*ae67895bSDavid Marchand 	EAL_LOG(DEBUG, "Mem event callback '%s:%p' unregistered",
22999a2dd95SBruce Richardson 			name, arg);
23099a2dd95SBruce Richardson 
23199a2dd95SBruce Richardson unlock:
23299a2dd95SBruce Richardson 	rte_rwlock_write_unlock(&mem_event_rwlock);
23399a2dd95SBruce Richardson 	return ret;
23499a2dd95SBruce Richardson }
23599a2dd95SBruce Richardson 
23699a2dd95SBruce Richardson void
eal_memalloc_mem_event_notify(enum rte_mem_event event,const void * start,size_t len)23799a2dd95SBruce Richardson eal_memalloc_mem_event_notify(enum rte_mem_event event, const void *start,
23899a2dd95SBruce Richardson 		size_t len)
23999a2dd95SBruce Richardson {
24099a2dd95SBruce Richardson 	struct mem_event_callback_entry *entry;
24199a2dd95SBruce Richardson 
24299a2dd95SBruce Richardson 	rte_rwlock_read_lock(&mem_event_rwlock);
24399a2dd95SBruce Richardson 
24499a2dd95SBruce Richardson 	TAILQ_FOREACH(entry, &mem_event_callback_list, next) {
245*ae67895bSDavid Marchand 		EAL_LOG(DEBUG, "Calling mem event callback '%s:%p'",
24699a2dd95SBruce Richardson 			entry->name, entry->arg);
24799a2dd95SBruce Richardson 		entry->clb(event, start, len, entry->arg);
24899a2dd95SBruce Richardson 	}
24999a2dd95SBruce Richardson 
25099a2dd95SBruce Richardson 	rte_rwlock_read_unlock(&mem_event_rwlock);
25199a2dd95SBruce Richardson }
25299a2dd95SBruce Richardson 
25399a2dd95SBruce Richardson int
eal_memalloc_mem_alloc_validator_register(const char * name,rte_mem_alloc_validator_t clb,int socket_id,size_t limit)25499a2dd95SBruce Richardson eal_memalloc_mem_alloc_validator_register(const char *name,
25599a2dd95SBruce Richardson 		rte_mem_alloc_validator_t clb, int socket_id, size_t limit)
25699a2dd95SBruce Richardson {
25799a2dd95SBruce Richardson 	struct mem_alloc_validator_entry *entry;
25899a2dd95SBruce Richardson 	int ret, len;
25999a2dd95SBruce Richardson 	if (name == NULL || clb == NULL || socket_id < 0) {
26099a2dd95SBruce Richardson 		rte_errno = EINVAL;
26199a2dd95SBruce Richardson 		return -1;
26299a2dd95SBruce Richardson 	}
26399a2dd95SBruce Richardson 	len = strnlen(name, RTE_MEM_ALLOC_VALIDATOR_NAME_LEN);
26499a2dd95SBruce Richardson 	if (len == 0) {
26599a2dd95SBruce Richardson 		rte_errno = EINVAL;
26699a2dd95SBruce Richardson 		return -1;
26799a2dd95SBruce Richardson 	} else if (len == RTE_MEM_ALLOC_VALIDATOR_NAME_LEN) {
26899a2dd95SBruce Richardson 		rte_errno = ENAMETOOLONG;
26999a2dd95SBruce Richardson 		return -1;
27099a2dd95SBruce Richardson 	}
27199a2dd95SBruce Richardson 	rte_rwlock_write_lock(&mem_alloc_validator_rwlock);
27299a2dd95SBruce Richardson 
27399a2dd95SBruce Richardson 	entry = find_mem_alloc_validator(name, socket_id);
27499a2dd95SBruce Richardson 	if (entry != NULL) {
27599a2dd95SBruce Richardson 		rte_errno = EEXIST;
27699a2dd95SBruce Richardson 		ret = -1;
27799a2dd95SBruce Richardson 		goto unlock;
27899a2dd95SBruce Richardson 	}
27999a2dd95SBruce Richardson 
28099a2dd95SBruce Richardson 	entry = malloc(sizeof(*entry));
28199a2dd95SBruce Richardson 	if (entry == NULL) {
28299a2dd95SBruce Richardson 		rte_errno = ENOMEM;
28399a2dd95SBruce Richardson 		ret = -1;
28499a2dd95SBruce Richardson 		goto unlock;
28599a2dd95SBruce Richardson 	}
28699a2dd95SBruce Richardson 
28799a2dd95SBruce Richardson 	/* callback successfully created and is valid, add it to the list */
28899a2dd95SBruce Richardson 	entry->clb = clb;
28999a2dd95SBruce Richardson 	entry->socket_id = socket_id;
29099a2dd95SBruce Richardson 	entry->limit = limit;
29199a2dd95SBruce Richardson 	strlcpy(entry->name, name, RTE_MEM_ALLOC_VALIDATOR_NAME_LEN);
29299a2dd95SBruce Richardson 	TAILQ_INSERT_TAIL(&mem_alloc_validator_list, entry, next);
29399a2dd95SBruce Richardson 
29499a2dd95SBruce Richardson 	ret = 0;
29599a2dd95SBruce Richardson 
296*ae67895bSDavid Marchand 	EAL_LOG(DEBUG, "Mem alloc validator '%s' on socket %i with limit %zu registered",
29799a2dd95SBruce Richardson 		name, socket_id, limit);
29899a2dd95SBruce Richardson 
29999a2dd95SBruce Richardson unlock:
30099a2dd95SBruce Richardson 	rte_rwlock_write_unlock(&mem_alloc_validator_rwlock);
30199a2dd95SBruce Richardson 	return ret;
30299a2dd95SBruce Richardson }
30399a2dd95SBruce Richardson 
30499a2dd95SBruce Richardson int
eal_memalloc_mem_alloc_validator_unregister(const char * name,int socket_id)30599a2dd95SBruce Richardson eal_memalloc_mem_alloc_validator_unregister(const char *name, int socket_id)
30699a2dd95SBruce Richardson {
30799a2dd95SBruce Richardson 	struct mem_alloc_validator_entry *entry;
30899a2dd95SBruce Richardson 	int ret, len;
30999a2dd95SBruce Richardson 
31099a2dd95SBruce Richardson 	if (name == NULL || socket_id < 0) {
31199a2dd95SBruce Richardson 		rte_errno = EINVAL;
31299a2dd95SBruce Richardson 		return -1;
31399a2dd95SBruce Richardson 	}
31499a2dd95SBruce Richardson 	len = strnlen(name, RTE_MEM_ALLOC_VALIDATOR_NAME_LEN);
31599a2dd95SBruce Richardson 	if (len == 0) {
31699a2dd95SBruce Richardson 		rte_errno = EINVAL;
31799a2dd95SBruce Richardson 		return -1;
31899a2dd95SBruce Richardson 	} else if (len == RTE_MEM_ALLOC_VALIDATOR_NAME_LEN) {
31999a2dd95SBruce Richardson 		rte_errno = ENAMETOOLONG;
32099a2dd95SBruce Richardson 		return -1;
32199a2dd95SBruce Richardson 	}
32299a2dd95SBruce Richardson 	rte_rwlock_write_lock(&mem_alloc_validator_rwlock);
32399a2dd95SBruce Richardson 
32499a2dd95SBruce Richardson 	entry = find_mem_alloc_validator(name, socket_id);
32599a2dd95SBruce Richardson 	if (entry == NULL) {
32699a2dd95SBruce Richardson 		rte_errno = ENOENT;
32799a2dd95SBruce Richardson 		ret = -1;
32899a2dd95SBruce Richardson 		goto unlock;
32999a2dd95SBruce Richardson 	}
33099a2dd95SBruce Richardson 	TAILQ_REMOVE(&mem_alloc_validator_list, entry, next);
33199a2dd95SBruce Richardson 	free(entry);
33299a2dd95SBruce Richardson 
33399a2dd95SBruce Richardson 	ret = 0;
33499a2dd95SBruce Richardson 
335*ae67895bSDavid Marchand 	EAL_LOG(DEBUG, "Mem alloc validator '%s' on socket %i unregistered",
33699a2dd95SBruce Richardson 		name, socket_id);
33799a2dd95SBruce Richardson 
33899a2dd95SBruce Richardson unlock:
33999a2dd95SBruce Richardson 	rte_rwlock_write_unlock(&mem_alloc_validator_rwlock);
34099a2dd95SBruce Richardson 	return ret;
34199a2dd95SBruce Richardson }
34299a2dd95SBruce Richardson 
34399a2dd95SBruce Richardson int
eal_memalloc_mem_alloc_validate(int socket_id,size_t new_len)34499a2dd95SBruce Richardson eal_memalloc_mem_alloc_validate(int socket_id, size_t new_len)
34599a2dd95SBruce Richardson {
34699a2dd95SBruce Richardson 	struct mem_alloc_validator_entry *entry;
34799a2dd95SBruce Richardson 	int ret = 0;
34899a2dd95SBruce Richardson 
34999a2dd95SBruce Richardson 	rte_rwlock_read_lock(&mem_alloc_validator_rwlock);
35099a2dd95SBruce Richardson 
35199a2dd95SBruce Richardson 	TAILQ_FOREACH(entry, &mem_alloc_validator_list, next) {
35299a2dd95SBruce Richardson 		if (entry->socket_id != socket_id || entry->limit > new_len)
35399a2dd95SBruce Richardson 			continue;
354*ae67895bSDavid Marchand 		EAL_LOG(DEBUG, "Calling mem alloc validator '%s' on socket %i",
35599a2dd95SBruce Richardson 			entry->name, entry->socket_id);
35699a2dd95SBruce Richardson 		if (entry->clb(socket_id, entry->limit, new_len) < 0)
35799a2dd95SBruce Richardson 			ret = -1;
35899a2dd95SBruce Richardson 	}
35999a2dd95SBruce Richardson 
36099a2dd95SBruce Richardson 	rte_rwlock_read_unlock(&mem_alloc_validator_rwlock);
36199a2dd95SBruce Richardson 
36299a2dd95SBruce Richardson 	return ret;
36399a2dd95SBruce Richardson }
364