Oracle® Solaris 11.2 デバイスドライバの記述

印刷ビューの終了

更新: 2014 年 9 月
 
 

GLDv3 のデータパス

    データパスエントリポイントは、次のコンポーネントで構成されます。

  • ドライバによってエクスポートされ、パケット送信のために GLDv3 フレームワークによって呼び出されるコールバック。

  • 転送フロー制御およびパケット受信のためにドライバによって呼び出される GLDv3 フレームワークのエントリポイント。


注 - ドライバがリング機能を実装している場合、そのドライバによって送信および受信されるデータはすべて、リング固有のエントリポイントを介して渡されます。

送信データパス

GLDv3 フレームワークがメッセージブロックをドライバに渡すために呼び出す送信エントリポイントのタイプは、ベースとなるドライバの MAC_CAPAB_RINGS サポートによって異なります。ドライバが MAC_CAPAB_RINGS 機能をサポートしている場合、フレームワークは mri_tx(9E) リングエントリポイントを呼び出します。それ以外の場合、フレームワークは mc_tx(9E) エントリポイントを呼び出します。

したがって、デバイスドライバは mc_tx()mri_tx() のいずれかに送信エントリポイントへのポインタを指定する必要があります。詳細は、GLDv3 MAC Registration Data Structuresおよびmr_rget() Entry Pointを参照してください。

使用例 19-6  mc_tx() および mri_tx() エントリポイント
mblk_t *
xx_m_tx(void *arg, mblk_t *mp)
{
        xx_t    *xxp = arg;
        mblk_t   *nmp;

        mutex_enter(&xxp->xx_xmtlock);

        if (xxp->xx_flags & XX_SUSPENDED) {
                while ((nmp = mp) != NULL) {
                        xxp->xx_carrier_errors++;
                        mp = mp->b_next;
                        freemsg(nmp);
                }
                mutex_exit(&xxp->xx_xmtlock);
                return (NULL);
        }

        while (mp != NULL) {
                nmp = mp->b_next;
                mp->b_next = NULL;

                if (!xx_send(xxp, mp)) {
                        mp->b_next = nmp;
                        break;
                }
                mp = nmp;
        }
        mutex_exit(&xxp->xx_xmtlock);

        return (mp);
}

次のセクションでは、ハードウェアへのデータ転送に関連する事項について説明します。

フロー制御

ハードウェアリソース不足のためドライバがパケットを送信できない場合、ドライバは送信できなかったパケットのサブチェーンを返します。利用可能な記述子があとから増えたとき、ドライバは mac_tx_update(9F) または mac_tx_ring(9F) を呼び出してフレームワークに通知する必要があります。ドライバは、自身がリング機能を実装しているかどうかに応じていずれかの関数を呼び出します。

ハードウェアによるチェックサム計算: ハードウェア

ドライバでハードウェアチェックサムのサポート (Hardware Checksum Offloadを参照) を指定した場合、ドライバは次のタスクを実行する必要があります。

  • mac_hcksum_get(9F) を使用して、ハードウェアチェックサムのメタデータの全パケットを確認します。

  • 必要なチェックサム計算を実行するようにハードウェアをプログラミングします。

ラージセグメントオフロード

ドライバで LSO 機能 (Large Segment (or Send) Offloadを参照) を指定した場合、ドライバは mac_lso_get(9F) を使用して、パケットに対して LSO を実行する必要があるかどうかを照会する必要があります。

仮想 LAN: ハードウェア

管理者が VLAN を構成した場合、アウトバウンドパケットが mc_tx() エントリポイントを介してドライバに渡される前に、MAC 層が必要な VLAN ヘッダーをアウトバウンドパケットに挿入します。ただし、ハードウェアが VLAN タグ付けをサポートしている場合、ハードウェアにタグ付けがオフロードされます。詳細は、mr_gget() Entry Pointを参照してください。

受信データパス

受信データパスは割り込み駆動とポーリング駆動のいずれかになります。

受信割り込みデータパス

