nkjmkzk.net

powered by Kazuki Nakajima

Archive for the ‘pci-passthrough’ tag

Oracle VMをCisco UCS + Palo(M81KR)で検証しました

8/6のOracle VM Forumで発表させていただきましたが、Oracle VMとCisco UCSを組み合わせて検証しました。検証の焦点はCisco UCSに装着したCNA, 「Palo」ことM81KRを認識できるかということと、その性能です。

M81KRはmezzanine cardですが一枚のM81KRで最大128個の仮想NICを作成できるところがポイントです。さらにOS側には特段SR-IOV対応等は必要ありません。OSはM81KRで作成された仮想NICを普通のPCIデバイスとして認識します。

Cisco UCS M81KR 仮想インターフェイス カード

結論から言うとまず認識に関してはまったく問題ありませんでした。

Oracle VM Serverでlspciコマンドを実行し、認識しているPCIデバイスを確認するとM81KRで作成した仮想NICは下記のように表示されます。

[root@vmserver]# lspci
0c:00.0 Ethernet controller: Cisco Systems Inc 10G Ethernet NIC (rev a2)
0d:00.0 Ethernet controller: Cisco Systems Inc 10G Ethernet NIC (rev a2)
0e:00.0 Ethernet controller: Cisco Systems Inc 10G Ethernet NIC (rev a2)
0f:00.0 Ethernet controller: Cisco Systems Inc 10G Ethernet NIC (rev a2)
10:00.0 Ethernet controller: Cisco Systems Inc 10G Ethernet NIC (rev a2)

lspciの出力は、デバイスから得られるPCI IDと、/usr/share/hwdata/pci.idsに格納されているPCI IDを照合してデバイス名を表示しています。したがってlspciでデバイス名が得られたからといってドライバがこのデバイスを認識しているかどうか(つまりNICとして使用可能な状態かどうか)は別問題です。

M81KRが作成する仮想NICを利用するにはenicというドライバが必要になります。これはまだ多くのLinuxディストリビューションには含まれていないため、別途Ciscoさんのサイトからダウンロードしてインストールする必要があります。RHEL5.x, OEL5.xであればRPMが用意されています。しかし今回僕も初めて気がつきましたが、Oracle VM Server 2.2.1はこのenicドライバを標準でインストールしてあります。なのでM81KRで作成した仮想NICはOracle VM Serverからは別途ドライバをインストールせずともNICとして正しく認識され、ethX, xenbrXが自動的に作成されます。

一方、この仮想NICを有効活用するにはPCI Passthroughが効果的でしょう。その場合はこのデバイスに対するドライバが必要となるのはゲストOS(仮想マシン)の方です。Passthrough設定を行うとVM Server(つまりdom0)からはそのNICは見えなくなります(ただし依然としてlspciの出力には現れます)。したがってPassthroughした先のゲストOSでこのNICを利用するにはゲストOS側にenicドライバをインストールする必要があります。

RHEL5.x, OEL5.xではenicドライバはバンドルされていませんが、RHEL6.x, OEL6.xでは標準でバンドルされるようです。

2010年8月時点ではOracle VM ServerでのPCI Passthroughは公式サポートされていません。チャレンジャーな方は下記に手順を紹介しますのでトライしてみてください。

Oracle VM Serverで上記の仮想NICをPassthroughするにはまずUCSの該当ブレードでVT-d(I/O Virtualization)がEnabledとなっていることを確認します。
次にOracle VM Serverのgrub.confを編集してI/O Virtualizationを有効にしてOSを再起動します。

title Oracle VM Server-ovs (xen-64-3.4.0 2.6.18-128.2.1.4.25.el5ovs)
        root (hd0,0)
        kernel /xen-64bit.gz dom0_mem=547M iommu=pv
        module /vmlinuz-2.6.18-128.2.1.4.25.el5xen ro root=UUID=f1b13de3-adb2-4b5a-a6e9-a8beda1b4f73
        module /initrd-2.6.18-128.2.1.4.25.el5xen.img

OSが起動したら下記のコマンドでI/O Virtualizationが有効化されていることを確認します。

