提交 beca52b6 编写于 作者: F Far

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
上级 b9a4f8b3
...@@ -1372,7 +1372,8 @@ int fatfs_readdir(struct Vnode *vp, struct fs_dirent_s *idir) ...@@ -1372,7 +1372,8 @@ int fatfs_readdir(struct Vnode *vp, struct fs_dirent_s *idir)
DEF_NAMBUF; DEF_NAMBUF;
INIT_NAMBUF(fs); INIT_NAMBUF(fs);
for (i = 0; i < idir->read_cnt; i++) { 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) { if (result == FR_NO_FILE) {
break; break;
} else if (result != FR_OK) { } else if (result != FR_OK) {
...@@ -1596,7 +1597,7 @@ static int fatfs_set_part_info(los_part *part) ...@@ -1596,7 +1597,7 @@ static int fatfs_set_part_info(los_part *part)
return -ENOMEM; return -ENOMEM;
} }
(void)memset_s(buf, disk->sector_size, 0, disk->sector_size); (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) { if (ret < 0) {
free(buf); free(buf);
return -EIO; return -EIO;
......
...@@ -303,6 +303,7 @@ INT32 los_disk_deinit(INT32 diskID); ...@@ -303,6 +303,7 @@ INT32 los_disk_deinit(INT32 diskID);
* @param buf [OUT] Type #VOID * memory which used to store read data. * @param buf [OUT] Type #VOID * memory which used to store read data.
* @param sector [IN] Type #UINT64 expected start sector number to read. * @param sector [IN] Type #UINT64 expected start sector number to read.
* @param count [IN] Type #UINT32 expected sector count 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 #0 Read success.
* @retval #-1 Read failed. * @retval #-1 Read failed.
...@@ -312,7 +313,7 @@ INT32 los_disk_deinit(INT32 diskID); ...@@ -312,7 +313,7 @@ INT32 los_disk_deinit(INT32 diskID);
* @see los_disk_write * @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 * @ingroup disk
...@@ -438,6 +439,7 @@ INT32 los_disk_set_bcache(INT32 drvID, UINT32 sectorPerBlock, UINT32 blockNum); ...@@ -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 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 sector [IN] Type #UINT64 start sector number of chosen partition.
* @param count [IN] Type #UINT32 the expected sector count for reading. * @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 #0 Read success.
* @retval #-1 Read failed. * @retval #-1 Read failed.
...@@ -447,7 +449,7 @@ INT32 los_disk_set_bcache(INT32 drvID, UINT32 sectorPerBlock, UINT32 blockNum); ...@@ -447,7 +449,7 @@ INT32 los_disk_set_bcache(INT32 drvID, UINT32 sectorPerBlock, UINT32 blockNum);
* @see los_part_read * @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 * @ingroup disk
...@@ -477,6 +479,30 @@ INT32 los_part_read(INT32 pt, VOID *buf, UINT64 sector, UINT32 count); ...@@ -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); 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 * @ingroup disk
* @brief Get information of chosen partition. * @brief Get information of chosen partition.
......
...@@ -45,11 +45,38 @@ ...@@ -45,11 +45,38 @@
#define ASYNC_EVENT_BIT 0x01 #define ASYNC_EVENT_BIT 0x01
#ifdef DEBUG #ifdef DEBUG
#define D(args) printf(args) #define D(args) printf args
#else #else
#define D(args) #define D(args)
#endif #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 #ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD
UINT32 g_syncThreadPrio = CONFIG_FS_FAT_SYNC_THREAD_PRIO; UINT32 g_syncThreadPrio = CONFIG_FS_FAT_SYNC_THREAD_PRIO;
...@@ -623,6 +650,11 @@ static INT32 BcacheGetBlock(OsBcache *bc, UINT64 num, BOOL readData, OsBcacheBlo ...@@ -623,6 +650,11 @@ static INT32 BcacheGetBlock(OsBcache *bc, UINT64 num, BOOL readData, OsBcacheBlo
if (block != NULL) { if (block != NULL) {
D(("bcache block = %llu found in cache\n", num)); 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) { if (first != block) {
ListMoveBlockToHead(bc, block); ListMoveBlockToHead(bc, block);
...@@ -647,6 +679,11 @@ static INT32 BcacheGetBlock(OsBcache *bc, UINT64 num, BOOL readData, OsBcacheBlo ...@@ -647,6 +679,11 @@ static INT32 BcacheGetBlock(OsBcache *bc, UINT64 num, BOOL readData, OsBcacheBlo
if (block == NULL) { if (block == NULL) {
return -ENOMEM; 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); BlockInit(bc, block, num);
if (readData == TRUE) { if (readData == TRUE) {
...@@ -667,6 +704,16 @@ static INT32 BcacheGetBlock(OsBcache *bc, UINT64 num, BOOL readData, OsBcacheBlo ...@@ -667,6 +704,16 @@ static INT32 BcacheGetBlock(OsBcache *bc, UINT64 num, BOOL readData, OsBcacheBlo
return ENOERR; 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, static INT32 BcacheInitCache(OsBcache *bc,
UINT8 *memStart, UINT8 *memStart,
UINT32 memSize, UINT32 memSize,
...@@ -701,6 +748,13 @@ static INT32 BcacheInitCache(OsBcache *bc, ...@@ -701,6 +748,13 @@ static INT32 BcacheInitCache(OsBcache *bc,
dataMem = blockMem + (sizeof(OsBcacheBlock) * blockNum); dataMem = blockMem + (sizeof(OsBcacheBlock) * blockNum);
dataMem += ALIGN_DISP((UINTPTR)dataMem); 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++) { for (i = 0; i < blockNum; i++) {
block = (OsBcacheBlock *)(VOID *)blockMem; block = (OsBcacheBlock *)(VOID *)blockMem;
block->data = dataMem; block->data = dataMem;
...@@ -710,7 +764,7 @@ static INT32 BcacheInitCache(OsBcache *bc, ...@@ -710,7 +764,7 @@ static INT32 BcacheInitCache(OsBcache *bc,
bc->wStart = block; bc->wStart = block;
} }
LOS_ListAdd(&bc->freeListHead, &block->listNode); LOS_ListTailInsert(&bc->freeListHead, &block->listNode);
blockMem += sizeof(OsBcacheBlock); blockMem += sizeof(OsBcacheBlock);
dataMem += bc->blockSize; dataMem += bc->blockSize;
...@@ -768,7 +822,7 @@ INT32 BlockCacheDrvCreate(VOID *handle, ...@@ -768,7 +822,7 @@ INT32 BlockCacheDrvCreate(VOID *handle,
return ENOERR; 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; OsBcacheBlock *block = NULL;
UINT8 *tempBuf = buf; UINT8 *tempBuf = buf;
...@@ -777,6 +831,9 @@ INT32 BlockCacheRead(OsBcache *bc, UINT8 *buf, UINT32 *len, UINT64 sector) ...@@ -777,6 +831,9 @@ INT32 BlockCacheRead(OsBcache *bc, UINT8 *buf, UINT32 *len, UINT64 sector)
INT32 ret = ENOERR; INT32 ret = ENOERR;
UINT64 pos; UINT64 pos;
UINT64 num; UINT64 num;
#ifdef BCACHE_ANALYSE
PRINTK("bcache read:\n");
#endif
if (bc == NULL || buf == NULL || len == NULL) { if (bc == NULL || buf == NULL || len == NULL) {
return -EPERM; return -EPERM;
...@@ -796,7 +853,8 @@ INT32 BlockCacheRead(OsBcache *bc, UINT8 *buf, UINT32 *len, UINT64 sector) ...@@ -796,7 +853,8 @@ INT32 BlockCacheRead(OsBcache *bc, UINT8 *buf, UINT32 *len, UINT64 sector)
(VOID)pthread_mutex_lock(&bc->bcacheMutex); (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) { if (ret != ENOERR) {
(VOID)pthread_mutex_unlock(&bc->bcacheMutex); (VOID)pthread_mutex_unlock(&bc->bcacheMutex);
break; break;
...@@ -841,6 +899,9 @@ INT32 BlockCacheWrite(OsBcache *bc, const UINT8 *buf, UINT32 *len, UINT64 sector ...@@ -841,6 +899,9 @@ INT32 BlockCacheWrite(OsBcache *bc, const UINT8 *buf, UINT32 *len, UINT64 sector
UINT32 currentSize; UINT32 currentSize;
UINT64 pos; UINT64 pos;
UINT64 num; UINT64 num;
#ifdef BCACHE_ANALYSE
PRINTK("bcache write:\n");
#endif
pos = sector * bc->sectorSize; pos = sector * bc->sectorSize;
num = pos >> bc->blockSizeLog2; num = pos >> bc->blockSizeLog2;
......
...@@ -798,7 +798,7 @@ INT32 DiskPartitionRegister(los_disk *disk) ...@@ -798,7 +798,7 @@ INT32 DiskPartitionRegister(los_disk *disk)
return ENOERR; 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 #ifdef LOSCFG_FS_FAT_CACHE
UINT32 len; UINT32 len;
...@@ -830,7 +830,8 @@ INT32 los_disk_read(INT32 drvID, VOID *buf, UINT64 sector, UINT32 count) ...@@ -830,7 +830,8 @@ INT32 los_disk_read(INT32 drvID, VOID *buf, UINT64 sector, UINT32 count)
goto ERROR_HANDLE; goto ERROR_HANDLE;
} }
len = disk->bcache->sectorSize * count; 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) { if (result != ENOERR) {
PRINT_ERR("los_disk_read read err = %d, sector = %llu, len = %u\n", result, sector, len); PRINT_ERR("los_disk_read read err = %d, sector = %llu, len = %u\n", result, sector, len);
} }
...@@ -975,7 +976,7 @@ ERROR_HANDLE: ...@@ -975,7 +976,7 @@ ERROR_HANDLE:
return VFS_ERROR; 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); const los_part *part = get_part(pt);
los_disk *disk = NULL; los_disk *disk = NULL;
...@@ -1017,7 +1018,8 @@ INT32 los_part_read(INT32 pt, VOID *buf, UINT64 sector, UINT32 count) ...@@ -1017,7 +1018,8 @@ INT32 los_part_read(INT32 pt, VOID *buf, UINT64 sector, UINT32 count)
goto ERROR_HANDLE; 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) { if (ret < 0) {
goto ERROR_HANDLE; goto ERROR_HANDLE;
} }
...@@ -1148,6 +1150,29 @@ ERROR_HANDLE: ...@@ -1148,6 +1150,29 @@ ERROR_HANDLE:
return VFS_ERROR; 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 #ifdef LOSCFG_FS_FAT_CACHE
static VOID DiskCacheThreadInit(UINT32 diskID, OsBcache *bc) static VOID DiskCacheThreadInit(UINT32 diskID, OsBcache *bc)
{ {
......
...@@ -131,6 +131,7 @@ typedef struct tagOsBcache { ...@@ -131,6 +131,7 @@ typedef struct tagOsBcache {
* @param len [IN] number of bytes to read * @param len [IN] number of bytes to read
* @param num [IN] starting block number * @param num [IN] starting block number
* @param pos [IN] starting position inside starting block * @param pos [IN] starting position inside starting block
* @param useRead [IN] whether use the read block or write block
* *
* @attention * @attention
* <ul> * <ul>
...@@ -147,7 +148,8 @@ typedef struct tagOsBcache { ...@@ -147,7 +148,8 @@ typedef struct tagOsBcache {
INT32 BlockCacheRead(OsBcache *bc, INT32 BlockCacheRead(OsBcache *bc,
UINT8 *buf, UINT8 *buf,
UINT32 *len, UINT32 *len,
UINT64 pos); UINT64 pos,
BOOL useRead);
/** /**
* @ingroup bcache * @ingroup bcache
...@@ -251,6 +253,7 @@ OsBcache *BlockCacheInit(struct Vnode *devNode, ...@@ -251,6 +253,7 @@ OsBcache *BlockCacheInit(struct Vnode *devNode,
*/ */
VOID BlockCacheDeinit(OsBcache *bc); VOID BlockCacheDeinit(OsBcache *bc);
INT32 BcacheClearCache(OsBcache *bc);
INT32 OsSdSync(INT32 id); INT32 OsSdSync(INT32 id);
#ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD #ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD
......
...@@ -248,8 +248,9 @@ STATIC INT32 GetArgs(CHAR **args) ...@@ -248,8 +248,9 @@ STATIC INT32 GetArgs(CHAR **args)
PRINT_ERR("Get EMMC disk failed!\n"); PRINT_ERR("Get EMMC disk failed!\n");
goto ERROUT; 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, 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) { if (ret != 0) {
PRINT_ERR("Read EMMC command line failed!\n"); PRINT_ERR("Read EMMC command line failed!\n");
goto ERROUT; goto ERROUT;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册