← Documents Documentation/networking/driver.rst GitHub 원문 ↗

Linux 6.18.37 · Networking

Softnet Driver Issues

네트워크 드라이버의 주소 검증, ndo_stop 정지 보장, 송신 큐 정지·재개 및 SKB 수명 규칙을 설명합니다.

Source pathDocumentation/networking/driver.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

driver.rst:1-127

이 문서의 중심 원칙은 드라이버가 네트워크 코어와 맺은 소유권·진행 보장 계약을 어기지 않는 것입니다. 정지 뒤 하드웨어 활동을 완전히 끝내고, 송신 링이 고갈되기 전에 큐를 멈추며, 완료 처리에서 큐를 다시 깨우고, 반환 코드에 맞춰 SKB 소유권을 정확히 넘겨야 합니다.

반환값과 SKB 소유권
반환값드라이버 책임
NETDEV_TX_OKSKB를 인수하고 유한 시간 안에 완료·해제
NETDEV_TX_BUSYSKB 참조를 보관하거나 해제하지 않음

`ndo_start_xmit`의 반환 결과에 따라 드라이버 책임이 달라집니다.

송신 큐 관리 흐름
링 여유량 계산SKB 큐 매핑패킷 큐잉생산자 인덱스 갱신여유량 임계값 검사필요 시 큐 정지완료 회수소비자 인덱스 갱신큐 재개

송신 링의 여유량을 기준으로 큐를 선제적으로 정지하고 완료 회수 뒤 재개합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 =====================
4 Softnet Driver Issues
5 =====================
6
7 Probing guidelines
8 ==================
9
10 Address validation
11 ------------------
12
13 Any hardware layer address you obtain for your device should
14 be verified. For example, for ethernet check it with
15 linux/etherdevice.h:is_valid_ether_addr()
16
17 Close/stop guidelines
18 =====================
19
20 Quiescence
21 ----------
22
23 After the ndo_stop routine has been called, the hardware must
24 not receive or transmit any data. All in flight packets must
25 be aborted. If necessary, poll or wait for completion of
26 any reset commands.
27
28 Auto-close
29 ----------
30
31 The ndo_stop routine will be called by unregister_netdevice
32 if device is still UP.
33
34 Transmit path guidelines
35 ========================
36
37 Stop queues in advance
38 ----------------------
39
40 The ndo_start_xmit method must not return NETDEV_TX_BUSY under
41 any normal circumstances. It is considered a hard error unless
42 there is no way your device can tell ahead of time when its
43 transmit function will become busy.
44
45 Instead it must maintain the queue properly. For example,
46 for a driver implementing scatter-gather this means:
47
48 .. code-block:: c
49
50 static u32 drv_tx_avail(struct drv_ring *dr)
51 {
52 u32 used = READ_ONCE(dr->prod) - READ_ONCE(dr->cons);
53
54 return dr->tx_ring_size - (used & bp->tx_ring_mask);
55 }
56
57 static netdev_tx_t drv_hard_start_xmit(struct sk_buff *skb,
58 struct net_device *dev)
59 {
60 struct drv *dp = netdev_priv(dev);
61 struct netdev_queue *txq;
62 struct drv_ring *dr;
63 int idx;
64
65 idx = skb_get_queue_mapping(skb);
66 dr = dp->tx_rings[idx];
67 txq = netdev_get_tx_queue(dev, idx);
68
69 //...
70 /* This should be a very rare race - log it. */
71 if (drv_tx_avail(dr) <= skb_shinfo(skb)->nr_frags + 1) {
72 netif_stop_queue(dev);
73 netdev_warn(dev, "Tx Ring full when queue awake!\n");
74 return NETDEV_TX_BUSY;
75 }
76
77 //... queue packet to card ...
78
79 netdev_tx_sent_queue(txq, skb->len);
80
81 //... update tx producer index using WRITE_ONCE() ...
82
83 if (!netif_txq_maybe_stop(txq, drv_tx_avail(dr),
84 MAX_SKB_FRAGS + 1, 2 * MAX_SKB_FRAGS))
85 dr->stats.stopped++;
86
87 //...
88 return NETDEV_TX_OK;
89 }
90
91 And then at the end of your TX reclamation event handling:
92
93 .. code-block:: c
94
95 //... update tx consumer index using WRITE_ONCE() ...
96
97 netif_txq_completed_wake(txq, cmpl_pkts, cmpl_bytes,
98 drv_tx_avail(dr), 2 * MAX_SKB_FRAGS);
99
100 Lockless queue stop / wake helper macros
101 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
102
103 .. kernel-doc:: include/net/netdev_queues.h
104 :doc: Lockless queue stopping / waking helpers.
105
106 No exclusive ownership
107 ----------------------
108
109 An ndo_start_xmit method must not modify the shared parts of a
110 cloned SKB.
111
112 Timely completions
113 ------------------
114
115 Do not forget that once you return NETDEV_TX_OK from your
116 ndo_start_xmit method, it is your driver's responsibility to free
117 up the SKB and in some finite amount of time.
118
119 For example, this means that it is not allowed for your TX
120 mitigation scheme to let TX packets "hang out" in the TX
121 ring unreclaimed forever if no new TX packets are sent.
122 This error can deadlock sockets waiting for send buffer room
123 to be freed up.
124
125 If you return NETDEV_TX_BUSY from the ndo_start_xmit method, you
126 must not keep any reference to that SKB and you must not attempt
127 to free it up.
128

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

