Feature: Fatfs scandir format and mmcblk read/write optimization
1. Bcache block with high mem address is after lower mem address in RCU list when initing bcache. 2. Format will clear the bcache before writing the FAT. 3. The fatfs_readdir use the bcache writing block to reduce the chance of data switching out 4. Add performance analysing macron switch Change-Id: I8fbc48418509d2e660d725d2c265266e931c26f8
This commit is contained in:
parent
b9a4f8b3f1
commit
beca52b61b
|
@ -1372,7 +1372,8 @@ int fatfs_readdir(struct Vnode *vp, struct fs_dirent_s *idir)
|
|||
DEF_NAMBUF;
|
||||
INIT_NAMBUF(fs);
|
||||
for (i = 0; i < idir->read_cnt; i++) {
|
||||
result = dir_read(dp, 0);
|
||||
/* using dir_read_massive to promote performance */
|
||||
result = dir_read_massive(dp, 0);
|
||||
if (result == FR_NO_FILE) {
|
||||
break;
|
||||
} else if (result != FR_OK) {
|
||||
|
@ -1596,7 +1597,7 @@ static int fatfs_set_part_info(los_part *part)
|
|||
return -ENOMEM;
|
||||
}
|
||||
(void)memset_s(buf, disk->sector_size, 0, disk->sector_size);
|
||||
ret = los_disk_read(part->disk_id, buf, 0, 1);
|
||||
ret = los_disk_read(part->disk_id, buf, 0, 1, TRUE); /* TRUE when not reading large data */
|
||||
if (ret < 0) {
|
||||
free(buf);
|
||||
return -EIO;
|
||||
|
|
|
@ -303,6 +303,7 @@ INT32 los_disk_deinit(INT32 diskID);
|
|||
* @param buf [OUT] Type #VOID * memory which used to store read data.
|
||||
* @param sector [IN] Type #UINT64 expected start sector number to read.
|
||||
* @param count [IN] Type #UINT32 expected sector count to read.
|
||||
* @param useRead [IN] Type #BOOL set FALSE to use the write block for optimization
|
||||
*
|
||||
* @retval #0 Read success.
|
||||
* @retval #-1 Read failed.
|
||||
|
@ -312,7 +313,7 @@ INT32 los_disk_deinit(INT32 diskID);
|
|||
* @see los_disk_write
|
||||
*
|
||||
*/
|
||||
INT32 los_disk_read(INT32 drvID, VOID *buf, UINT64 sector, UINT32 count);
|
||||
INT32 los_disk_read(INT32 drvID, VOID *buf, UINT64 sector, UINT32 count, BOOL useRead);
|
||||
|
||||
/**
|
||||
* @ingroup disk
|
||||
|
@ -438,6 +439,7 @@ INT32 los_disk_set_bcache(INT32 drvID, UINT32 sectorPerBlock, UINT32 blockNum);
|
|||
* @param buf [OUT] Type #VOID * memory which used to store the data to be read.
|
||||
* @param sector [IN] Type #UINT64 start sector number of chosen partition.
|
||||
* @param count [IN] Type #UINT32 the expected sector count for reading.
|
||||
* @param useRead [IN] Type #BOOL FALSE when reading large contiguous data, TRUE for other situations
|
||||
*
|
||||
* @retval #0 Read success.
|
||||
* @retval #-1 Read failed.
|
||||
|
@ -447,7 +449,7 @@ INT32 los_disk_set_bcache(INT32 drvID, UINT32 sectorPerBlock, UINT32 blockNum);
|
|||
* @see los_part_read
|
||||
*
|
||||
*/
|
||||
INT32 los_part_read(INT32 pt, VOID *buf, UINT64 sector, UINT32 count);
|
||||
INT32 los_part_read(INT32 pt, VOID *buf, UINT64 sector, UINT32 count, BOOL useRead);
|
||||
|
||||
/**
|
||||
* @ingroup disk
|
||||
|
@ -477,6 +479,30 @@ INT32 los_part_read(INT32 pt, VOID *buf, UINT64 sector, UINT32 count);
|
|||
*/
|
||||
INT32 los_part_write(INT32 pt, const VOID *buf, UINT64 sector, UINT32 count);
|
||||
|
||||
/**
|
||||
* @ingroup disk
|
||||
* @brief Clear the bcache data
|
||||
*
|
||||
* @par Description:
|
||||
* Flush the data and mark the block as unused.
|
||||
*
|
||||
* @attention
|
||||
* <ul>
|
||||
* None
|
||||
* </ul>
|
||||
*
|
||||
* @param drvID [IN] Type #INT32 disk id
|
||||
*
|
||||
* @retval #0 Write success.
|
||||
* @retval #-1 Write failed.
|
||||
*
|
||||
* @par Dependency:
|
||||
* <ul><li>disk.h</li></ul>
|
||||
* @see los_part_read
|
||||
*
|
||||
*/
|
||||
INT32 los_disk_cache_clear(INT32 drvID);
|
||||
|
||||
/**
|
||||
* @ingroup disk
|
||||
* @brief Get information of chosen partition.
|
||||
|
|
|
@ -45,11 +45,38 @@
|
|||
#define ASYNC_EVENT_BIT 0x01
|
||||
|
||||
#ifdef DEBUG
|
||||
#define D(args) printf(args)
|
||||
#define D(args) printf args
|
||||
#else
|
||||
#define D(args)
|
||||
#endif
|
||||
|
||||
#ifdef BCACHE_ANALYSE
|
||||
UINT32 g_memSize;
|
||||
volatile UINT32 g_blockNum;
|
||||
volatile UINT32 g_dataSize;
|
||||
volatile UINT8 *g_memStart;
|
||||
volatile UINT32 g_switchTimes[CONFIG_FS_FAT_BLOCK_NUMS] = { 0 };
|
||||
volatile UINT32 g_hitTimes[CONFIG_FS_FAT_BLOCK_NUMS] = { 0 };
|
||||
#endif
|
||||
|
||||
VOID BcacheAnalyse(UINT32 level)
|
||||
{
|
||||
(VOID)level;
|
||||
#ifdef BCACHE_ANALYSE
|
||||
int i;
|
||||
|
||||
PRINTK("Bcache information:\n");
|
||||
PRINTK(" mem: %u\n", g_memSize);
|
||||
PRINTK(" block number: %u\n", g_blockNum);
|
||||
PRINTK("index, switch, hit\n");
|
||||
for (i = 0; i < g_blockNum; i++) {
|
||||
PRINTK("%5d, %6d, %3d\n", i, g_switchTimes[i], g_hitTimes[i]);
|
||||
}
|
||||
#else
|
||||
PRINTK("Bcache hasn't started\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD
|
||||
|
||||
UINT32 g_syncThreadPrio = CONFIG_FS_FAT_SYNC_THREAD_PRIO;
|
||||
|
@ -623,6 +650,11 @@ static INT32 BcacheGetBlock(OsBcache *bc, UINT64 num, BOOL readData, OsBcacheBlo
|
|||
|
||||
if (block != NULL) {
|
||||
D(("bcache block = %llu found in cache\n", num));
|
||||
#ifdef BCACHE_ANALYSE
|
||||
UINT32 index = ((UINT32)(block->data - g_memStart)) / g_dataSize;
|
||||
PRINTK(", [HIT], %llu, %u\n", num, index);
|
||||
g_hitTimes[index]++;
|
||||
#endif
|
||||
|
||||
if (first != block) {
|
||||
ListMoveBlockToHead(bc, block);
|
||||
|
@ -647,6 +679,11 @@ static INT32 BcacheGetBlock(OsBcache *bc, UINT64 num, BOOL readData, OsBcacheBlo
|
|||
if (block == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
#ifdef BCACHE_ANALYSE
|
||||
UINT32 index = ((UINT32)(block->data - g_memStart)) / g_dataSize;
|
||||
PRINTK(", [MISS], %llu, %u\n", num, index);
|
||||
g_switchTimes[index]++;
|
||||
#endif
|
||||
BlockInit(bc, block, num);
|
||||
|
||||
if (readData == TRUE) {
|
||||
|
@ -667,6 +704,16 @@ static INT32 BcacheGetBlock(OsBcache *bc, UINT64 num, BOOL readData, OsBcacheBlo
|
|||
return ENOERR;
|
||||
}
|
||||
|
||||
INT32 BcacheClearCache(OsBcache *bc)
|
||||
{
|
||||
OsBcacheBlock *block = NULL;
|
||||
OsBcacheBlock *next = NULL;
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(block, next, &bc->listHead, OsBcacheBlock, listNode) {
|
||||
DelBlock(bc, block);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static INT32 BcacheInitCache(OsBcache *bc,
|
||||
UINT8 *memStart,
|
||||
UINT32 memSize,
|
||||
|
@ -701,6 +748,13 @@ static INT32 BcacheInitCache(OsBcache *bc,
|
|||
dataMem = blockMem + (sizeof(OsBcacheBlock) * blockNum);
|
||||
dataMem += ALIGN_DISP((UINTPTR)dataMem);
|
||||
|
||||
#ifdef BCACHE_ANALYSE
|
||||
g_memSize = memSize;
|
||||
g_blockNum = blockNum;
|
||||
g_dataSize = bc->blockSize;
|
||||
g_memStart = dataMem;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < blockNum; i++) {
|
||||
block = (OsBcacheBlock *)(VOID *)blockMem;
|
||||
block->data = dataMem;
|
||||
|
@ -710,7 +764,7 @@ static INT32 BcacheInitCache(OsBcache *bc,
|
|||
bc->wStart = block;
|
||||
}
|
||||
|
||||
LOS_ListAdd(&bc->freeListHead, &block->listNode);
|
||||
LOS_ListTailInsert(&bc->freeListHead, &block->listNode);
|
||||
|
||||
blockMem += sizeof(OsBcacheBlock);
|
||||
dataMem += bc->blockSize;
|
||||
|
@ -768,7 +822,7 @@ INT32 BlockCacheDrvCreate(VOID *handle,
|
|||
return ENOERR;
|
||||
}
|
||||
|
||||
INT32 BlockCacheRead(OsBcache *bc, UINT8 *buf, UINT32 *len, UINT64 sector)
|
||||
INT32 BlockCacheRead(OsBcache *bc, UINT8 *buf, UINT32 *len, UINT64 sector, BOOL useRead)
|
||||
{
|
||||
OsBcacheBlock *block = NULL;
|
||||
UINT8 *tempBuf = buf;
|
||||
|
@ -777,6 +831,9 @@ INT32 BlockCacheRead(OsBcache *bc, UINT8 *buf, UINT32 *len, UINT64 sector)
|
|||
INT32 ret = ENOERR;
|
||||
UINT64 pos;
|
||||
UINT64 num;
|
||||
#ifdef BCACHE_ANALYSE
|
||||
PRINTK("bcache read:\n");
|
||||
#endif
|
||||
|
||||
if (bc == NULL || buf == NULL || len == NULL) {
|
||||
return -EPERM;
|
||||
|
@ -796,7 +853,8 @@ INT32 BlockCacheRead(OsBcache *bc, UINT8 *buf, UINT32 *len, UINT64 sector)
|
|||
|
||||
(VOID)pthread_mutex_lock(&bc->bcacheMutex);
|
||||
|
||||
ret = BcacheGetBlock(bc, num, TRUE, &block);
|
||||
/* useRead should be FALSE when reading large contiguous data */
|
||||
ret = BcacheGetBlock(bc, num, useRead, &block);
|
||||
if (ret != ENOERR) {
|
||||
(VOID)pthread_mutex_unlock(&bc->bcacheMutex);
|
||||
break;
|
||||
|
@ -841,6 +899,9 @@ INT32 BlockCacheWrite(OsBcache *bc, const UINT8 *buf, UINT32 *len, UINT64 sector
|
|||
UINT32 currentSize;
|
||||
UINT64 pos;
|
||||
UINT64 num;
|
||||
#ifdef BCACHE_ANALYSE
|
||||
PRINTK("bcache write:\n");
|
||||
#endif
|
||||
|
||||
pos = sector * bc->sectorSize;
|
||||
num = pos >> bc->blockSizeLog2;
|
||||
|
|
|
@ -798,7 +798,7 @@ INT32 DiskPartitionRegister(los_disk *disk)
|
|||
return ENOERR;
|
||||
}
|
||||
|
||||
INT32 los_disk_read(INT32 drvID, VOID *buf, UINT64 sector, UINT32 count)
|
||||
INT32 los_disk_read(INT32 drvID, VOID *buf, UINT64 sector, UINT32 count, BOOL useRead)
|
||||
{
|
||||
#ifdef LOSCFG_FS_FAT_CACHE
|
||||
UINT32 len;
|
||||
|
@ -830,7 +830,8 @@ INT32 los_disk_read(INT32 drvID, VOID *buf, UINT64 sector, UINT32 count)
|
|||
goto ERROR_HANDLE;
|
||||
}
|
||||
len = disk->bcache->sectorSize * count;
|
||||
result = BlockCacheRead(disk->bcache, (UINT8 *)buf, &len, sector);
|
||||
/* useRead should be FALSE when reading large contiguous data */
|
||||
result = BlockCacheRead(disk->bcache, (UINT8 *)buf, &len, sector, useRead);
|
||||
if (result != ENOERR) {
|
||||
PRINT_ERR("los_disk_read read err = %d, sector = %llu, len = %u\n", result, sector, len);
|
||||
}
|
||||
|
@ -975,7 +976,7 @@ ERROR_HANDLE:
|
|||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
INT32 los_part_read(INT32 pt, VOID *buf, UINT64 sector, UINT32 count)
|
||||
INT32 los_part_read(INT32 pt, VOID *buf, UINT64 sector, UINT32 count, BOOL useRead)
|
||||
{
|
||||
const los_part *part = get_part(pt);
|
||||
los_disk *disk = NULL;
|
||||
|
@ -1017,7 +1018,8 @@ INT32 los_part_read(INT32 pt, VOID *buf, UINT64 sector, UINT32 count)
|
|||
goto ERROR_HANDLE;
|
||||
}
|
||||
|
||||
ret = los_disk_read((INT32)part->disk_id, buf, sector, count);
|
||||
/* useRead should be FALSE when reading large contiguous data */
|
||||
ret = los_disk_read((INT32)part->disk_id, buf, sector, count, useRead);
|
||||
if (ret < 0) {
|
||||
goto ERROR_HANDLE;
|
||||
}
|
||||
|
@ -1148,6 +1150,29 @@ ERROR_HANDLE:
|
|||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
INT32 los_disk_cache_clear(INT32 drvID)
|
||||
{
|
||||
INT32 result;
|
||||
los_disk *disk = NULL;
|
||||
|
||||
result = OsSdSync(drvID);
|
||||
if (result != 0) {
|
||||
PRINTK("[ERROR]disk cache clear failed!n");
|
||||
return result;
|
||||
}
|
||||
|
||||
disk = get_disk(drvID);
|
||||
if (disk == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
DISK_LOCK(&disk->disk_mutex);
|
||||
result = BcacheClearCache(disk->bcache);
|
||||
DISK_UNLOCK(&disk->disk_mutex);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_FS_FAT_CACHE
|
||||
static VOID DiskCacheThreadInit(UINT32 diskID, OsBcache *bc)
|
||||
{
|
||||
|
|
|
@ -131,6 +131,7 @@ typedef struct tagOsBcache {
|
|||
* @param len [IN] number of bytes to read
|
||||
* @param num [IN] starting block number
|
||||
* @param pos [IN] starting position inside starting block
|
||||
* @param useRead [IN] whether use the read block or write block
|
||||
*
|
||||
* @attention
|
||||
* <ul>
|
||||
|
@ -147,7 +148,8 @@ typedef struct tagOsBcache {
|
|||
INT32 BlockCacheRead(OsBcache *bc,
|
||||
UINT8 *buf,
|
||||
UINT32 *len,
|
||||
UINT64 pos);
|
||||
UINT64 pos,
|
||||
BOOL useRead);
|
||||
|
||||
/**
|
||||
* @ingroup bcache
|
||||
|
@ -251,6 +253,7 @@ OsBcache *BlockCacheInit(struct Vnode *devNode,
|
|||
*/
|
||||
VOID BlockCacheDeinit(OsBcache *bc);
|
||||
|
||||
INT32 BcacheClearCache(OsBcache *bc);
|
||||
INT32 OsSdSync(INT32 id);
|
||||
|
||||
#ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD
|
||||
|
|
|
@ -248,8 +248,9 @@ STATIC INT32 GetArgs(CHAR **args)
|
|||
PRINT_ERR("Get EMMC disk failed!\n");
|
||||
goto ERROUT;
|
||||
}
|
||||
/* param4 is TRUE for not reading large contiguous data */
|
||||
ret = los_disk_read(g_emmcDisk->disk_id, cmdLine, COMMAND_LINE_ADDR / EMMC_SEC_SIZE,
|
||||
COMMAND_LINE_SIZE / EMMC_SEC_SIZE);
|
||||
COMMAND_LINE_SIZE / EMMC_SEC_SIZE, TRUE);
|
||||
if (ret != 0) {
|
||||
PRINT_ERR("Read EMMC command line failed!\n");
|
||||
goto ERROUT;
|
||||
|
|
Loading…
Reference in New Issue