日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

第四章 第四节 per_cpu

發(fā)布時(shí)間:2023/12/20 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第四章 第四节 per_cpu 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

我們上一章說(shuō)了

實(shí)現(xiàn)內(nèi)核同步的方法很多,如下表

技術(shù)

說(shuō)明

適用范圍

每CPU變量

在CPU之間復(fù)制數(shù)據(jù)結(jié)構(gòu)

所有CPU

原子操作

對(duì)一個(gè)計(jì)數(shù)器原子地“讀-修改-寫(xiě)”的指令

所有CPU

內(nèi)存屏障

避免指令重新排序

本地CPU或所有CPU

自旋鎖

加鎖時(shí)忙等

所有CPU

信號(hào)量

加鎖時(shí)阻塞等待

所有CPU

順序鎖

基于訪問(wèn)計(jì)數(shù)器的鎖

所有CPU

本地中斷的禁止

禁止單個(gè)CPU上的中斷處理

本地CPU

本地軟中斷的禁止

禁止單個(gè)CPU上的可延遲函數(shù)處理

本地CPU

讀-復(fù)制-更新(RCU)

通過(guò)指針而不是鎖來(lái)訪問(wèn)共享數(shù)據(jù)結(jié)構(gòu)

所有CPU

但是這個(gè)每CPU變量,讓我看起來(lái)非常的拗口,什么是每CPU變量,我剛開(kāi)始看的時(shí)候,以為別人寫(xiě)錯(cuò)了,后面又查了很多資料,確定是對(duì)的,才放心,原來(lái)是翻譯的問(wèn)題

優(yōu)點(diǎn)

per_cpu的好處是訪問(wèn)它不需要加鎖,而且這個(gè)變量存在CPU的cache里,訪問(wèn)速度會(huì)非常快

原英文是 per_cpu

/*

* Add a offset to a pointer but keep the pointer as is.

*

* Only S390 provides its own means of moving the pointer.

*/

#ifndef SHIFT_PERCPU_PTR

/* Weird cast keeps both GCC and sparse happy. */

#define SHIFT_PERCPU_PTR(__p, __offset) ({ \

__verify_pcpu_ptr((__p)); \

RELOC_HIDE((typeof(*(__p)) __kernel __force *)(__p), (__offset)); \

})

#endif

/*

* A percpu variable may point to a discarded regions. The following are

* established ways to produce a usable pointer from the percpu variable

* offset.

*/

#define per_cpu(var, cpu) \

(*SHIFT_PERCPU_PTR(&(var), per_cpu_offset(cpu)))

既然這么拗口,我覺(jué)得就沒(méi)有必要翻譯了,直接說(shuō)明是per_cpu 就好了

怎么使用這個(gè) per_cpu 呢?

在源碼

drivers\cpufreq\cpufreq_userspace.c

下面有一個(gè)使用的歷程

聲明一個(gè) per_cpu

static DEFINE_PER_CPU(unsigned int, cpu_is_managed);

#define DEFINE_PER_CPU(type, name) \

DEFINE_PER_CPU_SECTION(type, name, "")

使用一個(gè)per_cpu

get_cpu_var(var) 和 set_cpu_var(var)

使用另一個(gè)CPU的per_cpu變量

per_cpu(cpu_cur_freq, freq->cpu) = freq->new;

導(dǎo)出一個(gè)per_cpu 變量供其他模塊使用

EXPORT_PER_CPU_SYMBOL(per_cpu_var);

EXPORT_PER_CPU_SYMBOL_GPL(per_cpu_var);

注意!!

在使用per_cpu的時(shí)候,記得禁止內(nèi)核搶占

DECLARE_PER_CPU(int, mycounter);

● int cpu;

● preempt_disable(); //禁止搶占

● cpu = smp_processor_id();

● per_cpu(mycounter, cpu) += 1;

● preempt_enable(); //開(kāi)啟內(nèi)核搶占

SMP系統(tǒng)chcae 命中

什么是smp 系統(tǒng)呢?就是有幾個(gè) CPU組成的芯片,就是我們通常說(shuō)的幾核幾核的說(shuō)法,大概的圖像這樣

? ? ? ? ? ? ? ? ? ? ? ?

per_cpu解決的是多個(gè)CPU上共享數(shù)據(jù)的問(wèn)題,如果聲明了一個(gè)變量A,這個(gè)變量A在每個(gè)CPU下都有自己的副本,使用的堆棧地址也不一樣,但是如果改變了A的值,其他的CPU同樣能獲取這個(gè)改變的值。

這樣的話每個(gè)CPU只要關(guān)心單個(gè)CPU的并發(fā)問(wèn)題,不用考慮多CPU的互斥加鎖并發(fā)問(wèn)題。

聲明和定義Per-CPU變量的API

描述

DECLARE_PER_CPU(type, name)?

DEFINE_PER_CPU(type, name)

普通的、沒(méi)有特殊要求的per cpu變量定義接口函數(shù)。沒(méi)有對(duì)齊的要求

DECLARE_PER_CPU_FIRST(type, name)?

DEFINE_PER_CPU_FIRST(type, name)

通過(guò)該API定義的per cpu變量位于整個(gè)per cpu相關(guān)section的最前面。

DECLARE_PER_CPU_SHARED_ALIGNED(type, name)?

DEFINE_PER_CPU_SHARED_ALIGNED(type, name)

通過(guò)該API定義的per cpu變量在SMP的情況下會(huì)對(duì)齊到L1 cache line ,對(duì)于UP,不需要對(duì)齊到cachine line

DECLARE_PER_CPU_ALIGNED(type, name)?

DEFINE_PER_CPU_ALIGNED(type, name)

無(wú)論SMP或者UP,都是需要對(duì)齊到L1 cache line

DECLARE_PER_CPU_PAGE_ALIGNED(type, name)?

DEFINE_PER_CPU_PAGE_ALIGNED(type, name)

為定義page aligned per cpu變量而設(shè)定的API接口

DECLARE_PER_CPU_READ_MOSTLY(type, name)?

DEFINE_PER_CPU_READ_MOSTLY(type, name)

通過(guò)該API定義的per cpu變量是read mostly

per_cpu 在內(nèi)存中固定的section

? ? ? ? ? ? ? ? ? ? ? ?

參考資料:(公眾號(hào)后臺(tái)回復(fù) per_cpu ?獲取)

? ? ? ? ? ? ? ? ? ? ? ?

推薦閱讀:

第4章 第三節(jié) 內(nèi)核同步

第4章 原子操作 第二節(jié)


總結(jié)

以上是生活随笔為你收集整理的第四章 第四节 per_cpu的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。