新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > Linux 2.6.10內核下PCI Express Native熱插拔框架的實現機制

Linux 2.6.10內核下PCI Express Native熱插拔框架的實現機制

作者: 時間:2008-07-22 來源:網絡 收藏
熱插拔技術,可以有效避免由更換外設引起的服務器系統(tǒng)停機,對于提高服務器系統(tǒng)可用性和可擴展性意義重大。本文討論了 熱插拔所涉及的軟件因素,并基于此,剖析了 插槽熱插拔子系統(tǒng)的關鍵。

一 相關技術與研究

1997年,PCI SIG制定了第一個PCI熱插拔規(guī)范,其中定義了支持熱插拔所必需的平臺、板卡和軟件元素。PCI SIG推出了標準熱插拔控制器規(guī)范(SHPC SPEC),其中明確了熱插拔的標準使用模式和嚴格的寄存器組要求,并且允許操作系統(tǒng)提供商在平臺特定的軟件之外提供熱插拔支持,逐步完成了熱插拔標準制定工作,進入技術的全面推廣階段。 2002年以后,Intel把熱插拔作為一種天然屬性賦予新推出的PCI 規(guī)范,PCI Express熱插拔總結了五年來工業(yè)標準的經驗,具有如下特點:

  • 基于SHPC模式并對其進行了功能擴展;
  • PCI Express從設計上就把熱插拔寄存器集成進入了其標準的性能寄存器組(而在SHPC 1.0中,熱插拔寄存器是附加的);
  • 提供給操作系統(tǒng)一個統(tǒng)一的熱插拔硬件寄存器接口,賦予了操作系統(tǒng)進行原生熱插拔(繞過了傳統(tǒng)基于BIOS的熱插拔方法)的能力;
  • 通過在基本的體系機構層次定義熱插拔必須的硬件要求,完善了一種標準的使用模式;
  • 提供了規(guī)格參數來保證OEM產品的低成本而高平臺可靠性。

具有完整功能的PCI Express熱插拔系統(tǒng)在平臺硬件和固件支持之外,還必須有操作系統(tǒng)以及設備驅動程序的支持。

在各大芯片廠商紛紛推出支持PCI熱插拔的產品的同時,Microsoft,Novell,SCO等公司在他們相關的操作系統(tǒng)中也都包括了支持熱插拔的技術, Novell NetWare 4.115和SCO UnixWare 7以及更新版本支持完整PCI熱插拔(熱替換和熱添加)。Microsoft Windows NT 4.0利用Compaq 服務器支持盤(SSD) for NT 4.0,提供了PCI熱替換支持,進入2000年后,Microsoft Windows 2000也內建了對PCI熱插拔技術的全面軟件支持。對于GNU/,從2001年1月份的2.4版本開始,PCI 熱插拔開始成為其標準特性之一,到2.6 版本,熱插拔功能已經被整合進入核心設備模型?,F在,幾乎所有的發(fā)行版本,包括RedHat, Debian和 United Linux,都對PCI 熱插拔提供了良好支持,并分別有所擴展。BSD分支在這方面起步較晚,OpenBSD在2004年三月份的3.6版本中才出現了不含設備驅動的設備熱插拔參考,而FreeBSD 到5.3版本為止,尚未提供對PCI 熱插拔的支持。

作為2002年出現的規(guī)范,各個通用操作系統(tǒng)對PCI Express的支持才剛剛起步。在微軟公司的 Windows 2000, Windows XP, and Windows Server 2003中,PCI Express設備被當作PCI設備進行熱插拔,其他PCI Express的高級功能可以由固件激活。在Windows Longhorn中,才提供對PCI Express高級特性的原生支持。GNU/Linux在版本2.6.9中開始專門提供對于PCI Express 熱插拔的支持,中間歷經軟件架構的改動,逐漸發(fā)展為以內核版本以及內核版本2.6.12下兩種不同的PCI Express熱插拔驅動架構。本文主要討論所采用的PCI Express熱插拔驅動架構,并在最后給出2.6.12的新特性。

三 PCI Express 熱插拔的軟件支持