[root@vmserver]# xm dmesg | grep 'I/O virtualisation'
(XEN) I/O virtualisation enabled
(XEN) I/O virtualisation for PV guests enabled

次にmodprobe.confに下記の記述を追加し、再起動を行います。これはdom0からPCIデバイスを隠蔽するための設定です。(0000:0c:00.0はdom0用に残しておきます)

install enic /sbin/modprobe pciback ; /sbin/modprobe --first-time --ignore-install enic
options pciback hide=(0000:0d:00.0)(0000:0e:00.0)(0000:0f:00.0)(0000:10:00.0)

ifconfig -a等でインターフェースを確認してみるとと、先ほどまでこれらの仮想NICにひもづいて作成されていたethXやxenbrXがなくなるはずです。

その代わりにPCIデバイスはPassthrough用にプールされています。xmコマンドで確認可能です。

[root@vmserver]# xm pci-list-assignable-device
0000:0d:00.0
0000:0e:00.0
0000:0f:00.0
0000:10:00.0

ここにリストされているPCIデバイスはゲストOSにPassthrough可能になっています。仮想マシンの設定ファイルを編集してPCIデバイスを割り当てます。ここではPVHVMを使用しています。

単なるHVMでももちろん可能ですが、PVMの場合はPVMのgrub.confにも少し設定が必要です。

ネットワークの内部構成は下図のようになります。

スクリーンショット(2010-08-07 13.40.36)

[root@vmserver]# vi /OVS/running_pool/oel55-phvm-01/vm.cfg
acpi = 1
apic = 1
builder = 'hvm'
device_model = '/usr/lib/xen/bin/qemu-dm'
disk = ['file:/OVS/running_pool/oel55-phvm-01/System.img,hda,w']
kernel = '/usr/lib/xen/boot/hvmloader'
keymap = 'en-us'
memory = 1000
name = 'oel55-phvm-01'
on_crash = 'restart'
on_reboot = 'restart'
pae = 1
serial = 'pty'
timer_mode = '2'
uuid = '313105b6-15ac-d7ea-de41-0ef0a90d302a'
vcpus = 4
vif = ['bridge=xenbr0,mac=00:16:3E:42:C7:A9,type=netfront'] #これはPVドライバを利用したインターフェース
vif_other_config = []
pci = ['0000:0d:00.0'] #PCI Passthroughの設定
vnc = 1
vncconsole = 1
vnclisten = '0.0.0.0'
vncpasswd = ''
vncunused = 1

これでゲストOSを起動します。まだゲストOSにenicドライバをインストールしていない場合はインストールします。
ドライバ:http://tools.cisco.com/support/downloads/go/ImageList.x?relVer=1.3%281e%29&mdfid=283004074&sftType=Unified+Computing+System+%28UCS%29+Tools+and+Drivers+Bundle&optPlat=Linux&nodecount=2&edesignator=null&modelName=Cisco+UCS+B200+M2+Blade+Server&treeMdfId=282558030&treeName=Unified+Computing&modifmdfid=&imname=&hybrid=Y&imst=N&lr=Y
*アカウントが必要です

[root@guest]# rpm -ivh kmod-enic-1.3.1c-rhel5u5.x86_64.rpm

そしてlspciコマンドで仮想NICをPCIデバイスとして認識できているか確認します。

[root@guest]# lspci | grep Cisco
00:03.0 Ethernet controller: Cisco Systems Inc VIC Ethernet NIC (rev a2)

ドライバをロードしてネットワークインターフェースが認識されることを確認します。

[root@guest]# ls /sys/class/net
eth0 lo sit0
[root@guest]# modprobe enic
[root@guest]# ls /sys/class/net
eth0 eth1 lo sit0

あとはいつも通りネットワークインターフェースを設定するだけです。

性能値についてはOracle社のポリシー上公開できないのですが、かなりの値が期待できると思っていただいて間違いないでしょう。また、スピードが速い、というだけでなくdom0へのCPUインパクトが激減(というかほぼゼロ)になるのが素晴らしいところです。

