OpenSSD Cosmos+ Platform Firmware
0.0.2
The firmware of Cosmos+ OpenSSD Platform for TOSHIBA nand flash module.
|
Go to the source code of this file.
Data Structures | |
struct | _DATA_BUF_ENTRY |
The structure of the data buffer entry. More... | |
struct | _DATA_BUF_MAP |
The structure of data buffer table. More... | |
struct | _DATA_BUF_LRU_LIST |
The structure of LRU list that records the head and tail data buffer entry index of the LRU list. More... | |
struct | _DATA_BUF_HASH_ENTRY |
The structure of data buffer bucket that records the head and tail data buffer entry index in the bucket. More... | |
struct | _DATA_BUF_HASH_TABLE |
The structure of data buffer hash table. More... | |
struct | _TEMPORARY_DATA_BUF_ENTRY |
struct | _TEMPORARY_DATA_BUF_MAP |
The structure of the temp data buffer table. More... | |
Typedefs | |
typedef struct _DATA_BUF_ENTRY | DATA_BUF_ENTRY |
The structure of the data buffer entry. More... | |
typedef struct _DATA_BUF_ENTRY * | P_DATA_BUF_ENTRY |
typedef struct _DATA_BUF_MAP | DATA_BUF_MAP |
The structure of data buffer table. More... | |
typedef struct _DATA_BUF_MAP * | P_DATA_BUF_MAP |
typedef struct _DATA_BUF_LRU_LIST | DATA_BUF_LRU_LIST |
The structure of LRU list that records the head and tail data buffer entry index of the LRU list. More... | |
typedef struct _DATA_BUF_LRU_LIST * | P_DATA_BUF_LRU_LIST |
typedef struct _DATA_BUF_HASH_ENTRY | DATA_BUF_HASH_ENTRY |
The structure of data buffer bucket that records the head and tail data buffer entry index in the bucket. More... | |
typedef struct _DATA_BUF_HASH_ENTRY * | P_DATA_BUF_HASH_ENTRY |
typedef struct _DATA_BUF_HASH_TABLE | DATA_BUF_HASH_TABLE |
The structure of data buffer hash table. More... | |
typedef struct _DATA_BUF_HASH_TABLE * | P_DATA_BUF_HASH_TABLE |
typedef struct _TEMPORARY_DATA_BUF_ENTRY | TEMPORARY_DATA_BUF_ENTRY |
typedef struct _TEMPORARY_DATA_BUF_ENTRY * | P_TEMPORARY_DATA_BUF_ENTRY |
typedef struct _TEMPORARY_DATA_BUF_MAP | TEMPORARY_DATA_BUF_MAP |
The structure of the temp data buffer table. More... | |
typedef struct _TEMPORARY_DATA_BUF_MAP * | P_TEMPORARY_DATA_BUF_MAP |
Functions | |
void | InitDataBuf () |
Initialization process of the Data buffer. More... | |
unsigned int | CheckDataBufHit (unsigned int reqSlotTag) |
Get the data buffer entry index of the given request. More... | |
unsigned int | AllocateDataBuf () |
Retrieve a LRU data buffer entry from the LRU list. More... | |
void | UpdateDataBufEntryInfoBlockingReq (unsigned int bufEntry, unsigned int reqSlotTag) |
Append the request to the blocking queue of the specified data buffer entry. More... | |
unsigned int | AllocateTempDataBuf (unsigned int dieNo) |
Retrieve the index of temp buffer entry of the target die. More... | |
void | UpdateTempDataBufEntryInfoBlockingReq (unsigned int bufEntry, unsigned int reqSlotTag) |
Append the request to the blocking queue specified by given temp buffer entry. More... | |
void | PutToDataBufHashList (unsigned int bufEntry) |
Insert the given data buffer entry into the hash table. More... | |
void | SelectiveGetFromDataBufHashList (unsigned int bufEntry) |
Remove the given data buffer entry from the hash table. More... | |
Variables | |
P_DATA_BUF_MAP | dataBufMapPtr |
DATA_BUF_LRU_LIST | dataBufLruList |
P_DATA_BUF_HASH_TABLE | dataBufHashTable |
P_TEMPORARY_DATA_BUF_MAP | tempDataBufMapPtr |
#define AVAILABLE_DATA_BUFFER_ENTRY_COUNT (16 * USER_DIES) |
Definition at line 54 of file data_buffer.h.
#define AVAILABLE_TEMPORARY_DATA_BUFFER_ENTRY_COUNT (USER_DIES) |
Definition at line 55 of file data_buffer.h.
#define BUF_DATA_ENTRY2ADDR | ( | iEntry | ) | (DATA_BUFFER_BASE_ADDR + ((iEntry)*BYTES_PER_DATA_REGION_OF_SLICE)) |
Definition at line 221 of file data_buffer.h.
#define BUF_ENTRY | ( | iEntry | ) | (&dataBufMapPtr->dataBuf[(iEntry)]) |
Definition at line 202 of file data_buffer.h.
#define BUF_ENTRY_IS_HEAD | ( | iEntry | ) | (BUF_PREV_IDX((iEntry)) == DATA_BUF_NONE) |
Definition at line 212 of file data_buffer.h.
#define BUF_ENTRY_IS_TAIL | ( | iEntry | ) | (BUF_NEXT_IDX((iEntry)) == DATA_BUF_NONE) |
Definition at line 213 of file data_buffer.h.
#define BUF_HEAD_ENTRY | ( | ) | (BUF_ENTRY(BUF_HEAD_IDX())) |
Definition at line 205 of file data_buffer.h.
#define BUF_HEAD_IDX | ( | ) | (dataBufLruList.headEntry) |
Definition at line 203 of file data_buffer.h.
#define BUF_LSA | ( | iEntry | ) | (BUF_ENTRY((iEntry))->logicalSliceAddr) |
Definition at line 219 of file data_buffer.h.
#define BUF_NEXT_ENTRY | ( | iEntry | ) | (BUF_ENTRY(BUF_NEXT_IDX((iEntry)))) |
Definition at line 210 of file data_buffer.h.
#define BUF_NEXT_IDX | ( | iEntry | ) | (BUF_ENTRY((iEntry))->nextEntry) |
Definition at line 208 of file data_buffer.h.
#define BUF_PREV_ENTRY | ( | iEntry | ) | (BUF_ENTRY(BUF_PREV_IDX((iEntry)))) |
Definition at line 209 of file data_buffer.h.
#define BUF_PREV_IDX | ( | iEntry | ) | (BUF_ENTRY((iEntry))->prevEntry) |
Definition at line 207 of file data_buffer.h.
#define BUF_SPARE_ENTRY2ADDR | ( | iEntry | ) | (SPARE_DATA_BUFFER_BASE_ADDR + ((iEntry)*BYTES_PER_SPARE_REGION_OF_SLICE)) |
Definition at line 222 of file data_buffer.h.
#define BUF_TAIL_ENTRY | ( | ) | (BUF_ENTRY(BUF_TAIL_IDX())) |
Definition at line 206 of file data_buffer.h.
#define BUF_TAIL_IDX | ( | ) | (dataBufLruList.tailEntry) |
Definition at line 204 of file data_buffer.h.
#define DATA_BUF_CLEAN 0 |
Definition at line 60 of file data_buffer.h.
#define DATA_BUF_DIRTY 1 |
Definition at line 59 of file data_buffer.h.
#define DATA_BUF_FAIL 0xffff |
Definition at line 58 of file data_buffer.h.
#define DATA_BUF_NONE 0xffff |
Definition at line 57 of file data_buffer.h.
#define FindDataBufHashTableEntry | ( | logicalSliceAddr | ) | ((logicalSliceAddr) % AVAILABLE_DATA_BUFFER_ENTRY_COUNT) |
Definition at line 62 of file data_buffer.h.
#define H_BUF_ENTRY | ( | iEntry | ) | (&dataBufHashTablePtr->dataBufHash[(iEntry)]) |
Definition at line 215 of file data_buffer.h.
#define H_BUF_HEAD_ENTRY | ( | iEntry | ) | (BUF_ENTRY(H_BUF_ENTRY((iEntry))->headEntry)) |
Definition at line 216 of file data_buffer.h.
#define H_BUF_HEAD_IDX | ( | iEntry | ) | (H_BUF_ENTRY((iEntry))->headEntry) |
Definition at line 217 of file data_buffer.h.
typedef struct _DATA_BUF_ENTRY DATA_BUF_ENTRY |
The structure of the data buffer entry.
Since only a limited number of data buffer entries could be maintained in DRAM, the fw must reuse the data buffer entries by maintaining a LRU list which is consist of data buffer entries.
The nodes of the LRU list are linked using the two members prevEntry
and nextEntry
of this structure.
dirty
of that entry is marked as true.Besides storing the data needed by the requests, the data buffer entries are also used as cache to speed up the read/write requests. When a new request is created the fw should first check if there is any data buffer entry cached the data needed by the new request (check ReqTransSliceToLowLevel()
and CheckDataBufHit()
for details).
However, if we simply traverse the LRU list every time we want to check the data buffer, it may be too slow. Therefore, in current implementation, the fw maintains a hash table to reduce the overhead for searching the target data buffer entry that owns the data of target LBA. And the nodes of the hash table are linked together by using the two members hashPrevEntry
and hashNextEntry
of this structure.
Also, since a data buffer may be shared by several requests, every data buffer entry maintains a blocking request queue (by using SSD_REQ_FORMAT::(prev|next)BlockingReq
, and DATA_BUF_ENTRY::blockingReqTail
) to make sure the requests will be executed in correct order (check UpdateDataBufEntryInfoBlockingReq()
for details).
UpdateDataBufEntryInfoBlockingReq()
. typedef struct _DATA_BUF_HASH_ENTRY DATA_BUF_HASH_ENTRY |
The structure of data buffer bucket that records the head and tail data buffer entry index in the bucket.
Similar to the LRU list, this structure only records the head and tail index, therefore we must manage the relation between data buffer entries in this bucket by maintaining the hashPrevEntry
and hashNextEntry
of the data buffer entries.
typedef struct _DATA_BUF_HASH_TABLE DATA_BUF_HASH_TABLE |
The structure of data buffer hash table.
A fixed-sized 1D data buffer bucket array. Used for fast finding the data buffer entry of a given request by the logicalSliceAddr
.
typedef struct _DATA_BUF_LRU_LIST DATA_BUF_LRU_LIST |
The structure of LRU list that records the head and tail data buffer entry index of the LRU list.
This structure only records the head and tail index, therefore we need to manage the relation between data buffer entries by maintaining the prevEntry
and nextEntry
of the data buffer entries in this LRU list.
typedef struct _DATA_BUF_MAP DATA_BUF_MAP |
The structure of data buffer table.
A fixed-sized 1D data buffer array. Used for storing a slice command and managing the relation between data buffer entries.
typedef struct _DATA_BUF_ENTRY * P_DATA_BUF_ENTRY |
typedef struct _DATA_BUF_HASH_ENTRY * P_DATA_BUF_HASH_ENTRY |
typedef struct _DATA_BUF_HASH_TABLE * P_DATA_BUF_HASH_TABLE |
typedef struct _DATA_BUF_LRU_LIST * P_DATA_BUF_LRU_LIST |
typedef struct _DATA_BUF_MAP * P_DATA_BUF_MAP |
typedef struct _TEMPORARY_DATA_BUF_ENTRY * P_TEMPORARY_DATA_BUF_ENTRY |
typedef struct _TEMPORARY_DATA_BUF_MAP * P_TEMPORARY_DATA_BUF_MAP |
typedef struct _TEMPORARY_DATA_BUF_ENTRY TEMPORARY_DATA_BUF_ENTRY |
typedef struct _TEMPORARY_DATA_BUF_MAP TEMPORARY_DATA_BUF_MAP |
The structure of the temp data buffer table.
A fixed-sized 1D temp data buffer array. The number of buffer entries is exactly the number of dies, therefore just choose the target entry by using the dieNo when allocating a temp buffer entry. (check the implementation of AllocateTempDataBuf
).
unsigned int AllocateDataBuf | ( | ) |
Retrieve a LRU data buffer entry from the LRU list.
Choose the LRU data buffer entry from the LRU list, and return it's index.
If the evictedEntry
is DATA_BUF_NONE
, that's an error or the dataBufLruList
is empty.
If the evictedEntry
, namely the last entry of LRU list, exists and:
it's also the head of LRU list:
this means that there is only entry in the LRU list, therefore we don't need to modify the prev/next entry of evictedEntry
.
it's the body of LRU list:
we have to make the prev entry be the new tail of LRU list, and make the evicted entry be the new head of the LRU list.
After the evicted entry being moved from the tail of LRU entry to head, we have to call the function SelectiveGetFromDataBufHashList
to remove the evictedEntry
from its bucket of hash table.
Definition at line 220 of file data_buffer.c.
unsigned int AllocateTempDataBuf | ( | unsigned int | dieNo | ) |
Retrieve the index of temp buffer entry of the target die.
By default, there is only NUM_DIES
entries in the tempDataBuf
, so we can just use the serial number of each die to determine which temp entry should be used.
dieNo | an unique number of the specified die |
Definition at line 288 of file data_buffer.c.
unsigned int CheckDataBufHit | ( | unsigned int | reqSlotTag | ) |
Get the data buffer entry index of the given request.
Try to find the data buffer entry of the given request (with same logicalSliceAddr
) by traversing the correspoding bucket of the given request.
If the request found, the corresponding data buffer entry become the Most Recently Used entry and should be moved to the head of LRU list.
reqSlotTag | the request pool entry index of the request to be check |
Definition at line 127 of file data_buffer.c.
void InitDataBuf | ( | ) |
Initialization process of the Data buffer.
Three buffer related lists will be initialized in this function
There are 16 x NUM_DIES
entries in the dataBuf
, and all the elements of dataBuf
will be initialized to:
dataBuf
array (except for head)dataBuf
array (except for tail)There are 16 x NUM_DIES
entries in the dataBufHashTable
, and all the elements will be initialized to empty bucket, so:
There are NUM_DIES
entries in the tempDataBuf
, and all the elements of it will be initialized to:
And the head/tail of dataBufLruList
points to the first/last entry of dataBuf
, this means the initial dataBufLruList
contains all the data buffer entries, therefore the data buffer should be allocated from the last element of dataBuf
array.
Definition at line 85 of file data_buffer.c.
void PutToDataBufHashList | ( | unsigned int | bufEntry | ) |
Insert the given data buffer entry into the hash table.
Insert the given data buffer entry into the tail of hash table bucket specified by the logicalSliceAddr
of the given entry, and modify the tail (head as well, if needed) of target hash table bucket.
bufEntry | the index of the data buffer entry to be inserted |
Definition at line 319 of file data_buffer.c.
void SelectiveGetFromDataBufHashList | ( | unsigned int | bufEntry | ) |
Remove the given data buffer entry from the hash table.
We may need to modify the head/tail index of corresponding bucket specified by the logicalSliceAddr
of the given data buffer entry.
bufEntry | the index of the data buffer entry to be removed |
Definition at line 349 of file data_buffer.c.
void UpdateDataBufEntryInfoBlockingReq | ( | unsigned int | bufEntry, |
unsigned int | reqSlotTag | ||
) |
Append the request to the blocking queue of the specified data buffer entry.
In current fw implementation, a slice request may be split into several sub-requests, and these sub-requests can share the same data buffer since they must be executed in correct order.
However, since the scheduler may reorder the requests base on the priority, the fw must make sure these sub-requests are executed in the correct order. To do this, each data buffer entry maintains a blocking request queue (DATA_BUF_ENTRY::blockingReqTail
). Whenever a new request is created, its request entry index will be appended to the blocking queue of the data buffer allocated for it.
ReqTransSliceToLowLevel()
, CheckBufDep()
, SelectLowLevelReqQ()
and DATA_BUF_ENTRY
.byfEntry | The data buffer entry index of the newly created request. |
reqSlotTag | The request pool entry index of the newly created request. |
Definition at line 268 of file data_buffer.c.
void UpdateTempDataBufEntryInfoBlockingReq | ( | unsigned int | bufEntry, |
unsigned int | reqSlotTag | ||
) |
Append the request to the blocking queue specified by given temp buffer entry.
Similar to UpdateDataBufEntryInfoBlockingReq()
, but the data buffer is temp buffer.
byfEntry | the temp data buffer entry index of the specified request |
reqSlotTag | the request pool entry index of the request to be |
Definition at line 298 of file data_buffer.c.
|
extern |
|
extern |
Definition at line 51 of file data_buffer.c.
|
extern |
Definition at line 50 of file data_buffer.c.
|
extern |
Definition at line 53 of file data_buffer.c.