国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

http://www.linuxidc.com/Linux/2013-07/86999.htm

2019-11-07 23:55:29
字體:
供稿:網(wǎng)友

內(nèi)核通知鏈

1.1. 概述

linux內(nèi)核中各個子系統(tǒng)相互依賴,當(dāng)其中某個子系統(tǒng)狀態(tài)發(fā)生改變時,就必須使用一定的機制告知使用其服務(wù)的其他子系統(tǒng),以便其他子系統(tǒng)采取相應(yīng)的措施。為滿足這樣的需求,內(nèi)核實現(xiàn)了事件通知鏈機制(notificationchain)。

通知鏈只能用在各個子系統(tǒng)之間,而不能在內(nèi)核和用戶空間進行事件的通知。組成內(nèi)核的核心系統(tǒng)代碼均位于kernel目錄下,通知鏈表位于kernel/notifier.c中,對應(yīng)的頭文件為include/linux/notifier.h。通知鏈表機制并不復(fù)雜,實現(xiàn)它的代碼只有區(qū)區(qū)幾百行。

事件通知鏈表是一個事件處理函數(shù)的列表,每個通知鏈都與某個或某些事件有關(guān),當(dāng)特定的事件發(fā)生時,就調(diào)用相應(yīng)的事件通知鏈中的回調(diào)函數(shù),進行相應(yīng)的處理。

推薦閱讀:

Linux內(nèi)核驅(qū)動開發(fā)之KGDB原理介紹及kgdboe方式配置 http://www.linuxidc.com/Linux/2013-06/86406.htm

Linux內(nèi)核中memcpy和memmove函數(shù)的區(qū)別和實現(xiàn) http://www.linuxidc.com/Linux/2013-06/85344.htm

 

圖 1 內(nèi)核通知鏈

1.2.?dāng)?shù)據(jù)結(jié)構(gòu)

如圖 1中所示,Linux的網(wǎng)絡(luò)子系統(tǒng)一共有3個通知鏈:表示ipv4地址發(fā)生變化時的inetaddr_chain;表示ipv6地址發(fā)生變化的inet6addr_chain;還有表示設(shè)備注冊、狀態(tài)變化的netdev_chain。

在這些鏈中都是一個個notifier_block結(jié)構(gòu):

struct notifier_block {      int (*notifier_call)(struct notifier_block *, unsigned long, void *);      struct notifier_block *next;      int PRiority;};

其中,

1. notifier_call:當(dāng)相應(yīng)事件發(fā)生時應(yīng)該調(diào)用的函數(shù),由被通知方提供,如other_subsys_1;

2. notifier_block *next:用于鏈接成鏈表的指針;

3. priority:回調(diào)函數(shù)的優(yōu)先級,一般默認為0。

內(nèi)核代碼中一般把通知鏈命名為xxx_chain, xxx_nofitier_chain這種形式的變量名。圍繞核心數(shù)據(jù)結(jié)構(gòu)notifier_block,內(nèi)核定義了四種通知鏈類型:

1. 原子通知鏈( Atomic notifier chains ):通知鏈元素的回調(diào)函數(shù)(當(dāng)事件發(fā)生時要執(zhí)行的函數(shù))在中斷或原子操作上下文中運行,不允許阻塞。對應(yīng)的鏈表頭結(jié)構(gòu):

struct atomic_notifier_head {        spinlock_t  lock;        struct  notifier_block *head;};

2. 可阻塞通知鏈( Blocking notifier chains ):通知鏈元素的回調(diào)函數(shù)在進程上下文中運行,允許阻塞。對應(yīng)的鏈表頭:

struct  blocking_notifier_head {        struct  rw_semaphore  rwsem;        struct  notifier_block  *head;};

3. 原始通知鏈( Raw notifierchains ):對通知鏈元素的回調(diào)函數(shù)沒有任何限制,所有鎖和保護機制都由調(diào)用者維護。對應(yīng)的鏈表頭:

 

網(wǎng)絡(luò)子系統(tǒng)就是該類型,通過以下宏實現(xiàn)head的初始化

static RAW_NOTIFIER_HEAD(netdev_chain);#define RAW_NOTIFIER_INIT(name)    {      /              .head= NULL }#define RAW_NOTIFIER_HEAD(name)        /      //調(diào)用他就好了struct raw_notifier_head name =        /                    RAW_NOTIFIER_INIT(name)  即:struct raw_notifier_head netdev_chain = {          .head = NULL;}

而其回調(diào)函數(shù)的注冊,比如向netdev_chain的注冊函數(shù):register_netdevice_notifier。

struct  raw_notifier_head {        struct  notifier_block  *head;};

4. SRCU 通知鏈( SRCU notifier chains ):可阻塞通知鏈的一種變體。對應(yīng)的鏈表頭:

struct  srcu_notifier_head {        struct  mutex mutex;        struct  srcu_struct  srcu;        struct  notifier_block  *head;};

1.3. 運行機理

 

被通知一方(other_subsys_x)通過notifier_chain_register向特定的chain注冊回調(diào)函數(shù),并且一般而言特定的子系統(tǒng)會用特定的notifier_chain_register包裝函數(shù)來注冊,比如路由子系統(tǒng)使用的是網(wǎng)絡(luò)子系統(tǒng)的:register_netdevice_notifier來注冊他的notifier_block。