without comments

Written by 中嶋 一樹

8月 7th, 2010 at 1:48 pm

Posted in Uncategorized

Tagged with , , , , ,

VT-dを使ってXenでPCI-Passthroughを設定する手順

システム環境

  • CPU: Intel Core-i7 860
  • チップセット: Intel P55 Express
  • マザーボード: MSI P55M-SD40
  • Xen: 3.4.0
  • dom0: Oracle VM Server (Oracle Enterprise Linux 5.3ベース)
  • Passthrough対象のdomU: OpenSolaris b134 PVHVM

Xenは既にインストールされているという前提で始めます。/etc/grub.confのkernel行に「iommu=pv」と追記してI/O Virtualizationを有効化します。*これはBIOSでの有効とは異なります。BIOSでI/O Virtualizationを有効にした上でこの設定を行います。参考までにgrub.conf全体を。

default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title Oracle VM server (2.6.18-128.2.1.4.25.el5xen)
	root (hd0,0)
	kernel /xen-64bit.gz dom0_mem=564M iommu=pv
	module /vmlinuz-2.6.18-128.2.1.4.25.el5xen ro root=UUID=d060bc44-d5d2-49ec-8312-222c761a3746
	module /initrd-2.6.18-128.2.1.4.25.el5xen.img

*より一般的にはiommu=1と設定しますが、これではPVM(準仮想化マシン)に対してのPassthroughが有効にならないのでiommu=pvとしています。iommu=pvとすればHVM, PVM双方でPassthroughが有効になります。

ここで一度OSを再起動します。再起動後、xm dmesgコマンドを発行してI/O Virtualizationが有効になったことを確認します。

[root@vmserver]# xm dmesg | grep "I/O virtualisation"
(XEN) I/O virtualisation enabled
(XEN) I/O virtualisation for PV guests enabled

*ちなみにgrepする場合はvirtualizationではなく上記のようにvirtualisationで引っ掛けてください。

次にdomUにPassthroughしたいPCIデバイスをdom0から隠します。作業の流れとしては、まず対象となるPCIデバイスのBDFを求めます(BDFについて詳しくはこちら)。次にPCIデバイスをdom0から隠すためのカーネルモジュール「pciback」をロードします。そしてsysファイルシステムを使うか、modprobe.confに適当な記述を行うことでPCIデバイスをdom0から隠しdomUにPassthrough可能な状態にします。

BDFはlspciコマンドでPCIデバイスの一覧を表示させ、それっぽいモノを判別します。

[root@vmserver]# lspci
00:00.0 Host bridge: Intel Corporation Clarksfield/Lynnfield DMI (rev 11)
00:03.0 PCI bridge: Intel Corporation Clarksfield/Lynnfield PCI Express Root Port 1 (rev 11)
00:08.0 System peripheral: Intel Corporation Clarksfield/Lynnfield System Management Registers (rev 11)
00:08.1 System peripheral: Intel Corporation Clarksfield/Lynnfield Semaphore and Scratchpad Registers (rev 11)
00:08.2 System peripheral: Intel Corporation Clarksfield/Lynnfield System Control and Status Registers (rev 11)
00:08.3 System peripheral: Intel Corporation Clarksfield/Lynnfield Miscellaneous Registers (rev 11)
00:10.0 System peripheral: Intel Corporation QPI Link (rev 11)
00:10.1 System peripheral: Intel Corporation QPI Routing and Protocol Registers (rev 11)
00:1a.0 USB Controller: Intel Corporation Ibex Peak USB2 Enhanced Host Controller (rev 05)
00:1b.0 Audio device: Intel Corporation Ibex Peak High Definition Audio (rev 05)
00:1c.0 PCI bridge: Intel Corporation Ibex Peak PCI Express Root Port 1 (rev 05)
00:1c.4 PCI bridge: Intel Corporation Ibex Peak PCI Express Root Port 5 (rev 05)
00:1c.5 PCI bridge: Intel Corporation Ibex Peak PCI Express Root Port 6 (rev 05)
00:1d.0 USB Controller: Intel Corporation Ibex Peak USB2 Enhanced Host Controller (rev 05)
00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev a5)
00:1f.0 ISA bridge: Intel Corporation Ibex Peak LPC Interface Controller (rev 05)
00:1f.2 IDE interface: Intel Corporation Ibex Peak 4 port SATA IDE Controller (rev 05)
00:1f.3 SMBus: Intel Corporation Ibex Peak SMBus Controller (rev 05)
00:1f.5 IDE interface: Intel Corporation Ibex Peak 2 port SATA IDE Controller (rev 05)
01:00.0 VGA compatible controller: nVidia Corporation Unknown device 0a65 (rev a2)
01:00.1 Audio device: nVidia Corporation Unknown device 0be3 (rev a1)
03:00.0 SATA controller: 1b4b:9123 (rev 11)
04:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 03)