注: ドライバがリング機能をサポートしていない場合、ドライバの割り込みハンドラ内で mac_rx(9F) 関数を呼び出すことで、1 つ以上のパケットのチェーンをスタック上方の MAC 層に渡します。mac_rx() または mac_rx_ring() の呼び出し中は、相互排他ロックやその他のロックを保持しないでください。特に、mac_rx() または mac_rx_ring() の呼び出し中に転送スレッドによって取得される可能性があるロックを保持しないでください。

割り込みモードでは、NIC でパケットチェーンが受信され、それをドライバから取得可能な場合は常に、ドライバから上方のフレームワークにパケットチェーンが送信されます。パケットチェーンでは 1 つ以上の mblk_tb_next を介して互いに連結されているため、パケット単位の処理のオーバーヘッドを減らすことができます。割り込みモードで受信されたパケットを上方のフレームワークに渡すには、mac_rx_ring() エントリポイントを呼び出します。

void mac_rx_ring(mac_handle_t mh, mac_ring_handle_t mrh, mblk_t *mp_chain, int64_tmr_gen_num)

mh_handle は、デバイスドライバが mac_register() 関数経由でのカーネルへの登録時に取得した MAC ハンドルに対応しています。mrh _handle は、mr_rget() 呼び出しの一部としてドライバに渡されたフレームワークリングハンドルです。mr_gen_num は、mri_start() エントリポイント経由で受信リングを開始する際にフレームワークによって指定された生成番号に設定する必要があります。ドライバから提供されたリング生成番号は、フレームワークに保持されているリング生成番号と比較されます。これらが一致しない場合、受信されたパケットはそのリングの古い割り当てからの古いパケットであるとみなされ、ドロップされます。

受信ポーリングデータパス

割り込み駆動のパス経由でパケットを受信できるだけでなく、フレームワークではポーリングベースのデータパスもサポートされています。ポーリングモードでは、スタック内で実行されているカーネルスレッドが、ポーリングエントリポイント経由でドライバからパケットを取得します。このため、スタックは、パケットを処理するタイミングやその優先度を効率的に制御しながら、システムに入ってくる割り込みの数を実際の負荷に基づいて減らすことができます。さらに、スタックはポーリングを使用することで、受信トラフィックに対して帯域幅制限をより効率的に適用できますが、これは特に、仮想化シナリオではクリティカルになります。ホストは、割り込みモードとポーリングモードを必要に応じて切り替えます。あるリングがポーリングモードになっている場合、ドライバはその受信リング経由で受信されたパケットを mac_rx_ring() 関数を使って配信すべきではありません。ポーリングモードでは割り込みが無効化されるため、このことが保証されます。代わりにフレームワークは、ドライバによって mac_ring_info 構造体の一部として公開された mri_poll() エントリポイントを呼び出します。詳細は、mr_rget() Entry Pointを参照してください。

割り込みモードとポーリングモードの切り替え

デフォルトでは、開始後のリングは割り込みモードになっているはずです。リングは、割り込みモードになっているかぎり、受信したパケットをエントリポイント経由でチェーンの形式で渡すべきです。ホストは、リングをポーリングモードに切り替える際に、その割り込みを無効化するために、mac_ring_info 構造体経由で事前に公開された mac_intr 構造体を介してエントリポイントを呼び出します。

ハードウェアによるチェックサム計算: MAC 層

ドライバでハードウェアチェックサムのサポート (Hardware Checksum Offloadを参照) を指定した場合、ドライバは mac_hcksum_set(9F) 関数を使用して、ハードウェアによるチェックサム計算のメタデータをパケットと関連付ける必要があります。

仮想 LAN: MAC 層

VLAN パケットは、そのタグとともに MAC 層に渡される必要があります。パケットから VLAN ヘッダーを取り除かないでください。ただし、ハードウェアが VLAN ストリップをサポートしており、かつフレームワークがハードウェアに VLAN タグのストリップをリクエストした場合、ハードウェアは VLAN タグをストリップすることでパフォーマンスを改善できます。詳細は、mr_gget() Entry Pointを参照してください。