Softnet 드라이버 구현 지침

1-6

이 문서는 `GPL-2.0` 라이선스를 따릅니다.

Softnet 드라이버의 탐색, 종료, 송신 경로에서 지켜야 할 핵심 구현 규칙을 설명합니다.

.. SPDX-License-Identifier: GPL-2.0

=====================
Softnet Driver Issues
=====================

장치 주소 검증

7-16

탐색 지침

주소 검증

장치에서 얻은 하드웨어 계층 주소는 반드시 검증해야 합니다. 예를 들어 이더넷 주소는 `linux/etherdevice.h`의 `is_valid_ether_addr()`로 확인합니다.

Probing guidelines
==================

Address validation
------------------

Any hardware layer address you obtain for your device should
be verified.  For example, for ethernet check it with
linux/etherdevice.h:is_valid_ether_addr()

ndo_stop 이후 정지 상태 보장

17-33

닫기 및 정지 지침

정지 상태

`ndo_stop` 루틴이 호출된 뒤에는 하드웨어가 어떤 데이터도 송수신해서는 안 됩니다. 처리 중인 모든 패킷을 중단해야 하며, 필요하면 재설정 명령이 끝날 때까지 폴링하거나 기다립니다.

자동 닫기

장치가 여전히 `UP` 상태라면 `unregister_netdevice`가 `ndo_stop` 루틴을 호출합니다.

Close/stop guidelines
=====================

Quiescence
----------

After the ndo_stop routine has been called, the hardware must
not receive or transmit any data.  All in flight packets must
be aborted. If necessary, poll or wait for completion of
any reset commands.

Auto-close
----------

The ndo_stop routine will be called by unregister_netdevice
if device is still UP.

송신 큐를 미리 멈추고 안전하게 깨우기

34-99

송신 경로 지침

큐를 미리 정지

정상적인 상황에서 `ndo_start_xmit` 메서드는 `NETDEV_TX_BUSY`를 반환해서는 안 됩니다. 장치의 송신 기능이 언제 바빠질지 미리 알 방법이 전혀 없는 경우가 아니라면 이는 심각한 오류로 간주됩니다.

대신 드라이버가 큐를 올바르게 관리해야 합니다. 다음 scatter-gather 드라이버 예제에서 `drv_tx_avail()`은 생산자·소비자 인덱스를 `READ_ONCE()`로 읽어 사용 가능한 송신 링 엔트리 수를 계산합니다.

static u32 drv_tx_avail(struct drv_ring *dr)
{
        u32 used = READ_ONCE(dr->prod) - READ_ONCE(dr->cons);

        return dr->tx_ring_size - (used & bp->tx_ring_mask);
}

`drv_hard_start_xmit()`은 SKB의 큐 매핑으로 송신 링과 `netdev_queue`를 선택합니다. 큐가 깨어 있는데도 필요한 엔트리가 부족한 드문 경쟁 조건에서는 큐를 멈추고 경고를 기록한 다음 `NETDEV_TX_BUSY`를 반환합니다.

패킷을 카드에 넣은 뒤 `netdev_tx_sent_queue()`로 전송 바이트를 회계 처리하고, 생산자 인덱스를 `WRITE_ONCE()`로 갱신합니다. 이어 `netif_txq_maybe_stop()`으로 현재 여유 공간과 정지·재개 임계값을 검사하여 필요하면 큐를 멈추고 통계를 증가시킵니다.

송신 완료 회수 처리의 끝에서는 소비자 인덱스를 `WRITE_ONCE()`로 갱신한 후 `netif_txq_completed_wake()`에 완료 패킷 수, 완료 바이트 수, 현재 링 여유량, 재개 임계값을 전달해 큐를 깨웁니다.