根據規(guī)范,一個完整的 PCI Express 熱插拔系統(tǒng)需要幾方面的相互配合,分別為硬件元素、固件元素和軟件元素。硬件元素是指主板總線系統(tǒng)的電氣特性方面的支持,包括熱插拔控制器(Hot-Plug Controller)、卡槽電源切換邏輯(Card Slot Power Switching Logic)、板卡重置邏輯(Card Reset Logic)、電源指示燈(Power Indicator)、提示按鈕(Attention Button)和板卡存在檢測引腳(Card Present Detect Pins)等等;固件元素是指主板BIOS必須對熱插拔提供的支持,要 PCI Express熱插拔,固件必須提供OSHP方法或ACPI _OSC方法之一;軟件元素是指操作系統(tǒng)操綜合使用PCI Express 熱插拔所必須提供的功能組件。

軟件元素

為了操縱平臺的硬件元素,提供PCI Express熱插拔服務,我們必須表1所示的主要熱插拔軟件元素。



PCI Express服務模型

PCIE熱插拔(PCIEHP)子系統(tǒng)中的標準熱插拔系統(tǒng)驅動程序通過檢查PCI Express性能數據結構中的插槽性能寄存器(Slot Capabilities register),來獲取硬件的熱插拔部件信息。這些寄存器所能反映的信息如下:

  1. 插槽是否支持熱插拔
  2. 設備是否支持不通知軟件的突然拔出操作
  3. 提示燈、控制器等硬件元素是否存在

一旦軟件完成了PCI Express設備熱插拔功能的開啟和配置工作,熱插拔行為(例如移出或插入請求,電源故障)就可以向系統(tǒng)熱插拔處理提交系統(tǒng)中斷和電源管理事件。這種熱插拔處理由操作系統(tǒng)獨立提供,圖1展示了PCI Express 熱插拔的服務模型,并展示了它與傳統(tǒng)的基于ACPI的模型之間的區(qū)別。


圖1 PCI Express熱插拔服務模型比較
圖1 PCI Express熱插拔服務模型比較

四Linux 2.6.10 PCIE 熱插拔子系統(tǒng)代碼分析

熱插拔

為了提供PCI Express熱插拔服務,Linux 2.6.10 PCIE熱插拔(PCIEHP)子系統(tǒng)必須實現用戶操作界面、熱插拔服務程序和標準熱插拔系統(tǒng)驅動等熱插拔軟件元素,并使軟件的行為符合熱插拔標準使用模式[4]。另外,一些特定的熱插拔功能必須與支持熱插拔的設備驅動結合在一起發(fā)揮作用。

PCIEHP核內部分的主體是一個核心線程,其控制邏輯以模塊的方式加載入內核,負責監(jiān)控PCI Express總線上的熱插拔事件,并做相關處理;核外部分是一個用戶空間的腳本,從內核中調用,并根據內核傳回的信息執(zhí)行后續(xù)處理過程。

1 熱插拔驅動程序生命周期

從PCIEHP子系統(tǒng)啟動,到子系統(tǒng)被卸載期間,PCIEHP完全接管系統(tǒng)中PCI Express插槽熱插拔事件。

PCIEHP子系統(tǒng)啟動時,首先要開啟用戶態(tài)守護進程。然后初始化通知機制,開啟PCI Express熱插拔事件處理核心線程,為操作系統(tǒng)中各總線數據結構分別預初始化一個熱插拔插槽列表。接著,根據內核編譯時是否指定ACPI式資源管理,初始化設備資源管理方式。最后,根據設備標識,在系統(tǒng)中注冊PCI Express熱插拔驅動程序,并將其綁定到總線上所有可能掛載熱插拔插槽的PCIE橋接設備,然后初始化對應的熱插拔控制器,分配資源,開啟定時的中斷輪詢機制。

卸載PCIEHP子系統(tǒng),首先釋放熱插拔控制器全局列表中每個控制器所占用的資源,釋放熱插拔插槽全局列表中每個插槽所占用的資源,終止通知機制的運行,結束PCI Express熱插拔事件處理核心線程;接著,根據內核編譯時是否指定ACPI式資源管理,釋放相關設備占用的系統(tǒng)資源;然后,注銷PCI Express熱插拔驅動程序;在處理完當前熱插拔事件后,終止核外守護進程。