1.3.1. 向事件通知鏈注冊的步驟

1. 申明struct notifier_block結(jié)構(gòu)

2. 編寫notifier_call函數(shù)

3. 調(diào)用特定的事件通知鏈的注冊函數(shù),將notifier_block注冊到通知鏈中

如果內(nèi)核組件需要處理夠某個事件通知鏈上發(fā)出的事件通知,其就該在初始化時在該通知鏈上注冊回調(diào)函數(shù)。

1.3.2. 通知子系統(tǒng)有事件發(fā)生

inet_subsys是通過notifier_call_chain來通知其他的子系統(tǒng)(other_subsys_x)的。

notifier_call_chain會按照通知鏈上各成員的優(yōu)先級順序執(zhí)行回調(diào)函數(shù)(notifier_call_x);回調(diào)函數(shù)的執(zhí)行現(xiàn)場在notifier_call_chain進程地址空間;其返回值是NOTIFY_XXX的形式,在include/linux/notifier.h中:

#define NOTIFY_DONE            0x0000        /* 對事件視而不見 */#define NOTIFY_OK          0x0001        /* 事件正確處理 */#define NOTIFY_STOP_MASK  0x8000        /*由notifier_call_chain檢查,看繼續(xù)調(diào)用回調(diào)函數(shù),還是停止,_BAD和_STOP中包含該標(biāo)志 */#define NOTIFY_BAD        (NOTIFY_STOP_MASK|0x0002)      /*事件處理出錯,不再繼續(xù)調(diào)用回調(diào)函數(shù) *//* *Clean way to return from the notifier and stop further calls. */#define NOTIFY_STOP            (NOTIFY_OK|NOTIFY_STOP_MASK)    /*  回調(diào)出錯,不再繼續(xù)調(diào)用該事件回調(diào)函數(shù) */

notifier_call_chain捕獲并返回最后一個事件處理函數(shù)的返回值;注意:notifier_call_chain可能同時被不同的cpu調(diào)用,故而調(diào)用者必須保證互斥。

1.3.3. 事件列表

對于網(wǎng)絡(luò)子系統(tǒng)而言,其事件常以NETDEV_XXX命名;描述了網(wǎng)絡(luò)設(shè)備狀態(tài)(dev->flags)、傳送隊列狀態(tài)(dev->state)、設(shè)備注冊狀態(tài)(dev->reg_state),以及設(shè)備的硬件功能特性(dev->features):

include/linux/notifier.h中

/* netdevice notifier chain */#define NETDEV_UP  0x0001  /* 激活一個網(wǎng)絡(luò)設(shè)備 */#define NETDEV_DOWN  0x0002f /* 停止一個網(wǎng)絡(luò)設(shè)備,所有對該設(shè)備的引用都應(yīng)釋放 */#define NETDEV_REBOOT      0x0003      /* 檢查到網(wǎng)絡(luò)設(shè)備接口硬件崩潰,硬件重啟 */#define NETDEV_CHANGE      0x0004  /* 網(wǎng)絡(luò)設(shè)備的數(shù)據(jù)包隊列狀態(tài)發(fā)生改變 */#define NETDEV_REGISTER  0x0005  /*一個網(wǎng)絡(luò)設(shè)備事例注冊到系統(tǒng)中,但尚未激活 */#define NETDEV_UNREGISTER      0x0006      /*網(wǎng)絡(luò)設(shè)備驅(qū)動已卸載 */#define NETDEV_CHANGEMTU      0x0007  /*MTU發(fā)生了改變 */#define NETDEV_CHANGEADDR    0x0008  /*硬件地址發(fā)生了改變 */#define NETDEV_GOING_DOWN  0x0009  /*網(wǎng)絡(luò)設(shè)備即將注銷,有dev->close報告,通知相關(guān)子系統(tǒng)處理 */#define NETDEV_CHANGENAME  0x000A  /*網(wǎng)絡(luò)設(shè)備名改變 */#define NETDEV_FEAT_CHANGE    0x000B  /*feature網(wǎng)絡(luò)硬件功能改變 */#define NETDEV_BONDING_FAILOVER 0x000C  /*    */#define NETDEV_PRE_UP        0x000D  /*    */#define NETDEV_BONDING_OLDTYPE  0x000E              /*    */#define NETDEV_BONDING_NEWTYPE  0x000F      /*    */


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 仪征市| 洪洞县| 共和县| 甘孜县| 江孜县| 张家界市| 盈江县| 长海县| 香港| 庄河市| 禹州市| 河池市| 鲁甸县| 仲巴县| 孟州市| 楚雄市| 桦南县| 牡丹江市| 页游| 昌宁县| 五台县| 阳江市| 桦甸市| 高台县| 东台市| 青神县| 宜兰市| 盘锦市| 霍邱县| 怀宁县| 淮滨县| 江达县| 浦县| 巴东县| 随州市| 吐鲁番市| 天气| 苏州市| 伊吾县| 林西县| 如东县|