手元の環境では増設したSATAコントローラ(赤字)がPassthroughしたいPCIデバイスです。したがって対象のBDFは03:00.0です。が、実際にはこの番号の頭に0000:をくっつけて、『0000:03:00.0」が正式なBDFで、この後もこちらの正式なBDFを使用します。

*ちなみに00:1f.0, 00:1f.2, 00:1f.3, 00:1f.5のように下一桁だけが異なるものはマルチファンクションのPCIデバイスです。この例ではこのPCIデバイスはオンボードのSATAコントローラ・ブリッジで、6ポートのSATAポートを装備しています。そしてこの内4ポートが00:1f.2に属しており、2ポートが00:1f.5に属しています。一度00:1f.2にSSDを一枚差し、00:1f.5にSSDを一枚差して後者だけをdomUにPassthroughできるか試してみましたが、結果はNGでした。Xen 3.4.0とXen 4.0.0両方でトライしましたが、前者は一見うまくいったように見えるのですがその内I/Oエラーやファイルシステムのジャーナルエラーが報告され、domo, domUともフリーズしました。後者は割り当てた瞬間にフリーズが発生しました。DMAのマップがめちゃくちゃになってそうな雰囲気です。

次にpcibackのロードですが、Oracle VM Serverのdom0カーネルでは(恐らく多くの他の環境でも)、pcibackはカーネルに組み込まれてビルドされておらずモジュールとしてビルドされています。この状態ではpcibackはオンラインでmodprobeコマンドによってロードできますが、逆にブート時にカーネルパラメータを渡すことでロードすることはできません。自動的にロードさせたい場合はブートのもう少し後の段階でロードします。具体的にはrc.localかmodprobe.confを少々編集します。今回はrc.localに記載する手順で話を進めます。そしてロードに続けてPCIデバイスをdom0から隠しPassthrough可能にする設定を行います。これらをまとめてrc.localに下記のように記述します。

BDF=0000:03:00.0
# Load pciback
modprobe pciback
# Unbind a PCI function from its driver as necessary
[ ! -e /sys/bus/pci/devices/$BDF/driver/unbind ] || \
        echo -n $BDF > /sys/bus/pci/devices/$BDF/driver/unbind
# Add a new slot to the PCI Backend's list
echo -n $BDF > /sys/bus/pci/drivers/pciback/new_slot
# Now that the backend is watching for the slot, bind to it
echo -n $BDF > /sys/bus/pci/drivers/pciback/bind

*pcibackはpvops採用のdom0カーネルではxen-pcibackと名前が変更されています。

*環境によってはPCIデバイスをunbindした瞬間にOSがクラッシュするかもしれません。僕はahciドライバで認識しているデバイスをunbindしたときにこのクラッシュに遭遇しました。これを回避するためにはrc.localではなくmodprobe.confを利用する設定方法が有効でした。ahci等のドライバがデバイスを認識する前にpcibackをロードして該当デバイスを隠蔽することによって回避することができました。詳しくはこちらの2.の手法を参照してください。skgeは手元の環境に合わせて変える必要があります。

設定がうまくいっていれば、xm pci-list-assignable-deviceで確認できます。

[root@vmserver]# xm pci-list-assignable-device
0000:03:00.0

この出力が確認できれば対象のPCIデバイスはPassthroughされる準備が整っています。あとはdomUの設定ファイルにてpci = [ '0000:03:00.0' ]の記述を入れてdomUを起動すればPassthroughが実現できます。参考までに手元のOpenSolaris b134のPVHVMの設定ファイルを掲載しておきます。

acpi = 1
apic = 1
builder = 'hvm'
device_model = '/usr/lib/xen/bin/qemu-dm'
disk = ['file:/var/ovs/mount/4ED5C364C05246FE8AEE8C0E26D79ACF/running_pool/nas/System.img,hda,w',
',hdc:cdrom,r',
]
kernel = '/usr/lib/xen/boot/hvmloader'
keymap = 'en-us'
memory = '1024'
name = 'nas'
on_crash = 'restart'
on_reboot = 'restart'
pae = 1
pci = ['0000:03:00.0']
serial = 'pty'
timer_mode = '0'
uuid = '42d9bfd3-dd90-4b54-a8a0-af90bcc53028'
vcpus = 4
vif = ['bridge=xenbr0,mac=00:16:3E:15:01:3E,type=netfront']
vif_other_config = []
vnc = 1
vncconsole = 1
vnclisten = '0.0.0.0'
vncpasswd = 'secret'
vncunused = 1

正直PCI-Passthroughの設定はなかなかクセがあり、苦労しました。動いたように見えて半日くらいしてからI/Oエラーがでたり、サーバ全体がクラッシュしたり、デバイスによっては隠蔽設定はうまくいくもののxm pci-list-assignable-deviceには表示されなかったり、Xenのバージョンによってかなり挙動が違ったり。下記にPCI-Passthroughにおける教訓を掲載しておきます 。

  • マルチファンクションデバイスの一部だけPassthroughしようとしない。Passthroughするときは丸ごと。
  • Linuxで確実に動作する鉄板のPCIデバイスを使う。
  • Xenは出来る限り新しいバージョンを使う。
  • 動いたと思っても油断しない。最低1日はヒートランすべき。

*今回検証した機材の他に、下記の組み合わせでも動作を確認しています。ご参考まで。

  • CPU: Intel Core-i7 860
  • チップセット: Intel H55 Express
  • マザーボード: Intel DH55TC
  • Xen: 4.0.0
  • dom0: Fedora12 kernel 2.6.32
  • Passthrough対象のdomU: OpenSolaris b134 PVHVM

with 2 comments

Written by 中嶋 一樹

5月 4th, 2010 at 3:08 am

Posted in Uncategorized

Tagged with , ,

XenのPCI-Passthroughとは?そのユースケースは?

PCI-Passthroughとは、PCIデバイスをごっそりdomU(ゲストOS)に「あげちゃう」手法です。ちなみにPCIデバイスとは主にディスクコントローラであったり、HBAであったり、ネットワークカードであったり、あるいはグラフィックカードであったりします。わかり易くするためにPCIデバイスをディスクに絞って話を進めます。通常XenではディスクをdomUに割り当てる際にはdom0が物理ディスクを一度認識した上で、そのディスクリソースを分配する形でdomUに割り当てるVBD(Virtual Block Device)という形式をとります。

例えばサーバにSATAディスクが接続されているとします。これはオンボードまたは拡張PCIカードのSATAコントローラにSATAケーブルで接続されています。このディスクがdomUに認識される道筋を通常のVBD形式とPCI-Passthroughとで比較したのが下図です。

通常のVBD割り当て

スクリーンショット(2010-04-25 20.13.03)

  • ディスク(PCIデバイス)はdom0によって管理され、複数のdomUで共有できる
  • domUからのディスクアクセスはdom0を経由して物理デバイスに到達する(一般的に性能劣化が発生する)
  • domUはデバイスドライバを使用しない(厳密にはdom0が提供するダミーデバイスと通信するためのドライバを使用する)

PCI-Passthroughの場合