在PCIEHP加載后,為了在熱插拔執(zhí)行過程中追蹤其狀態(tài)變化,我們把熱插拔插槽的狀態(tài)抽象如下:

  • 靜態(tài) (STATIC STATE ),
    正常工作或者空閑的時段,
  • 開啟前閃爍提示態(tài)(BLINKINGON STATE)
    發(fā)出開啟請求到確認之前的時段
  • 關閉前閃爍提示態(tài) (BLINKINGOFF STATE)
    發(fā)出關閉請求到確認之前的時段
  • 開啟態(tài) (POWERON STATE)
    執(zhí)行開啟操作的時段
  • 關閉態(tài)(POWEROFF STATE)
    執(zhí)行關閉操作的時段

各個插槽狀態(tài)之間的轉換關系如圖2所示:


圖2 插槽狀態(tài)轉換圖
圖2 插槽狀態(tài)轉換圖

2 用戶控制腳本/sbin/hotplug和核內外通信機制

在內核熱插拔處理完畢后,它會在核內調用一個用戶態(tài)腳本hotplug,這個腳本將根據內核提供的信息進行后續(xù)處理工作。它是設備熱插拔通告的用戶空間部分,它接收內核傳出的熱插拔操作類型和環(huán)境變量,處理設備掛載和卸載操作。通常,hotplug會根據設備類型調用一個策略腳本,針對設備和系統(tǒng)當前參數進行后續(xù)的配置工作。例如,對于網卡,可能會調用腳本指定IP地址,網關和域名服務器等等,對于存儲設備,可能會調用mount命令來加載它到文件系統(tǒng)內。

內核傳送給hotplug的信息包含熱插拔操作類型(例如PCI),并且在一個環(huán)境變量中提供本次操作相關信息:

  • 行為種類:添加或刪除
  • 對象設備所屬PCI 類、子類和編程接口
  • 對象制造商標志和設備標志
  • 對象總線地址、插槽地址和功能函數編號

核外的后續(xù)配置工作涉及如下文件:

/etc/hotplug/pci.rc/ect/hotplug/pci.Agent/etc/rc.d/init.d/hotplug

在內核中,由kernel/kmod.c中的函數

int call_usermodehelper (char *path, char **argv, char **envp, int wait)來開啟用戶態(tài)腳本/sbin/hotplug。在參數表中,path表示了所啟動的核外應用程序的路徑,argv是應用程序的參數表,envp是環(huán)境變量列表,wait則指出了是否同步等待應用程序執(zhí)行完畢再返回執(zhí)行結果的狀態(tài)。

3 PCIE 熱插拔模塊構成

為了使用PCI Express Native Hotplug,我們必須在編譯的時候開啟對應的功能模塊。

在內核配置中,PCIE Hotplug對應的開關為HOTPLUG_PCI_PCIE,它依賴于HOTPLUG_PCI。如果你的主板支持PCI Express Native Hotplug,可以選擇Y;如果你只是想把這個驅動作為模塊來編譯,那么選擇M,此模塊叫做pciehp,在源代碼dirverpcihotplugKconfig文件中,你可以看到:

config HOTPLUG_PCI_PCIEtristate "PCI Express Hotplug driver"depends on HOTPLUG_PCI

完整的pciehp模塊功能涉及到如下幾個文件pci_hotplug_core.c, pciehp_core.c,pciehp_ctrl.c,pciehp_pci.c pciehp_hpc.c,另外根據是否開啟了ACPI,包含pciehprm_acpi.c 或者pciehprm_nonacpi.c,在源代碼dirverpcihotplugMakefile文件中,你可以看到:

pci_hotplug-objs	:=	pci_hotplug_core.opciehp-objs		:=	pciehp_core.o	pciehp_ctrl.o	pciehp_pci.o	pciehp_hpc.oifdef CONFIG_ACPI_BUSpciehp-objs += pciehprm_acpi.oelsepciehp-objs += pciehprm_nonacpi.oendif

代碼的主要任務就是在所有支持熱插拔的PCIE橋上加載熱插拔驅動程序,監(jiān)控熱插拔事件,并根據類型,如是熱插入事件、熱拔出事件還是電源故障等分別予以處理。

熱插拔驅動的加載

熱插拔驅動程序的加載所進行的主要工作是開啟并初始化PCIE熱插拔的內核線程,這部分代碼位于/driver/pci/hotplug/pciehp_core.c中。入口函數為:

static int __init pcied_init(void)

