Skip to content

Commit 6c7e96d

Browse files
committed
[nrf fromlist] soc: nordic: common: dmm: Add optional usage stats
Add support for getting usage statistics for DMM. Upstream PR #: 95306 Signed-off-by: Krzysztof Chruściński <[email protected]>
1 parent 1990a03 commit 6c7e96d

File tree

3 files changed

+76
-0
lines changed

3 files changed

+76
-0
lines changed

soc/nordic/common/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ config DMM_HEAP_CHUNKS
6060
Number of chunks is a trade-off between performance and granularity.
6161
Must be multiply of 32.
6262

63+
config DMM_STATS
64+
bool "Usage statistics"
65+
6366
endif # HAS_NORDIC_DMM
6467

6568
rsource "vpr/Kconfig"

soc/nordic/common/dmm.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ struct dmm_heap {
5252
size_t blk_size;
5353
const struct dmm_region *region;
5454
sys_bitarray_t bitarray;
55+
#ifdef CONFIG_DMM_STATS
56+
atomic_t curr_use;
57+
uint32_t max_use;
58+
struct k_spinlock lock;
59+
#endif
5560
};
5661

5762
static const struct dmm_region dmm_regions[] = {
@@ -128,6 +133,15 @@ static void *dmm_buffer_alloc(struct dmm_heap *dh, size_t length)
128133
return NULL;
129134
}
130135

136+
#ifdef CONFIG_DMM_STATS
137+
k_spinlock_key_t key;
138+
139+
key = k_spin_lock(&dh->lock);
140+
dh->curr_use += num_bits;
141+
dh->max_use = MAX(dh->max_use, dh->curr_use);
142+
k_spin_unlock(&dh->lock, key);
143+
#endif
144+
131145
if (num_bits > 1) {
132146
size_t idx = off / 32;
133147
size_t woff = off - 32 * idx;
@@ -153,6 +167,10 @@ static void dmm_buffer_free(struct dmm_heap *dh, void *buffer)
153167
atomic_and(&dh->tail_mask[idx], ~mask);
154168
}
155169

170+
#ifdef CONFIG_DMM_STATS
171+
atomic_sub(&dh->curr_use, num_bits);
172+
#endif
173+
156174
int rv = sys_bitarray_free(&dh->bitarray, num_bits, offset);
157175

158176
(void)rv;
@@ -341,6 +359,34 @@ int dmm_buffer_in_release(void *region, void *user_buffer, size_t user_length, v
341359
return 0;
342360
}
343361

362+
int dmm_stats_get(void *region, uintptr_t *start_addr, uint32_t *curr_use, uint32_t *max_use)
363+
{
364+
#ifdef CONFIG_DMM_STATS
365+
struct dmm_heap *dh;
366+
367+
dh = dmm_heap_find(region);
368+
if (dh == NULL) {
369+
return -EINVAL;
370+
}
371+
372+
if (start_addr) {
373+
*start_addr = dh->ptr;
374+
}
375+
376+
if (curr_use) {
377+
*curr_use = (100 * dh->curr_use) / dh->bitarray.num_bits;
378+
}
379+
380+
if (max_use) {
381+
*max_use = (100 * dh->max_use) / dh->bitarray.num_bits;
382+
}
383+
384+
return 0;
385+
#else
386+
return -ENOTSUP;
387+
#endif
388+
}
389+
344390
int dmm_init(void)
345391
{
346392
struct dmm_heap *dh;

soc/nordic/common/dmm.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,22 @@ int dmm_buffer_in_prepare(void *region, void *user_buffer, size_t user_length, v
163163
*/
164164
int dmm_buffer_in_release(void *region, void *user_buffer, size_t user_length, void *buffer_in);
165165

166+
/**
167+
* @brief Get statistics.
168+
*
169+
* Must be enabled with CONFIG_DMM_STATS.
170+
*
171+
* @param[in] region DMM memory region.
172+
* @param[out] start_addr Location where starting address of the memory region is set. Can be null.
173+
* @param[out] curr_use Location where current use in percent is written. Can be null.
174+
* @param[out] max_use Location where maximum use in percent is written. Can be null.
175+
*
176+
* @retval 0 on success.
177+
* @retval -EINVAL Invalid region.
178+
* @retval -ENOTSUP Feature is disabled.
179+
*/
180+
int dmm_stats_get(void *region, uintptr_t *start_addr, uint32_t *curr_use, uint32_t *max_use);
181+
166182
/**
167183
* @brief Initialize DMM.
168184
*
@@ -210,6 +226,17 @@ static ALWAYS_INLINE int dmm_buffer_in_release(void *region, void *user_buffer,
210226
return 0;
211227
}
212228

229+
static ALWAYS_INLINE int dmm_stats_get(void *region, uintptr_t *start_addr,
230+
uint32_t *curr_use, uint32_t *max_use)
231+
{
232+
ARG_UNUSED(region);
233+
ARG_UNUSED(start_addr);
234+
ARG_UNUSED(curr_use);
235+
ARG_UNUSED(max_use);
236+
237+
return 0;
238+
}
239+
213240
static ALWAYS_INLINE int dmm_init(void)
214241
{
215242
return 0;

0 commit comments

Comments
 (0)