Skip to content

Commit e937046

Browse files
committed
lib: mempool: Synchronize level checks
Do not perform early level usage check. This can lead to situation where block is seen as available on level when it was taken from the other context. Fixes: zephyrproject-rtos#14504 Signed-off-by: Pawel Dunaj <[email protected]>
1 parent f989a0e commit e937046

File tree

1 file changed

+4
-12
lines changed

1 file changed

+4
-12
lines changed

lib/os/mempool.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,6 @@
1616
#define LVL_ARRAY_SZ(n) (n)
1717
#endif
1818

19-
static bool level_empty(struct sys_mem_pool_base *p, int l)
20-
{
21-
return sys_dlist_is_empty(&p->levels[l].free_list);
22-
}
23-
2419
static void *block_ptr(struct sys_mem_pool_base *p, size_t lsz, int block)
2520
{
2621
return (u8_t *)p->buf + lsz * block;
@@ -236,7 +231,7 @@ static void *block_break(struct sys_mem_pool_base *p, void *block, int l,
236231
int z_sys_mem_pool_block_alloc(struct sys_mem_pool_base *p, size_t size,
237232
u32_t *level_p, u32_t *block_p, void **data_p)
238233
{
239-
int i, from_l, alloc_l = -1, free_l = -1;
234+
int i, from_l, alloc_l = -1;
240235
unsigned int key;
241236
void *data = NULL;
242237
size_t lsizes[LVL_ARRAY_SZ(p->n_levels)];
@@ -258,12 +253,9 @@ int z_sys_mem_pool_block_alloc(struct sys_mem_pool_base *p, size_t size,
258253
}
259254

260255
alloc_l = i;
261-
if (!level_empty(p, i)) {
262-
free_l = i;
263-
}
264256
}
265257

266-
if (alloc_l < 0 || free_l < 0) {
258+
if (alloc_l < 0) {
267259
*data_p = NULL;
268260
return -ENOMEM;
269261
}
@@ -280,7 +272,7 @@ int z_sys_mem_pool_block_alloc(struct sys_mem_pool_base *p, size_t size,
280272
* spurious -ENOMEM.
281273
*/
282274
key = pool_irq_lock(p);
283-
for (i = free_l; i >= 0; i--) {
275+
for (i = alloc_l; i >= 0; i--) {
284276
data = block_alloc(p, i, lsizes[i]);
285277

286278
/* Found one. Iteratively break it down to the size
@@ -290,9 +282,9 @@ int z_sys_mem_pool_block_alloc(struct sys_mem_pool_base *p, size_t size,
290282
*/
291283
if (data != NULL) {
292284
for (from_l = i; from_l < alloc_l; from_l++) {
293-
data = block_break(p, data, from_l, lsizes);
294285
pool_irq_unlock(p, key);
295286
key = pool_irq_lock(p);
287+
data = block_break(p, data, from_l, lsizes);
296288
}
297289
break;
298290
}

0 commit comments

Comments
 (0)