#ifdef CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODEpciehp_poll_mode = 1;#endifretval = pcie_start_thread();if (retval)goto error_hpc_init;retval = pciehprm_init(PCI);if (!retval) {retval = pci_register_driver(pcie_driver);dbg("pci_register_driver = %d", retval);info(DRIVER_DESC " version: " DRIVER_VERSION "");}

pcied_init中所涉及的關鍵函數分析如下:

retval = pcie_start_thread();

初始化并開啟通知機制:

pciehp_event_start_thread()啟動事件監(jiān)控處理線程
然后初始化slot列表,系統(tǒng)中每個bus給一個slot列表。
struct pci_func *pciehp_slot_list[256]; 都設為NULL

retval = pciehprm_init(PCI);

原型:int pciehprm_init(enum php_ctlr_type ctlr_type)

初始化資源(區(qū)別兩種情況:acpi和非acpi的)在非acpi的初始化方式下,調用空函數legacy_pciehprm_init_pci();在pcihprm_nonacpi.h中,定義了irq_info,irq_routing_table兩個結構。在acpi初始化方式下,通過pciehprm_acpi_scan_pci()在acpi樹下遍歷搜尋PCI設備。不論acpi和非acpi的,都要求php_ctlr_type為PCI。

retval = pci_register_driver(pcie_driver);

注冊并初始化PCI橋熱插拔驅動程序模塊。

把設備驅動加入已注冊設備驅動列表,即使在期間沒有相應設備出現驅動程序仍然保持有效。

	int count = 0;/* initialize common driver fields */

用來泛化之,可以把drv->driver看作為drv的基類信息

	drv->driver.name = drv->name;drv->driver.bus = pci_bus_type;drv->driver.probe = pci_device_probe;drv->driver.remove = pci_device_remove;drv->driver.kobj.ktype = pci_driver_kobj_type;pci_init_dynids(drv->dynids);count = driver_register(drv->driver);

注意:這里是如何從基類drv->driver一般設備的驅動向子類drv這個pci設備的驅動逆向關聯(lián)的--使用CONTAINER宏

pcie_driver為PCIE驅動程序對象,定義在 pciehp_core.c中

	static struct pci_driver pcie_driver = {//驅動名稱定義為"pciehp".name=	PCIE_MODULE_NAME, // id_table指定探測函數probe所應用的范圍,這里在表中指定為所有的PCI橋設備.id_table	=	pcied_pci_tbl, //probe為指定的設備探測函數.probe	=	pcie_probe, };static struct pci_device_id pcied_pci_tbl[] = {{//此處選擇所有PCI橋.class =        ((PCI_CLASS_BRIDGE_PCI  8) | 0x00),.class_mask =	~0,.vendor =       PCI_ANY_ID,.device =       PCI_ANY_ID,.subvendor =    PCI_ANY_ID,.subdevice =    PCI_ANY_ID,},

設備探測pcie_probe:

static int pcie_probe(struct pci_dev *pdev, const struct pci_device_id *ent)in pcie-core.c

已經確定了pdev就是pcie_driver 所匹配的PCI橋設備,而且它在pcie_driver中所對應的設備特征號是*ent,就可以對其進行進一步的初始化和探測。

具體行為如下:

  • 綁定熱插拔插槽
  • 設置了控制器及其狀態(tài)
  • 注冊中斷處理函數
  • 讀寫配置頭,然后分配資源,最后對插槽檢測,掛接

熱插拔事件的監(jiān)控處理線程

熱插拔驅動程序對于熱插拔事件的輪詢和通知采用異步機制,對熱插拔功能部件的操縱是通過讀寫相關寄存器組進行的。主要功能函數關系請參見圖3:


圖3 插槽熱插拔事件處理函數關系
圖3 插槽熱插拔事件處理函數關系

圖3中主要函數的功能介紹如下:

A插槽事件監(jiān)控線程

作為熱插拔活動最直接的信息,插槽事件由硬件操作并置位相關寄存器組,系統(tǒng)軟件可以通過定時輪詢或者中斷方式獲取事件信息,執(zhí)行對應的事件預處理函數。插槽事件如下:

  • 熱插拔命令到達
  • 插槽鎖狀態(tài)改變
  • 適配卡存在狀態(tài)改變
  • 電源出現故障

php_ctlr->int_poll_timer.function = int_poll_timeout 其中php_ctlr是熱插拔控制器狀態(tài)php_ctlr_state_s類型,它定義于pciehp_hpc.h中,記錄當前熱插拔控制器重要狀態(tài),被用作HPC(controller)的控制器句柄;熱插拔控制器controller位于文件pciehp.h中,描述了PCIE熱插拔控制器的特征;

定時輪詢函數原型如下:

static void int_poll_timeout(unsigned long lphp_ctlr)
其中調用pcie_isr( 0, (void *)php_ctlr, NULL );
當最后一個參數是NULL時,采用polling機制。
static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs);
輪詢機制通過定期(2second,使用一個計時器)讀取ctrller對應的狀態(tài)寄存器,來獲取事件,然后調用ctrl狀態(tài)參量對應的事件處理函數。也就是按鈕、電源、MRL等等事件處理函數,并分別調用event_semaphore來激活event_thread.

