Linux內(nèi)核內(nèi)存分配
Linux系統(tǒng)使用了一種稱為“虛擬內(nèi)存”的機(jī)制。虛擬內(nèi)存機(jī)制使得每個(gè)內(nèi)存地址都是虛擬的,這意味著它們不會(huì)直接指向RAM中的任何地址。這樣我們訪問內(nèi)存中的存儲(chǔ)單元時(shí),都會(huì)進(jìn)行地址轉(zhuǎn)換以匹配相應(yīng)的物理內(nèi)存
在Linux系統(tǒng)中,內(nèi)核中的每個(gè)進(jìn)程都表示為一個(gè)task_struct結(jié)構(gòu)體實(shí)例,該結(jié)構(gòu)體實(shí)例表征并描述了這個(gè)進(jìn)程。在進(jìn)程開始運(yùn)行之前,系統(tǒng)會(huì)為其分配一個(gè)內(nèi)存映射表,該表存放在struct mm_struct類型的變量中。在內(nèi)核中,全局變量current時(shí)鐘指向當(dāng)前進(jìn)程,current->mm字段指向當(dāng)前的進(jìn)程內(nèi)存映射表,struct mm_struct結(jié)構(gòu)定義參見include/linux/mm_types.h
地址轉(zhuǎn)換和MMU
MMU不僅可以將虛擬地址轉(zhuǎn)換為物理地址,還可以保護(hù)內(nèi)存免受未經(jīng)授權(quán)的訪問。給定一個(gè)進(jìn)程,需要從此進(jìn)程訪問的任何頁都必須位于一個(gè)VMA中,且必須位于進(jìn)程的頁表中
由于最近訪問的數(shù)據(jù)存放在緩存中,因此最近轉(zhuǎn)換的地址也存放在緩存中。數(shù)據(jù)緩存加快了數(shù)據(jù)訪問過程,TLB則加快了虛擬地址的轉(zhuǎn)換過程。TLB是內(nèi)容可尋址內(nèi)存,其中鍵是虛擬地址,值是物理地址,其運(yùn)作過程如下圖所示
內(nèi)存分配機(jī)制
下圖展示了Linux系統(tǒng)中不同的內(nèi)存分配器。最低級(jí)別的分配器是頁分配器,它以頁為單位分配內(nèi)存,然后是Slab分配器,它建立在頁分配器的基礎(chǔ)上,從中獲取頁并將它們拆分為較小的內(nèi)存實(shí)體,kmalloc分配器依賴于Slab分配器
實(shí)現(xiàn)DMA支持
DMA是計(jì)算機(jī)系統(tǒng)的一種特性,它允許設(shè)備在沒有CPU干預(yù)的情況下訪問主系統(tǒng)內(nèi)存,使CPU嫩鞏固專注于其他任務(wù)。它的使用示例包括網(wǎng)絡(luò)流量加速、音頻數(shù)據(jù)或視頻幀抓取等,它的使用并不限于特定領(lǐng)域。負(fù)責(zé)管理DMA事務(wù)的外圍設(shè)備是DMA控制器,它存在于大多數(shù)現(xiàn)代處理器和微控制器中。
DMA的工作方式如下:當(dāng)驅(qū)動(dòng)程序需要傳輸數(shù)據(jù)塊時(shí),便使用源地址、目標(biāo)地址和要復(fù)制的總字節(jié)數(shù)設(shè)置DMA控制器,然后DMA控制器自動(dòng)將數(shù)據(jù)地址從源地址傳輸?shù)侥繕?biāo)地址,而不會(huì)占用CPU周期。當(dāng)剩余字節(jié)數(shù)為0時(shí),數(shù)據(jù)塊傳輸結(jié)束并通知驅(qū)動(dòng)程序。
DMA引擎API
DMA控制器接口由兩部分組成:控制器和通道。控制器執(zhí)行內(nèi)存?zhèn)鬏敚ǖ绖t是客戶端驅(qū)動(dòng)程序向控制器提交作業(yè)的方式
DMA控制器在Linux內(nèi)核中別抽象為dma_device結(jié)構(gòu)體實(shí)例,其定義如下
struct dma_device {
struct kref ref;
unsigned int chancnt;
unsigned int privatecnt;
struct list_head channels;
struct list_head global_node;
struct dma_filter filter;
dma_cap_mask_tcap_mask;
enum dma_desc_metadata_mode desc_metadata_modes;
unsigned short max_xor;
unsigned short max_pq;
enum dmaengine_alignment copy_align;
enum dmaengine_alignment xor_align;
enum dmaengine_alignment pq_align;
enum dmaengine_alignment fill_align;
#define DMA_HAS_PQ_CONTINUE (1 << 15)
int dev_id;
struct device *dev;
struct module *owner;
struct ida chan_ida;
u32 src_addr_widths;
u32 dst_addr_widths;
u32 directions;
u32 min_burst;
u32 max_burst;
u32 max_sg_burst;
bool descriptor_reuse;
enum dma_residue_granularity residue_granularity;
int (*device_alloc_chan_resources)(struct dma_chan *chan);
int (*device_router_config)(struct dma_chan *chan);
void (*device_free_chan_resources)(struct dma_chan *chan);
struct dma_async_tx_descriptor *(*device_prep_dma_memcpy)(
struct dma_chan *chan, dma_addr_t dst, dma_addr_t src,
size_t len, unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_dma_xor)(
struct dma_chan *chan, dma_addr_t dst, dma_addr_t *src,
unsigned int src_cnt, size_t len, unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_dma_xor_val)(
struct dma_chan *chan, dma_addr_t *src,unsigned int src_cnt,
size_t len, enum sum_check_flags *result, unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_dma_pq)(
struct dma_chan *chan, dma_addr_t *dst, dma_addr_t *src,
unsigned int src_cnt, const unsigned char *scf,
size_t len, unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_dma_pq_val)(
struct dma_chan *chan, dma_addr_t *pq, dma_addr_t *src,
unsigned int src_cnt, const unsigned char *scf, size_t len,
enum sum_check_flags *pqres, unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_dma_memset)(
struct dma_chan *chan, dma_addr_t dest, int value, size_t len,
unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_dma_memset_sg)(
struct dma_chan *chan, struct scatterlist *sg,
unsigned int nents, int value, unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_dma_interrupt)(
struct dma_chan *chan, unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_slave_sg)(
struct dma_chan *chan, struct scatterlist *sgl,
unsigned int sg_len, enum dma_transfer_direction direction,
unsigned long flags, void *context);
struct dma_async_tx_descriptor *(*device_prep_dma_cyclic)(
struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
size_t period_len, enum dma_transfer_direction direction,
unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_interleaved_dma)(
struct dma_chan *chan, struct dma_interleaved_template *xt,
unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_dma_imm_data)(
struct dma_chan *chan, dma_addr_t dst, u64 data,
unsigned long flags);
void (*device_caps)(struct dma_chan *chan,
struct dma_slave_caps *caps);
int (*device_config)(struct dma_chan *chan,
struct dma_slave_config *config);
int (*device_pause)(struct dma_chan *chan);
int (*device_resume)(struct dma_chan *chan);
int (*device_terminate_all)(struct dma_chan *chan);
void (*device_synchronize)(struct dma_chan *chan);
enum dma_status (*device_tx_status)(struct dma_chan *chan,
dma_cookie_t cookie,
struct dma_tx_state *txstate);
void (*device_issue_pending)(struct dma_chan *chan);
void (*device_release)(struct dma_device *dev);
/* debugfs support */
void (*dbg_summary_show)(struct seq_file *s, struct dma_device *dev);
struct dentry *dbg_dev_root;
};
DMA通道的結(jié)構(gòu)體定義如下
struct dma_chan {
int dev_id;/* this channel is allocated if >= 0, */
/* free otherwise */
void __iomem *io;
const char *dev_str;
int irq;
void *irq_dev;
unsigned int fifo_addr;
unsigned int mode;
};
請(qǐng)求DMA通道
dma_request_channel()函數(shù)用于請(qǐng)求一個(gè)通道
struct dma_chan *dma_request_channel(dma_cap_mask_t mask,
dma_filter_fn filter_fn,
void *filter_param);
配置DMA通道
DMA引擎框架使用struct dma_slave_config數(shù)據(jù)結(jié)構(gòu)進(jìn)行配置,該數(shù)據(jù)結(jié)構(gòu)表示DMA通道的運(yùn)行時(shí)配置,這樣客戶端就可以指定諸如DMA方向、DMA地址、總線寬度和DMA突發(fā)成都等外設(shè)的參數(shù),struct dma_slave_config數(shù)據(jù)結(jié)構(gòu)定義如下
struct dma_slave_config {
enum dma_transfer_direction direction;
phys_addr_t src_addr;
phys_addr_t dst_addr;
enum dma_slave_buswidth src_addr_width;
enum dma_slave_buswidth dst_addr_width;
u32 src_maxburst;
u32 dst_maxburst;
u32 src_port_window_size;
u32 dst_port_window_size;
bool device_fc;
void *peripheral_config;
size_t peripheral_size;
};
通過dmaengine_slave_config()函數(shù)將這種配置作用于底層硬件上
static inline int dmaengine_slave_config(struct dma_chan *chan,
struct dma_slave_config *config)
{
if (chan->device->device_config)
return chan->device->device_config(chan, config);
return -ENOSYS;
}
配置DMA傳輸
這一步用于確認(rèn)DMA傳輸?shù)姆绞剑M(jìn)行一次DMA傳輸,就需要用到與DMA通道對(duì)應(yīng)的控制器中的一些函數(shù),這些函數(shù)名為device_prep_dma_*,例如對(duì)于內(nèi)存到內(nèi)存的傳輸,使用device_prep_dma_memcpy()
struct dma_async_tx_descriptor *tx;
struct dma_chan *chan = acdev->dma_chan;
dma_cookie_t cookie;
unsigned long flags = DMA_PREP_INTERRUPT;
int ret = 0;
tx = chan->device->device_prep_dma_memcpy(chan, dest, src, len, flags);
if (!tx) {
dev_err(acdev->host->dev, \"device_prep_dma_memcpy failed\\\\n\");
return -EAGAIN;
}
提交DMA傳輸
為了把事務(wù)放到驅(qū)動(dòng)程序的事務(wù)待處理隊(duì)列中,可以使用dmaengine_submit()函數(shù)
static inline dma_cookie_t dmaengine_submit(struct dma_async_tx_descriptor *desc)
{
return desc->tx_submit(desc);
}
發(fā)出待處理的DMA請(qǐng)求并等待回調(diào)通知
啟動(dòng)傳輸是DMA傳輸設(shè)置的最后一步,可以通過在通道上調(diào)用dma_async_issue_pending()來激活通道待處理隊(duì)列中的傳輸。
static inline void dma_async_issue_pending(struct dma_chan *chan)
{
chan->device->device_issue_pending(chan);
}
發(fā)表于 02-04 22:30
在2025算力互聯(lián)網(wǎng)大會(huì)期間,算力互聯(lián)網(wǎng)服務(wù)論壇在成都成功舉辦。論壇現(xiàn)場舉行了《算力服務(wù)商互聯(lián)能
發(fā)表于 12-31 11:50
?652次閱讀
12月22日,云天勵(lì)飛與360集團(tuán)簽署戰(zhàn)略合作協(xié)議。雙方將圍繞“納米AI”算力底座建設(shè)、大模型安全能力提升以及智慧生活產(chǎn)品打造等方向,充分發(fā)揮各自在資源、場景與技術(shù)方面的優(yōu)勢,聯(lián)合打造國產(chǎn)生態(tài)下的AI推理協(xié)同生態(tài)。
發(fā)表于 12-25 17:09
?519次閱讀
出,人工智能規(guī)模化應(yīng)用驅(qū)動(dòng)算力部署需求全面升級(jí),華為AI WAN解決方案憑借持續(xù)的技術(shù)創(chuàng)新突破,有效解決了跨域算
發(fā)表于 12-25 15:17
?579次閱讀
電子發(fā)燒友網(wǎng)綜合報(bào)道 2025年11月21日,在上海舉辦的“2025 AI容器應(yīng)用落地與發(fā)展論壇”上,華為正式發(fā)布并開源了創(chuàng)新AI容器技術(shù)Flex:ai,為解決算力資源利用難題帶來了全新的思路和解
發(fā)表于 11-26 08:31
?7605次閱讀
在華為全聯(lián)接大會(huì)2025(HUAWEI CONNECT 2025)上,華為發(fā)布最強(qiáng)算力超節(jié)點(diǎn)和集群,并表示將發(fā)展生態(tài)作為公司核心戰(zhàn)略,提升到前所未有的戰(zhàn)略高度。在計(jì)算領(lǐng)域,
發(fā)表于 10-10 17:29
?2239次閱讀
未來,騰視科技將繼續(xù)深耕AI算力模組領(lǐng)域,全力推動(dòng)AI邊緣計(jì)算行業(yè)的深度發(fā)展。隨著AI技術(shù)的不斷演進(jìn)和物聯(lián)網(wǎng)應(yīng)用的持續(xù)拓展,騰視科技的AI算力模組將在更多領(lǐng)域
發(fā)表于 09-19 15:26
?1713次閱讀
未來,騰視科技將繼續(xù)深耕AI算力模組領(lǐng)域,全力推動(dòng)AI邊緣計(jì)算行業(yè)的深度發(fā)展。隨著AI技術(shù)的不斷演進(jìn)和物聯(lián)網(wǎng)應(yīng)用的持續(xù)拓展,騰視科技的AI算力模組將在更多領(lǐng)域
發(fā)表于 09-19 15:25
?829次閱讀
的優(yōu)勢,如高效、徹底、節(jié)能、環(huán)保等。本文將重點(diǎn)介紹非標(biāo)超聲波清洗設(shè)備的最大優(yōu)勢以及如何充分發(fā)揮其特點(diǎn)。一、高效清洗非標(biāo)超聲波清洗設(shè)備通過高頻聲波的作用,能夠在短時(shí)
發(fā)表于 07-08 16:58
?626次閱讀
近日,大唐高鴻信安(浙江)信息科技有限公司(簡稱:高鴻信安)和華為技術(shù)有限公司(簡稱:華為)聯(lián)合開展鯤鵬產(chǎn)品雙認(rèn)證工作,高鴻信安自主研發(fā)的可信支撐模塊V2.0、操作系統(tǒng)可信增強(qiáng)系統(tǒng)V
發(fā)表于 06-26 17:02
?1461次閱讀
園區(qū)超級(jí)智能體”解決方案及聯(lián)合創(chuàng)新中心建設(shè)等核心議題展開深度研討。此次會(huì)議旨在充分發(fā)揮各方專業(yè)優(yōu)勢,加速構(gòu)建具有全球競爭力的自主可控算力生態(tài),為海滄區(qū)打造AI產(chǎn)業(yè)高地提供核心支撐,助力
發(fā)表于 06-23 11:51
?1266次閱讀
為滿足客戶對(duì)電子設(shè)備日益增長的功率和功能的期望,連接器的小型化發(fā)揮了關(guān)鍵作用。然而,尺寸縮減絕不能以犧牲產(chǎn)品的耐用性為代價(jià)。材料科學(xué)在開發(fā)堅(jiān)固耐用小型連接器中至關(guān)重要,使其即使在嚴(yán)苛環(huán)境中也能保持
發(fā)表于 03-07 11:28
?683次閱讀
評(píng)論