スクリーンショット(2010-04-25 20.13.32)

  • PCI-Passthrough対象のSATAコントローラ(PCIデバイス)はdom0に認識させない
  • PCI-Passthroughを行うdomUがSATAコントローラ(PCIデバイス)を独占する
  • PCI-Passthroughを行うdomUからのディスクアクセスはは自身のデバイスドライバを使用して直接SATAコントローラ(PCIデバイス)、ディスクに到達する(dom0経由によって発生していた性能劣化から解放される)
  • domUとローカルマシンのデバイスとの静的な紐付けが行われるため、ライブマイグレーションが出来ないといった制約が発生する

ひとことで言えば、

  • PCI-Passthroughを使用すればdomUのディスクアクセスは高速になるが、そのデバイスは一つのdomUによって独占されてしまう。

ということになります。環境によってこれが使えそうかどうかはそれぞれだと思いますが、SATAコントローラが丸ごと一つのdomU専用になってしまうのでは収容できる仮想マシンの台数が大幅に制限されてしまいます。

*厳密には単一のSATAコントローラでもポートがハブ形式になっており複数のPCI識別子(BDF)が割り当てられていることもあるのでその場合はこの限りではない

仮想化とはそもそもH/WとOSを疎結合にすることが大きなメリットの一つでした。その中でPCI-Passthroughのような密結合を引き起こすコンフィグレーションはどのようなシチュエーションで有用なのでしょうか?

僕が考えるユースケースの一つはNASのバーチャルアプライアンスを稼動させる場合です。実際、NexentaStorのようにNAS(NFS, iSCSI)を仮想マシンとして構成することができる製品が存在します。そのような製品では仮想マシンとして高速にディスクにアクセスすることがマストの要件になってきますし、NASバーチャルアプライアンスが使用するディスクを他のdomUと共有するといった必然性は恐らくないでしょう。したがってNASバーチャルアプライアンスのような製品ではPCI-Passthroughは理想的なコンフィグレーションだと思います。

「仮想マシンでNASを構成しようなんて思うか?」という意見が聞こえてきそうですが、例えば僕は今その必要性に迫られています。限られたサーバ資源をフルに活用してフルスペックの仮想化環境を自宅に構築したいと思っています。しかしストレージ専用機、なんてもってのほかですし(費用、スペース、音、電力、等々)、サーバを丸ごとストレージにするのも勿体ない。そんなとき、OpenSolarisのZFSを使ったNASを仮想マシンで構成できればとても効率的ですよね。でも仮想マシンだとI/O系のパフォーマンスに不安がある。そんなときに!このPCI-Passthorughがソリューションになります。具体的にはOpenSolarisをEPT, VT-dが有効なサーバ上にPVHVMとして作成します。そしてSSDをPCI-PassthroughでOpenSolaris PVHVMから直接I/Oできるようにすればベアメタル上のネイティブOSと遜色ないパフォーマンスが確保できます。メモリアクセスや演算処理もVTテクノロジで実際非常に高速に動作します。ネットワークについてもPCI-Passthroughすることは可能ですが、手元の環境ではNICが豊富にあるわけではないのでネットワークアクセスについてはdom0から割り当てたVIFをPVドライバで高速化するという構成です。(そもそも通信は同筐体内という前提ですし)そして同一サーバ上の他のdomUはこのOpenSolaris PVHVMのZFS上に作成します。ZFSの機能を存分に活用してスナップショットによるバックアップ/ロールバック、クローンによる高速プロビジョニング、圧縮、重複排除などの高度なストレージ技術がすべて利用できます。それも物理的にはサーバ一台というオールインワンで。検証環境としては最高に高密度なシロモノとなります。

スクリーンショット(2010-04-25 20.45.57)

また、僕のような変テコな検証環境だけでなく、これからI/Aサーバをストレージとして使用する「Open Storage」という実装が世に広がってくるようになれば、このような構成がフィットするケースが増えてくるのではないかと考えています。

それでは別エントリでこのPCI-Passthroughの構成方法を解説しようと思います。

without comments

Written by 中嶋 一樹

4月 25th, 2010 at 8:36 pm

Posted in Uncategorized

Tagged with ,