fs/procfs: add mempool info to proc/mempool
server> cat /proc/mempool total bsize nused nfree nifree nwaiter hello: 400 20 17 3 0 0 Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
parent
e3bbbfe4d0
commit
c18b5602e8
|
@ -68,6 +68,7 @@ extern const struct procfs_operations cpuload_operations;
|
|||
extern const struct procfs_operations critmon_operations;
|
||||
extern const struct procfs_operations meminfo_operations;
|
||||
extern const struct procfs_operations memdump_operations;
|
||||
extern const struct procfs_operations mempool_operations;
|
||||
extern const struct procfs_operations iobinfo_operations;
|
||||
extern const struct procfs_operations module_operations;
|
||||
extern const struct procfs_operations uptime_operations;
|
||||
|
@ -122,6 +123,10 @@ static const struct procfs_entry_s g_procfs_entries[] =
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MM_MEMPOOL) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MEMPOOL)
|
||||
{ "mempool", &mempool_operations, PROCFS_FILE_TYPE },
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MM_IOB) && !defined(CONFIG_FS_PROCFS_EXCLUDE_IOBINFO)
|
||||
{ "iobinfo", &iobinfo_operations, PROCFS_FILE_TYPE },
|
||||
#endif
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <queue.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <nuttx/fs/procfs.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
|
||||
|
@ -35,10 +36,22 @@
|
|||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_FS_PROCFS_EXCLUDE_MEMPOOL
|
||||
struct mempool_procfs_entry_s
|
||||
{
|
||||
FAR const char *name;
|
||||
FAR struct mempool_procfs_entry_s *next;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* This structure describes memory buffer pool */
|
||||
|
||||
struct mempool_s
|
||||
{
|
||||
#ifndef CONFIG_FS_PROCFS_EXCLUDE_MEMPOOL
|
||||
struct mempool_procfs_entry_s procfs; /* The entry of procfs */
|
||||
#endif
|
||||
|
||||
sq_queue_t list; /* The free block list in normal mempool */
|
||||
sq_queue_t ilist; /* The free block list in interrupt mempool */
|
||||
sq_queue_t elist; /* The expand block list for normal mempool */
|
||||
|
@ -50,6 +63,16 @@ struct mempool_s
|
|||
sem_t wait; /* The semaphore of waiter get free block */
|
||||
};
|
||||
|
||||
struct mempoolinfo_s
|
||||
{
|
||||
unsigned long arena; /* This is the total size of mempool */
|
||||
unsigned long ordblks; /* This is the number of free blocks for normal mempool */
|
||||
unsigned long iordblks; /* This is the number of free blocks for interrupt mempool */
|
||||
unsigned long aordblks; /* This is the number of used blocks */
|
||||
unsigned long sizeblks; /* This is the size of a mempool blocks */
|
||||
unsigned long nwaiter; /* This is the number of waiter for mempool */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
@ -71,6 +94,7 @@ extern "C"
|
|||
*
|
||||
* Input Parameters:
|
||||
* pool - Address of the memory pool to be used.
|
||||
* name - The name of memory pool.
|
||||
* bsize - The block size of memory blocks in pool.
|
||||
* ninitial - The initial count of memory blocks in pool.
|
||||
* nexpand - The increment count of memory blocks in pool.
|
||||
|
@ -84,8 +108,9 @@ extern "C"
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mempool_init(FAR struct mempool_s *pool, size_t bsize, size_t ninitial,
|
||||
size_t nexpand, size_t ninterrupt);
|
||||
int mempool_init(FAR struct mempool_s *pool, FAR const char *name,
|
||||
size_t bsize, size_t ninitial, size_t nexpand,
|
||||
size_t ninterrupt);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mempool_alloc
|
||||
|
@ -119,6 +144,22 @@ FAR void *mempool_alloc(FAR struct mempool_s *pool);
|
|||
|
||||
void mempool_free(FAR struct mempool_s *pool, FAR void *blk);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mempool_info
|
||||
*
|
||||
* Description:
|
||||
* mempool_info returns a copy of updated current mempool information.
|
||||
*
|
||||
* Input Parameters:
|
||||
* pool - Address of the memory pool to be used.
|
||||
* info - The pointer of mempoolinfo.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success; A negated errno value on any failure.
|
||||
****************************************************************************/
|
||||
|
||||
int mempool_info(FAR struct mempool_s *pool, FAR struct mempoolinfo_s *info);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mempool_deinit
|
||||
*
|
||||
|
@ -131,6 +172,38 @@ void mempool_free(FAR struct mempool_s *pool, FAR void *blk);
|
|||
|
||||
int mempool_deinit(FAR struct mempool_s *pool);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mempool_procfs_register
|
||||
*
|
||||
* Description:
|
||||
* Add a new mempool entry to the procfs file system.
|
||||
*
|
||||
* Input Parameters:
|
||||
* entry - Describes the entry to be registered.
|
||||
* name - The name of mempool.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_FS_PROCFS_EXCLUDE_MEMPOOL
|
||||
void mempool_procfs_register(FAR struct mempool_procfs_entry_s *entry,
|
||||
FAR const char *name);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mempool_procfs_unregister
|
||||
*
|
||||
* Description:
|
||||
* Remove a mempool entry from the procfs file system.
|
||||
*
|
||||
* Input Parameters:
|
||||
* entry - Describes the entry to be unregistered.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_FS_PROCFS_EXCLUDE_MEMPOOL
|
||||
void mempool_procfs_unregister(FAR struct mempool_procfs_entry_s *entry);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
|
|
@ -178,6 +178,11 @@ config MM_MEMPOOL
|
|||
Memory buffer pool support. Such pools are mostly used
|
||||
for guaranteed, deadlock-free memory allocations.
|
||||
|
||||
config FS_PROCFS_EXCLUDE_MEMPOOL
|
||||
bool "Exclude mempool"
|
||||
default n
|
||||
depends on FS_PROCFS
|
||||
|
||||
config MM_KASAN
|
||||
bool "Kernel Address Sanitizer"
|
||||
default n
|
||||
|
|
|
@ -21,8 +21,19 @@
|
|||
# Memory buffer pool management
|
||||
|
||||
ifeq ($(CONFIG_MM_MEMPOOL),y)
|
||||
|
||||
CSRCS += mempool.c
|
||||
|
||||
ifeq ($(CONFIG_FS_PROCFS),y)
|
||||
|
||||
ifneq ($(CONFIG_FS_PROCFS_EXCLUDE_MEMPOOL),y)
|
||||
|
||||
CSRCS += mempool_procfs.c
|
||||
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
# Add the memory buffer pool directory to the build
|
||||
|
||||
DEPPATH += --dep-path mempool
|
||||
|
|
|
@ -53,6 +53,7 @@ static inline void mempool_add_list(FAR sq_queue_t *list, FAR void *base,
|
|||
*
|
||||
* Input Parameters:
|
||||
* pool - Address of the memory pool to be used.
|
||||
* name - The name of memory pool.
|
||||
* bsize - The block size of memory blocks in pool.
|
||||
* ninitial - The initial count of memory blocks in pool.
|
||||
* nexpand - The increment count of memory blocks in pool.
|
||||
|
@ -66,8 +67,9 @@ static inline void mempool_add_list(FAR sq_queue_t *list, FAR void *base,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mempool_init(FAR struct mempool_s *pool, size_t bsize, size_t ninitial,
|
||||
size_t nexpand, size_t ninterrupt)
|
||||
int mempool_init(FAR struct mempool_s *pool, FAR const char *name,
|
||||
size_t bsize, size_t ninitial, size_t nexpand,
|
||||
size_t ninterrupt)
|
||||
{
|
||||
size_t count = ninitial + ninterrupt;
|
||||
|
||||
|
@ -102,6 +104,10 @@ int mempool_init(FAR struct mempool_s *pool, size_t bsize, size_t ninitial,
|
|||
nxsem_init(&pool->wait, 0, 0);
|
||||
nxsem_set_protocol(&pool->wait, SEM_PRIO_NONE);
|
||||
|
||||
#ifndef CONFIG_FS_PROCFS_EXCLUDE_MEMPOOL
|
||||
mempool_procfs_register(&pool->procfs, name);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -227,6 +233,51 @@ void mempool_free(FAR struct mempool_s *pool, FAR void *blk)
|
|||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mempool_info
|
||||
*
|
||||
* Description:
|
||||
* mempool_info returns a copy of updated current mempool information.
|
||||
*
|
||||
* Input Parameters:
|
||||
* pool - Address of the memory pool to be used.
|
||||
* info - The pointer of mempoolinfo.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success; A negated errno value on any failure.
|
||||
****************************************************************************/
|
||||
|
||||
int mempool_info(FAR struct mempool_s *pool, FAR struct mempoolinfo_s *info)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
if (pool == NULL || info == NULL)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
flags = spin_lock_irqsave(&pool->lock);
|
||||
info->ordblks = sq_count(&pool->list);
|
||||
info->iordblks = sq_count(&pool->ilist);
|
||||
info->aordblks = pool->nused;
|
||||
info->arena = (pool->nused + info->ordblks + info->iordblks) * pool->bsize;
|
||||
spin_unlock_irqrestore(&pool->lock, flags);
|
||||
info->sizeblks = pool->bsize;
|
||||
if (pool->nexpand == 0)
|
||||
{
|
||||
int semcount;
|
||||
|
||||
nxsem_get_value(&pool->wait, &semcount);
|
||||
info->nwaiter = -semcount;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->nwaiter = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mempool_deinit
|
||||
*
|
||||
|
@ -251,6 +302,10 @@ int mempool_deinit(FAR struct mempool_s *pool)
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_FS_PROCFS_EXCLUDE_MEMPOOL
|
||||
mempool_procfs_unregister(&pool->procfs);
|
||||
#endif
|
||||
|
||||
while ((blk = sq_remfirst(&pool->elist)) != NULL)
|
||||
{
|
||||
kmm_free(blk);
|
||||
|
|
|
@ -0,0 +1,260 @@
|
|||
/****************************************************************************
|
||||
* mm/mempool/mempool_procfs.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/mm/mempool.h>
|
||||
#include <nuttx/fs/procfs.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Determines the size of an intermediate buffer that must be large enough
|
||||
* to handle the longest line generated by this logic.
|
||||
*/
|
||||
|
||||
#define MEMPOOLINFO_LINELEN 80
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This structure describes one open "file" */
|
||||
|
||||
struct mempool_file_s
|
||||
{
|
||||
struct procfs_file_s base; /* Base open file structure */
|
||||
unsigned int linesize; /* Number of valid characters in line[] */
|
||||
char line[MEMPOOLINFO_LINELEN]; /* Pre-allocated buffer for formatted lines */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static int mempool_open(FAR struct file *filep, FAR const char *relpath,
|
||||
int oflags, mode_t mode);
|
||||
static int mempool_close(FAR struct file *filep);
|
||||
static int mempool_dup(FAR const struct file *oldp,
|
||||
FAR struct file *newp);
|
||||
static int mempool_stat(FAR const char *relpath, FAR struct stat *buf);
|
||||
static ssize_t mempool_read(FAR struct file *filep, FAR char *buffer,
|
||||
size_t buflen);
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
const struct procfs_operations mempool_operations =
|
||||
{
|
||||
mempool_open, /* open */
|
||||
mempool_close, /* close */
|
||||
mempool_read, /* read */
|
||||
NULL, /* write */
|
||||
mempool_dup, /* dup */
|
||||
NULL, /* opendir */
|
||||
NULL, /* closedir */
|
||||
NULL, /* readdir */
|
||||
NULL, /* rewinddir */
|
||||
mempool_stat /* stat */
|
||||
};
|
||||
|
||||
static FAR struct mempool_procfs_entry_s *g_mempool_procfs = NULL;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mempool_open
|
||||
****************************************************************************/
|
||||
|
||||
static int mempool_open(FAR struct file *filep, FAR const char *relpath,
|
||||
int oflags, mode_t mode)
|
||||
{
|
||||
FAR struct mempool_file_s *procfile;
|
||||
|
||||
procfile = kmm_zalloc(sizeof(struct mempool_file_s));
|
||||
if (procfile == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
filep->f_priv = procfile;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mempool_close
|
||||
****************************************************************************/
|
||||
|
||||
static int mempool_close(FAR struct file *filep)
|
||||
{
|
||||
kmm_free(filep->f_priv);
|
||||
filep->f_priv = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mempool_read
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t mempool_read(FAR struct file *filep, FAR char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
FAR const struct mempool_procfs_entry_s *entry;
|
||||
FAR struct mempool_file_s *procfile;
|
||||
size_t linesize;
|
||||
size_t copysize;
|
||||
size_t totalsize;
|
||||
off_t offset;
|
||||
|
||||
offset = filep->f_pos;
|
||||
procfile = filep->f_priv;
|
||||
linesize = procfs_snprintf(procfile->line, MEMPOOLINFO_LINELEN,
|
||||
"%13s%11s%9s%9s%9s%9s%9s\n", "", "total",
|
||||
"bsize", "nused", "nfree", "nifree",
|
||||
"nwaiter");
|
||||
|
||||
copysize = procfs_memcpy(procfile->line, linesize, buffer, buflen,
|
||||
&offset);
|
||||
totalsize = copysize;
|
||||
|
||||
for (entry = g_mempool_procfs; entry != NULL; entry = entry->next)
|
||||
{
|
||||
if (totalsize < buflen)
|
||||
{
|
||||
struct mempoolinfo_s minfo;
|
||||
|
||||
buffer += copysize;
|
||||
buflen -= copysize;
|
||||
|
||||
mempool_info((FAR struct mempool_s *)entry, &minfo);
|
||||
linesize = procfs_snprintf(procfile->line, MEMPOOLINFO_LINELEN,
|
||||
"%12s:%11lu%9lu%9lu%9lu%9lu%9lu\n",
|
||||
entry->name, minfo.arena,
|
||||
minfo.sizeblks, minfo.aordblks,
|
||||
minfo.ordblks, minfo.iordblks,
|
||||
minfo.nwaiter);
|
||||
copysize = procfs_memcpy(procfile->line, linesize, buffer,
|
||||
buflen, &offset);
|
||||
totalsize += copysize;
|
||||
}
|
||||
}
|
||||
|
||||
filep->f_pos += totalsize;
|
||||
return totalsize;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mempool_dup
|
||||
*
|
||||
* Description:
|
||||
* Duplicate open file data in the new file structure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int mempool_dup(FAR const struct file *oldp, FAR struct file *newp)
|
||||
{
|
||||
FAR struct mempool_file_s *oldattr;
|
||||
FAR struct mempool_file_s *newattr;
|
||||
|
||||
oldattr = oldp->f_priv;
|
||||
newattr = kmm_malloc(sizeof(struct mempool_file_s));
|
||||
if (newattr == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(newattr, oldattr, sizeof(struct mempool_file_s));
|
||||
newp->f_priv = newattr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mempool_stat
|
||||
*
|
||||
* Description: Return information about a file or directory
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int mempool_stat(FAR const char *relpath, FAR struct stat *buf)
|
||||
{
|
||||
memset(buf, 0, sizeof(struct stat));
|
||||
buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mempool_procfs_register
|
||||
*
|
||||
* Description:
|
||||
* Add a new mempool entry to the procfs file system.
|
||||
*
|
||||
* Input Parameters:
|
||||
* entry - Describes the entry to be registered.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mempool_procfs_register(FAR struct mempool_procfs_entry_s *entry,
|
||||
FAR const char *name)
|
||||
{
|
||||
entry->name = name;
|
||||
entry->next = g_mempool_procfs;
|
||||
g_mempool_procfs = entry;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mempool_procfs_unregister
|
||||
*
|
||||
* Description:
|
||||
* Remove a mempool entry from the procfs file system.
|
||||
*
|
||||
* Input Parameters:
|
||||
* entry - Describes the entry to be unregistered.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mempool_procfs_unregister(FAR struct mempool_procfs_entry_s *entry)
|
||||
{
|
||||
FAR struct mempool_procfs_entry_s **cur;
|
||||
|
||||
for (cur = &g_mempool_procfs; *cur != NULL; cur = &(*cur)->next)
|
||||
{
|
||||
if (*cur == entry)
|
||||
{
|
||||
*cur = entry->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue