DLPAR 認識へのカーネル・エクステンションの変更

アプリケーションと同様に、ほとんどのカーネル・エクステンションは、デフォルトで DLPAR セーフです。

ただし、中にはシステム構成に敏感で、DLPAR サブシステムに登録しなければならない可能性のあるものもあります。 一部のカーネル・エクステンションは、プロセッサー行に従ってそのデータを区分化したり、オンライン・プロセッサーの数に基づいてスレッドを作成したり、大規模な固定メモリー・バッファー・プールを備えていたりします。 これらのカーネル・エクステンションには、システム・トポロジーを変更するときに通知する必要があります。 このメカニズムと実行する必要のあるアクションは、DLPAR 認識アプリケーションと似ています。

再構成ハンドラーの登録

再構成ハンドラーを登録および登録抹消するため、以下のカーネル・サービスが用意されています。
#include sys/dr.h

int reconfig_register(int (*handler)(void *, void *, int, dr_info_t *),
                      int actions, void * h_arg, ulong *h_token, char *name);

void reconfig_unregister(ulong h_token);

int (*handler)(void *event, void *h_arg, unsigned long long req, void *resource_info);

void reconfig_unregister(ulong h_token);

int reconfig_register_ext (int (*handler)(void *, void *, unsigned long long, dr_info_t *),
unsigned long long actions, void * h_arg, ulong *h_token, char *name);

int (*handler)(void *event, void *h_arg, unsigned long long req, void *resource_info);

kerrno_t reconfig_register_list(int (*handler)(void *, void *, dr_kevent_t, void *), 
dr_kevent_t event_list[], size_t list_size, void *h_arg, ulong *h_token, char *name);

int (*handler)(void *event, void *h_arg, dr_kevent_t event_in_prog, void *resource_info);
注: カーネル・サービス reconfig_register_list を使用することが推奨されています。 このサービスは、カーネル・エクステンションに通知されるイベントをより多くサポートします。 既存のカーネル・サービス (reconfig_register および reconfig_register_ext) ではそれぞれ 32 イベントと 64 イベントに制限されており、このサービスを使用するカーネル・エクステンションは、32 イベントと 64 イベントより多いイベントをサポートする将来のシステムに移植できません。
reconfig_registerreconfig_register_ext、および reconfig_register_list サブルーチンのパラメーターは以下のとおりです。
  • handler パラメーターは、呼び出されるカーネル・エクステンションです。
  • actions パラメーターでは、カーネル・エクステンションが どのイベントの通知を必要とするかを指定することができます。 このイベント・リストについては、reconfig_registerreconfig_register_ext、および reconfig_unregister カーネル・サービスを参照してください。
  • h_arg パラメーターは、カーネル・エクステンションで指定され、ハンドラーの機能ディスクリプターと共にカーネルに記憶され、呼び出されるとハンドラーに渡されます。 これは、カーネルによって直接には使用されませんが、 複数のアダプター・インスタンスを管理するカーネル・エクステンションをサポートするためのものです。 実際には、このパラメーターはアダプター制御ブロックを指します。
  • h_token パラメーターは出力パラメーターであり、 ハンドラーを登録抹消するときに使用します。
  • name パラメーターは通知目的で用意されており、 ドライバーがエラーを戻す場合にエラー・ログ・エントリーの中に組み入れることができます。 これはカーネル・エクステンションによって提供され、15 ASCII 文字以内に制限されます。
  • event_list パラメーターは、カーネル・エクステンションにその発生を知らせる dr_kevent_t 値のアレイです。 定義されたイベントのリストについては、reconfig_register_list カーネル・サービスを参照してください。
  • list_size パラメーターは、event_list パラメーターが消費するメモリーのサイズです。

reconfig_register 関数と reconfig_register_ext 関数は、成功の場合は 0 を戻し、それ以外の場合は該当する errno 値を戻します。

reconfig_unregister 関数は、以前にインストールされたハンドラーを除去するために呼び出されます。

reconfig_registerreconfig_register_ext、および reconfig_unregister 関数は、プロセス環境でのみ呼び出すことができます。

カーネル・エクステンションを pre フェーズ用に登録する場合は、check フェーズ用にも登録して、リソースの除去時にシステムが部分的に未構成にならないようにするようお勧めします。

再構成ハンドラー

reconfig_register_list カーネル・サービスとともに使用される再構成ハンドラーのインターフェースは以下のとおりです。
Int (*handler)(void *event, void *h_arg, dr_kevent_t event_in_prog, void *resource_info);
再構成ハンドラーのパラメーターは、以下のとおりです。
  • event パラメーターは、reconfig_handler_complete サブルーチンを呼び出すときにハンドラーに渡され、そのときにだけ使用されます。
  • h_arg パラメーターは、登録時にハンドラーによって指定されます。
  • event_in_prog パラメーターは、ハンドラーによって実行される DLPAR 操作を示します。 このイベント・リストについては、reconfig_register_list カーネル・サービスを参照してください。
  • resource_info パラメーターは、現行の DLPAR 要求に関するリソース固有の情報を示します。 要求がプロセッサーに関するものである場合は、 dri_cpu 構造体を介して resource_info データが提供されます。 要求がメモリー・ベースの場合は、dri_mem 構造体が使用されます。 Micro-Partitioning® パーティションでは、要求がプロセッサー能力ベースの場合は、resource_info データが dri_cpu_capacity 構造体を介して提供されます。 詳細および dri_cpu_capacity 構造体の形式については、reconfig Kernel Service を参照してください。
struct dri_cpu {
        cpu_t           lcpu;           /* Logical CPU Id of target CPU */
        cpu_t           bcpu;           /* Bind Id of target CPU        */
};

struct dri_mem {
        size64_t        req_memsz_change;   /* user requested mem size  */
        size64_t        sys_memsz;          /* system mem size at start */
        size64_t        act_memsz_change;   /* mem added/removed so far */
        rpn64_t         sys_free_frames;    /* Number of free frames */
        rpn64_t         sys_pinnable_frames;/* Number of pinnable frames */
        rpn64_t         sys_total_frames;   /* Total number of frames */
        unsigned long long lmb_addr;        /* start addr of logical memory block */
        size64_t        lmb_size;           /* Size of logical memory block being added */
};

現行の DLPAR 要求がパーティションの移行である場合、ハンドラーが resource_info データを resource_info データのカーネル・エクステンションに供給しますが、このデータはカーネル・エクステンションで使用しないため、カーネル・エクステンションは resource_info データの内容にアクセスする必要がありません。

再構成ハンドラーはプロセス環境で呼び出されます。

カーネル・エクステンションでは、以下のことを想定できます。
  • 一度に 1 つのタイプのリソースだけが構成または除去される。
  • 同時に複数のプロセッサーは指定されない。 ただし、カーネル・エクステンションは、複数の論理メモリー・ブロックの追加または除去をサポートするようコーディングされている必要があります。 ユーザーは、数ギガバイトのメモリーを追加または除去する要求を始めることがあります。

check フェーズでは、 DLPAR 認識アプリケーションおよびカーネル・エクステンションが、ユーザーの要求が適用される前にその要求に反応することができます。 したがって、要求が複数の論理メモリー・ブロックに及ぶ可能性があるとしても、check フェーズのカーネル拡張ハンドラーが呼び出されるのは 1 回です。 pre フェーズ、post フェーズ、および post-error フェーズは、check フェーズとは違って論理メモリー・ブロック・レベルで適用されます。 アプリケーション通知の場合はこれとは異なり、基礎となる論理メモリー・ブロックの数には関係なく、pre フェーズ、post フェーズ、もしくは post-error フェーズがユーザー要求ごとに 1 回呼び出されます。 もう 1 つの違いは、カーネル・エクステンションの post-error フェーズは特定の論理メモリー・ブロック操作が失敗したときに使用されるのに対し、アプリケーションの post-error フェーズは操作 (この場合はユーザーの要求全体) が失敗したときに使用されるという点です。

通常、カーネル・エクステンションは check フェーズ中に その状態を検査して、間近に迫っている DLPAR 要求に応じることができるかどうか判断します。 この操作を実行できない場合や、この操作が拡張機能の正しい実行に悪影響を及ぼす場合、ハンドラーは DR_FAIL を戻します。 それ以外の場合、ハンドラーは DR_SUCCESS を戻します。

pre-remove フェーズでは、カーネル・エクステンションは、指定されたリソースに対して持っている依存関係 (存在する場合) を除去しようとします。 1 つの例は、プロセッサー別バッファー・プールを保守するドライバーです。 このドライバーは関連するバッファー・プールを削除保留中としてマークし、そこからは新しい要求に割り当てられないようにできます。 やがてプールはドレーンされ、解放可能になります。 pre-remove フェーズで考慮する必要のある他の項目は、タイマーとバインド済みのスレッドです。これらはそれぞれ停止して終了する必要があります。 あるいは、バインド済みのスレッドをアンバインドすることができます。

post-remove フェーズでは、カーネル・エクステンションはリソースが実際に除去されたと想定して、ガーベッジ・コレクションによってリソースを解放しようとします。 リソースが除去されていなかった場合は、タイマーとスレッドを再設定しなければなりません。 DR_resource_POST_ERROR 要求は、エラーが発生したことを示すために使用されます。

pre-add フェーズでは、カーネル・エクステンションは新規リソースに依存するデータ・パス (存在する場合) を事前に初期化して、新規リソースの構成時に使用できるようにしておく必要があります。 システムでは、post フェーズでハンドラーが再び呼び出されるまでそのリソースが使用されないという保証はありません。

post-add フェーズでは、 カーネル・エクステンションは、リソースが正しく追加されて使用可能になっていると想定することができます。 このフェーズは、バインド済みのスレッドを開始し、タイマーをスケジュールし、バッファーのサイズを増やすのに都合の良いフェーズです。

カーネル・エクステンションは、1 つ以上の _OP_ 通知タイプに登録することで、アプリケーションと同様に、事前操作に基づいてメモリーの除去または追加も通知されます。 これにより、カーネル・エクステンションはそのリソース使用を 1 論理メモリー・ブロック (LMB) につき一度ではなく、1 操作につき一度だけメモリー DR 操作に応じて変更できます。

DR_MEM_REMOVE_OP_PRE 通知がメモリーの除去前に送信されます。 再構成ハンドラーは、この時点でメモリー除去を予想してリソースの調整を開始できます。 DR_MEM_REMOVE_OP_POST 通知と DR_MEM_ADD_OP_POST 通知は、操作が失敗したかどうかに関係なく、メモリーの除去または追加操作後にそれぞれ送信されます。 操作が失敗した場合は、act_memsz_change0 になります。

再構成ハンドラーは、可能であれば数秒以内に、DR_SUCCESS を戻して再構成が正常に行われたことを示すか、または DR_FAIL を戻して失敗を示します。 さらに時間が必要な場合、ハンドラーは DR_WAIT を戻します。

拡張 DR ハンドラー

操作が長時間 (つまり数秒間) に及ぶ可能性があるとカーネル・エクステンションが予想した場合、ハンドラーは呼び出し側に DR_WAIT を戻しますが、非同期で要求を処理します。 以下の例では、ハンドラーは reconfig_handler_complete ルーチンを呼び出すことによって、要求を完了したことを示します。
void reconfig_handler_complete(void *event, int rc);

event パラメーターは、ハンドラーがカーネルによって呼び出されたときに渡されたのと同じパラメーターです。 rc パラメーターは、DR_SUCCESS または DR_FAIL のいずれかに設定され、ハンドラーの終了状況を示す必要があります。