B事件預處理函數

在插槽事件監(jiān)控線程截獲插槽事件后,它根據事件類型調用這組處理函數,執(zhí)行完畢后,填寫對應控制器上所掛接的事件隊列,并激活睡眠等待的處理線程??梢约せ钏咧械奶幚砭€程的函數包括如下幾個:

pciehp_handle_attention_button :處理按鈕事件
pciehp_handle_switch_change:處理開關狀態(tài)改變事件
pciehp_handle_presence_change:處理存在性狀態(tài)變化事件
pciehp_handle_power_fault:處理電源故障事件
pushbutton_helper_thread:按鈕動作處理線程

C熱插拔事件處理核心線程event_thread

event_thread的處理過程如下:
在一個無限循環(huán)中,阻塞等待插槽事件發(fā)生
當線程被某一事件喚醒后,
如果 熱插拔請求已通過延時確認
進入熱插拔請求處理函數
否則
輪詢熱插拔控制器隊列:
把控制器作為參數傳給插槽事件處理函數
其中

if (pushbutton_pending)pciehp_pushbutton_thread(pushbutton_pending);else if (surprise_rm_pending)pciehp_surprise_rm_thread(surprise_rm_pending);

前一個處理按鈕事件,后一個處理突然拔出事件。

參數pushbutton_pending是由如下函數提供的:

static void pushbutton_helper_thread(unsigned long data){pushbutton_pending = data;up(event_semaphore);

而這個函數又被作為定時task事件的行動部分,賦值給

static void interrupt_event_handler(struct controller *ctrl)中的
p_slot->task_event.function:
函數:
p_slot->task_event.function
= (void (*)(unsigned long)) pushbutton_helper_thread;
參數:
p_slot->task_event.data
= (unsigned long) p_slot;

D插槽事件處理函數interrupt_event_handler

根據控制器信息,獲取控制器對應插槽事件
尚有事件等待處理,則執(zhí)行以下內容:

逐一查看控制器所掛接事件隊列的每個成員(根據事件類型):

1. 請求取消
取消前五秒內觸發(fā)的一次熱插拔請求

2. 請求觸發(fā)
觸發(fā)一次熱插拔操作:導致一個五秒鐘的延時,如果五秒內請求沒有被拒絕,則確認前一個熱插拔請求

3. 電源故障
彈出提示信息

4. 其他
讀取插槽的功能寄存器,更新狀態(tài)信息。

E熱插拔請求處理函數pciehp_pushbutton_thread

一個定期運行的程序,處理當前插槽上阻塞的請求,根據請求類型:對插槽中的設備進行熱移出(F)或者熱添加操作(G)。

F插槽熱拔出設備pciehp_disable_slot

保證所除去的不是視頻控制器
卸載所除去的適配卡占用的系統(tǒng)資源,更新總線結構,關閉電源
通知用戶態(tài)守護進程
更新插槽狀態(tài)

G插槽熱添加設備pciehp_enable_slot

1. 執(zhí)行適配卡添加的一系列相關操作: 失敗恢復預處理,存在性檢驗、打開電源,檢查link training狀態(tài),獲取設備基本信息,配置設備,為設備建立相關數據結構,掛接到上級總線等。

2. 為新添加的設備查找并掛接驅動程序。

3. 特別地,對于橋接設備,把它掛接到上級總線后,還要繼續(xù)對其下級總線進行掃描和掛接。

4. 通知用戶態(tài)守護進程。

5. 更新插槽狀態(tài)。

五 PCIE板卡熱插拔的標準過程

熱插拔PCI板卡可以使用提示按鈕或用戶界面來進行,下面我們介紹使用用戶界面來啟動熱插入和熱拔出的操作過程,以及Fedora C4T2下所采用的方式。

設備的熱插入

1. 操作員安裝卡,閉合插槽保護鎖,保護鎖感應器通知熱插拔控制器把連接信號接通到插槽。

2. 然后,操作員通知熱插拔服務程序:卡已經被安裝并可以激活。軟件提示用戶對此進行確認。

3. 在操作員請求連接后,熱插拔服務程序向控制著熱插拔控制器的熱插拔系統(tǒng)驅動程序下達命令,閃爍插槽的電源指示燈,提示操作員此時不可以拔動適配卡。

4. 在熱插拔軟件對此請求進行確認期間內,電源指示燈繼續(xù)閃爍。注意此時軟件可能會拒絕這個安裝請求(例如,安全策略此刻禁止插槽被激活)。另外,如果請求沒有生效,軟件拒絕請求并對熱插拔控制器發(fā)出命令關閉電源指示燈。規(guī)范建議軟件通過一條消息通知操作員請求被拒絕的原因。

5. 如果請求被確認,熱插拔服務程序對熱插拔系統(tǒng)驅動發(fā)出請求,為插槽加電。

6. 加電后,軟件發(fā)出命令完全打開電源指示燈。

7. 當link training完成后,操作系統(tǒng)指示平臺配置程序賦予適配卡必需的資源,來配置適配卡的功能。

8. 操作系統(tǒng)為PCI Express設備中的功能尋找恰當的驅動程序,并加載之。

9. 接著系統(tǒng)調用驅動程序的初始化入口,并執(zhí)行驅動的初始化代碼。這些代碼完成設備的設置,并填寫設備的PCI 配置命令寄存器的相關標志位來激活設備。

熱移出設備

1. 操作員通過指定適配卡所在物理插槽號碼來初始化移出請求。

2. 軟件彈出窗口要求操作員確認請求。注意,此時電源指示燈保持開啟狀態(tài)。

3. 操作員確認請求后,熱插拔服務程序向熱插拔系統(tǒng)驅動發(fā)出請求,要求熱插拔控制器閃爍電源指示燈。注意此時軟件可能會拒絕這個移出請求(例如,適配卡目前正被關鍵系統(tǒng)功能所使用)。另外,如果請求沒有被確認,軟件將拒絕請求并對熱插拔控制器發(fā)出命令,重新開啟電源指示燈。規(guī)范建議軟件通過一條消息通知操作員請求被拒絕的原因。

4. 如果請求被確認,熱插拔服務程序將命令適配卡的設備驅動保持靜默,也就是說驅動一方面必須停止向適配卡發(fā)出請求,另一方面必須完成或者終止所有已經發(fā)出的請求,并禁止適配卡產生新的事務(包括中斷)。

5. 軟件發(fā)出命令,通過在插槽所連接的根端口或交換端口中的鏈接控制寄存器禁掉適配卡的鏈接。這使得鏈接兩側的端口均被禁止。

6. 軟件指示熱插拔控制器禁掉插槽。

7. 成功切斷電源后,軟件發(fā)出關閉電源指示燈命令。指示燈熄滅后,操作員可以開始安全地從插槽移出適配卡。打開插槽安全鎖,熱插拔控制器從插槽上撤除所有的信號(例如SMBus 和Vaux),此時卡可以被移出。

8. 操作系統(tǒng)釋放內存空間,I/O空間,中斷線等曾經屬于該設備的系統(tǒng)資源。

Fedora下所采用熱插拔實現的方式

如果在最近一次編譯中選擇了PCI Express 熱插拔功能,而且驅動是以模塊方式存在,那么,可以在命令行下鍵入以下內容:

modprobe pciehp

如果驅動成功,則可以在/sys/bus/pci/slots/下面發(fā)現以可熱插拔插槽編號命名的目錄,進入相關目錄,可以進行下一步操作。

echo 1 >power開啟某個插槽上的電源 ,進行熱插入

echo 0 >power關閉某個插槽上的電源,執(zhí)行熱拔出

若不能加載pciehp驅動,一般是由于硬件不支持或者固件缺少OSHP方法或ACPI _OSC方法之一。

六 linux2.6.12中PCIE驅動模型的變化

在linux2.6.10中,Linux驅動程序模型要求物理設備被單獨的驅動程序獨占訪問。 PCI Express端口是一個擁有許多獨立功能的PCI-PCI橋設備,作為一個簡潔的方案,每個功能要分別實現其自己的驅動程序,但是這樣造成了多個驅動程序在唯一的PCI-PCI橋設備中出現競爭的狀況。也就是說,雖然PCI Express提供了如Power Management (PME)、 Advanced Error Reporting (AER)、 Hot-Plug (HP) 和Virtual Channel (VC) access等多種功能,但是如果某個PCI Express端口的native hotplug 驅動程序加載后,它就會獨占這個PCI-PCI橋的端口,內核就不能再于其上加載其他功能的驅動程序了。為解決這個問題,在Linux內核版本2.6.12中,PCI Express的熱插拔又有所改變,提出了PCI Express 端口總線驅動程序(PCI Express Port Bus Driver)的概念。

在實現上,PCI Express 端口總線驅動程序管理主板上的所有PCI Express 端口,并且把所有提供的服務請求發(fā)送到對應的服務驅動程序上。其優(yōu)點概括如下:

  • 允許多個服務驅動程序在一個PCI-PCI橋端口設備上同步運行。
  • 允許各個服務驅動程序相互不受干擾地獨立實現。
  • 允許一個服務驅動程序在多個PCI-PCI橋端口設備上運行。
  • 管理PCI-PCI橋端口設備資源并分發(fā)它們到發(fā)出請求的服務驅動程序。

例如,在注冊熱插拔驅動程序時,不再使用pci_register_driver直接向系統(tǒng)注冊,而是使用int pcie_port_service_register(struct pcie_port_service_driver *new) 向端口總線驅動程序注冊;在注銷熱插拔驅動程序時,不再使用pci_unregister_driver直接向系統(tǒng)注銷,而是使用void pcie_port_service_unregister(struct pcie_port_service_driver *new)來向端口總線驅動程序注銷;而端口總線驅動程序是直接注冊注銷到系統(tǒng)的。

目前,PCI Express 端口總線驅動程序模型還在發(fā)展演變中。

七 評估與總結

根據可用性理論,系統(tǒng)的可用度可以使用下列公式來計算:



在高負荷運轉的服務器上,商用可靠性的元件的故障更換并非小概率事件,對于更換故障元件和升級配件這樣的事件,沒有熱插拔支持的系統(tǒng)必須停機斷電進行處理,而具備熱插拔支持的系統(tǒng)則僅僅需要很少的軟件切換和拔插時間開銷。從上面的公式我們可以看出,MTTR值越小,系統(tǒng)的可用性就越高。我們定義了一個比例因子V,V= MTTRnoHP/MTTRHP,根據業(yè)界經驗,V的取值一般在10-100之間。描述可用性的一種常用的方法是使用"9"。如三個 9 表示 99.9% 的可用性,它表示一年大約有 8.5 小時的服務中斷期。四個 9 (99.99%) 是更高一級的可用性,表示一年大約有 1 小時的服務中斷期。根據可用度公式計算,在單個元件可靠度不變的情況下,Linux操作系統(tǒng)對PCI Express熱插拔的支持,可以使服務器系統(tǒng)的外設相關可用性躍升一個等級(1個9),同時,PCI Express熱插拔技術使得在線更換和升級PCI Express外設板卡成為可能,這使系統(tǒng)獲得了良好的可擴展性。

綜上所述,本文討論了PCI Express熱插拔所涉及的軟件因素,分析了linux2.6.10的PCI Express插槽熱插拔功能PCIEHP子系統(tǒng),并對熱插拔支持在提高服務器系統(tǒng)外設相關可用性的作用進行了定量的分析。為了繼續(xù)提高操作系統(tǒng)可用性和可擴展性支持能力,Linux PCI Express hotplug以下方面還有待發(fā)展:繼續(xù)完善熱插拔架構的開放性,以提供完整統(tǒng)一的接口供驅動開發(fā)人員編寫其他設備的熱插拔支持模塊;在插槽熱插拔之外,提供對Server IO Module(SIOM)熱插拔的支持;完善熱替換和熱升級技術。這些問題都是非常具有挑戰(zhàn)性的。

linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)

linux相關文章:linux教程




評論


相關推薦

技術專區(qū)

關閉