//... update tx consumer index using WRITE_ONCE() ...

netif_txq_completed_wake(txq, cmpl_pkts, cmpl_bytes,
                         drv_tx_avail(dr), 2 * MAX_SKB_FRAGS);
Transmit path guidelines
========================

Stop queues in advance
----------------------

The ndo_start_xmit method must not return NETDEV_TX_BUSY under
any normal circumstances.  It is considered a hard error unless
there is no way your device can tell ahead of time when its
transmit function will become busy.

Instead it must maintain the queue properly.  For example,
for a driver implementing scatter-gather this means:

.. code-block:: c

        static u32 drv_tx_avail(struct drv_ring *dr)
        {
                u32 used = READ_ONCE(dr->prod) - READ_ONCE(dr->cons);

                return dr->tx_ring_size - (used & bp->tx_ring_mask);
        }

        static netdev_tx_t drv_hard_start_xmit(struct sk_buff *skb,
                                               struct net_device *dev)
        {
                struct drv *dp = netdev_priv(dev);
                struct netdev_queue *txq;
                struct drv_ring *dr;
                int idx;

                idx = skb_get_queue_mapping(skb);
                dr = dp->tx_rings[idx];
                txq = netdev_get_tx_queue(dev, idx);

                //...
                /* This should be a very rare race - log it. */
                if (drv_tx_avail(dr) <= skb_shinfo(skb)->nr_frags + 1) {
                        netif_stop_queue(dev);
                        netdev_warn(dev, "Tx Ring full when queue awake!\n");
                        return NETDEV_TX_BUSY;
                }

                //... queue packet to card ...

                netdev_tx_sent_queue(txq, skb->len);

                //... update tx producer index using WRITE_ONCE() ...

                if (!netif_txq_maybe_stop(txq, drv_tx_avail(dr),
                                          MAX_SKB_FRAGS + 1, 2 * MAX_SKB_FRAGS))
                        dr->stats.stopped++;

                //...
                return NETDEV_TX_OK;
        }

And then at the end of your TX reclamation event handling:

.. code-block:: c

        //... update tx consumer index using WRITE_ONCE() ...

        netif_txq_completed_wake(txq, cmpl_pkts, cmpl_bytes,
                                 drv_tx_avail(dr), 2 * MAX_SKB_FRAGS);

잠금 없는 큐 정지·재개 도우미

100-105

잠금 없는 큐 정지 및 깨우기 도우미 매크로

잠금 없는 큐 정지·재개 도우미의 커널 문서는 `include/net/netdev_queues.h`에서 가져옵니다.

Lockless queue stop / wake helper macros
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. kernel-doc:: include/net/netdev_queues.h
   :doc: Lockless queue stopping / waking helpers.

복제 SKB의 공유 영역 보호

106-111

배타적 소유권 없음

`ndo_start_xmit` 메서드는 복제된 SKB의 공유 영역을 수정해서는 안 됩니다.

No exclusive ownership
----------------------

An ndo_start_xmit method must not modify the shared parts of a
cloned SKB.

유한 시간 안에 송신 완료 처리

112-127

적시 완료

`ndo_start_xmit` 메서드에서 `NETDEV_TX_OK`를 반환한 뒤에는 드라이버가 SKB를 해제할 책임이 있으며, 반드시 유한한 시간 안에 처리해야 합니다.

예를 들어 새 송신 패킷이 들어오지 않는다는 이유로 송신 완화 기법이 기존 패킷을 송신 링에 영원히 미회수 상태로 남겨서는 안 됩니다. 이런 오류는 송신 버퍼 공간이 해제되기를 기다리는 소켓을 교착 상태에 빠뜨릴 수 있습니다.

`ndo_start_xmit`에서 `NETDEV_TX_BUSY`를 반환했다면 해당 SKB의 참조를 보관해서도, 그 SKB를 해제하려 해서도 안 됩니다.

Timely completions
------------------

Do not forget that once you return NETDEV_TX_OK from your
ndo_start_xmit method, it is your driver's responsibility to free
up the SKB and in some finite amount of time.

For example, this means that it is not allowed for your TX
mitigation scheme to let TX packets "hang out" in the TX
ring unreclaimed forever if no new TX packets are sent.
This error can deadlock sockets waiting for send buffer room
to be freed up.

If you return NETDEV_TX_BUSY from the ndo_start_xmit method, you
must not keep any reference to that SKB and you must not attempt
to free it up.