reconfig_handler_complete カーネル・サービスは、プロセス環境か割り込み環境で呼び出すことができます。

xmemdma カーネル・サービスの使用

メモリーの動的除去などの DLPAR 対応のシステム上で、XMEM_DR_SAFE フラグなしに xmemdma カーネル・サービスを呼び出すと、指定されたメモリーに除去不能のフラグが立てられます。 これは、システムの整合性を保証するために行われます。その理由は、戻された実メモリー・アドレスを、呼び出 し側がどのようにして使用するつもりなのかを、システ ムが知らないからです。 その他のメモリーには動的メモリー除去操作が引き続き可能ですが、 xmemdma 呼び出しが指定したメモリーに対しては可能ではありません。

呼び出し側が通知のみの目的 (トレース・バッファーあるいはデバッグ情報な ど) に実メモリー・アドレスを使用する場合、呼び出し側は XMEM_DR_SAFE フラグを 設定することができます。 これは、データ破壊の危険なく、実メモリー・アドレスを呼び出し側に公開できることを、システムに知らせます。 このフラグが存在する場合、システムは指定されたメモリーを引き続き動的に除去します。

呼び出し側が、データ変換をオフにし実メモリーに対する CPU ロードまたは保管アクセスを 実行するか、あるいは実メモリーを対象にする直接メモリー・アクセス (DMA) コントローラーをプログラミングすることで実メモリー・アドレスを使用して実際のデータ・アクセスを実行する場合、XMEM_DR_SAFE フラグを設定しないでください。 このフラグが設定されると、メモリーが動的に除去されるときに、システムのデータ保全性が損なわれます。 このように実メモリー・アドレスを使用するカーネル・エクステンションを DLPAR 対応に変換する方法については、IBM® サービス技術員にお問い合わせください。

詳細については、xmemdma カーネル・サービスを参照してください。

アプリケーションへのメモリー DLPAR 通知の制御

動的追加、または複数の DLPAR 対応プログラムを実行する LPAR か らのメモリー除去を行うと、リソース競合が発生する可能性があります。 デフォルトでは、 各プログラムはリソース変更に関して等しく通知されます。 例えば、1 GB のメモリーが DR 対応 の 2 つのプログラムを実行している LPAR から除去された場合、デフォルトでは 各プログラムは 1 GB のメモリーが除去されたと通知されます。 2 つのプログラムは 一般的には互いを認識しないため、両方のプログラムがメモリーの使用を 1 GB 分 削減し、結果として効率が悪化します。 新規メモリー増設時にも同様の効率問題が 発生する可能性があります。

この問題を解決するために AIX® では、実メモリー・リソース変更をパーセンテージで示すパーセンテージ・ファクターを用いて、アプリケーション・スクリプトをインストールできます。 その場合、システムはメモリー DLPAR の イベントでそのアプリケーションに通知をします。 drmgr コマンドを使用してアプリケーション・スクリプトをインストール する際に、DR_MEM_PERCENT name=value ペアを用いてこのパーセンテージ・ファクターを指定できます。 drmgr コマンドが scriptinfo サブコマンド指定でアプリケーション・スクリプトを呼び出す場合、このアプリケーション・スクリプトはこの name=value ペアを出力する必要があります。 この値は 1 から 100 の間の整数でなければなりません。 この範囲から外れたどの値も無 視され、デフォルト値である 100 が使われます。 さらに、この name=value ペアは、インストール時は環境変数として設定することもできます。 インストール時に、環境変数からの値はアプリケー ション・スクリプトが提供する値をオーバーライドします (環境変数を設定している場合)。

同様に、SIGRECONFIG シグナル・ハンドラー および dr_reconfig() システム・コールを使用する アプリケーションにおいては、DR_MEM_PERCENT name=value ペアを環境変数として設定することで、メモリー DLPAR 通知を 制御してからアプリケーションの実行を開始できます。 ただし、この値はアプリケーションを再始動しない限 り変更できません。