DPDK patches and discussions
 help / color / mirror / Atom feed
From: Ferruh Yigit <ferruh.yigit@intel.com>
To: Huisong Li <lihuisong@huawei.com>
Cc: "dev@dpdk.org" <dev@dpdk.org>
Subject: Re: [dpdk-dev] [PATCH 1/4] ethdev: fix max Rx packet length
Date: Wed, 21 Jul 2021 16:29:46 +0100	[thread overview]
Message-ID: <4e1ae26c-197b-ea45-0860-66c195d1f820@intel.com> (raw)
In-Reply-To: <1a891390-1122-6dcf-03e8-1f0b147b30ec@huawei.com>

On 7/19/2021 4:35 AM, Huisong Li wrote:
> Hi, Ferruh
> 

Hi Huisong,

Thanks for the review.

> 在 2021/7/10 1:29, Ferruh Yigit 写道:
>> There is a confusion on setting max Rx packet length, this patch aims to
>> clarify it.
>>
>> 'rte_eth_dev_configure()' API accepts max Rx packet size via
>> 'uint32_t max_rx_pkt_len' filed of the config struct 'struct
>> rte_eth_conf'.
>>
>> Also 'rte_eth_dev_set_mtu()' API can be used to set the MTU, and result
>> stored into '(struct rte_eth_dev)->data->mtu'.
>>
>> These two APIs are related but they work in a disconnected way, they
>> store the set values in different variables which makes hard to figure
>> out which one to use, also two different related method is confusing for
>> the users.
>>
>> Other issues causing confusion is:
>> * maximum transmission unit (MTU) is payload of the Ethernet frame. And
>>    'max_rx_pkt_len' is the size of the Ethernet frame. Difference is
>>    Ethernet frame overhead, but this may be different from device to
>>    device based on what device supports, like VLAN and QinQ.
>> * 'max_rx_pkt_len' is only valid when application requested jumbo frame,
>>    which adds additional confusion and some APIs and PMDs already
>>    discards this documented behavior.
>> * For the jumbo frame enabled case, 'max_rx_pkt_len' is an mandatory
>>    field, this adds configuration complexity for application.
>>
>> As solution, both APIs gets MTU as parameter, and both saves the result
>> in same variable '(struct rte_eth_dev)->data->mtu'. For this
>> 'max_rx_pkt_len' updated as 'mtu', and it is always valid independent
>> from jumbo frame.
>>
>> For 'rte_eth_dev_configure()', 'dev->data->dev_conf.rxmode.mtu' is user
>> request and it should be used only within configure function and result
>> should be stored to '(struct rte_eth_dev)->data->mtu'. After that point
>> both application and PMD uses MTU from this variable.
>>
>> When application doesn't provide an MTU during 'rte_eth_dev_configure()'
>> default 'RTE_ETHER_MTU' value is used.
>>
>> As additional clarification, MTU is used to configure the device for
>> physical Rx/Tx limitation. Other related issue is size of the buffer to
>> store Rx packets, many PMDs use mbuf data buffer size as Rx buffer size.
>> And compares MTU against Rx buffer size to decide enabling scattered Rx
>> or not, if PMD supports it. If scattered Rx is not supported by device,
>> MTU bigger than Rx buffer size should fail.
>>
>> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>

<...>

>> diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
>> index e51512560e15..8bccdeddb2f7 100644
>> --- a/drivers/net/hns3/hns3_ethdev.c
>> +++ b/drivers/net/hns3/hns3_ethdev.c
>> @@ -2379,20 +2379,11 @@ hns3_refresh_mtu(struct rte_eth_dev *dev, struct
>> rte_eth_conf *conf)
>>   {
>>       struct hns3_adapter *hns = dev->data->dev_private;
>>       struct hns3_hw *hw = &hns->hw;
>> -    uint32_t max_rx_pkt_len;
>> -    uint16_t mtu;
>> -    int ret;
>> -
>> -    if (!(conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME))
>> -        return 0;
>> +    uint32_t max_rx_pktlen;
>>   -    /*
>> -     * If jumbo frames are enabled, MTU needs to be refreshed
>> -     * according to the maximum RX packet length.
>> -     */
>> -    max_rx_pkt_len = conf->rxmode.max_rx_pkt_len;
>> -    if (max_rx_pkt_len > HNS3_MAX_FRAME_LEN ||
>> -        max_rx_pkt_len <= HNS3_DEFAULT_FRAME_LEN) {
>> +    max_rx_pktlen = conf->rxmode.mtu + HNS3_ETH_OVERHEAD;
>> +    if (max_rx_pktlen > HNS3_MAX_FRAME_LEN ||
>> +        max_rx_pktlen <= HNS3_DEFAULT_FRAME_LEN) {
>>           hns3_err(hw, "maximum Rx packet length must be greater than %u "
>>                "and no more than %u when jumbo frame enabled.",
>>                (uint16_t)HNS3_DEFAULT_FRAME_LEN,
> 
> The preceding check for the maximum frame length was based on the scenario where
> jumbo frames are enabled.
> 
> Since there is no offload of jumbo frames in this patchset, the maximum frame
> length does not need to be checked and only ensure conf->rxmode.mtu is valid.
> 
> These should be guaranteed by dev_configure() in the framework .
> 

Got it, agree that 'HNS3_DEFAULT_FRAME_LEN' check is now wrong, and as you said
these checks are becoming redundant, so I will remove them.

In that case 'hns3_refresh_mtu()' becomes just wrapper to 'hns3_dev_mtu_set()',
I will remove function too.

<...>

>> diff --git a/drivers/net/hns3/hns3_ethdev_vf.c
>> b/drivers/net/hns3/hns3_ethdev_vf.c
>> index e582503f529b..ca839fa55fa0 100644
>> --- a/drivers/net/hns3/hns3_ethdev_vf.c
>> +++ b/drivers/net/hns3/hns3_ethdev_vf.c
>> @@ -784,8 +784,7 @@ hns3vf_dev_configure(struct rte_eth_dev *dev)
>>       uint16_t nb_rx_q = dev->data->nb_rx_queues;
>>       uint16_t nb_tx_q = dev->data->nb_tx_queues;
>>       struct rte_eth_rss_conf rss_conf;
>> -    uint32_t max_rx_pkt_len;
>> -    uint16_t mtu;
>> +    uint32_t max_rx_pktlen;
>>       bool gro_en;
>>       int ret;
>>   @@ -825,29 +824,21 @@ hns3vf_dev_configure(struct rte_eth_dev *dev)
>>               goto cfg_err;
>>       }
>>   -    /*
>> -     * If jumbo frames are enabled, MTU needs to be refreshed
>> -     * according to the maximum RX packet length.
>> -     */
>> -    if (conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) {
>> -        max_rx_pkt_len = conf->rxmode.max_rx_pkt_len;
>> -        if (max_rx_pkt_len > HNS3_MAX_FRAME_LEN ||
>> -            max_rx_pkt_len <= HNS3_DEFAULT_FRAME_LEN) {
>> -            hns3_err(hw, "maximum Rx packet length must be greater "
>> -                 "than %u and less than %u when jumbo frame enabled.",
>> -                 (uint16_t)HNS3_DEFAULT_FRAME_LEN,
>> -                 (uint16_t)HNS3_MAX_FRAME_LEN);
>> -            ret = -EINVAL;
>> -            goto cfg_err;
>> -        }
>> -
>> -        mtu = (uint16_t)HNS3_PKTLEN_TO_MTU(max_rx_pkt_len);
>> -        ret = hns3vf_dev_mtu_set(dev, mtu);
>> -        if (ret)
>> -            goto cfg_err;
>> -        dev->data->mtu = mtu;
>> +    max_rx_pktlen = conf->rxmode.mtu + HNS3_ETH_OVERHEAD;
>> +    if (max_rx_pktlen > HNS3_MAX_FRAME_LEN ||
>> +        max_rx_pktlen <= HNS3_DEFAULT_FRAME_LEN) {
>> +        hns3_err(hw, "maximum Rx packet length must be greater "
>> +             "than %u and less than %u when jumbo frame enabled.",
>> +             (uint16_t)HNS3_DEFAULT_FRAME_LEN,
>> +             (uint16_t)HNS3_MAX_FRAME_LEN);
>> +        ret = -EINVAL;
>> +        goto cfg_err;
>>       }
> Please remove this check now, thanks!

ack

<...>

>> diff --git a/examples/ip_reassembly/main.c b/examples/ip_reassembly/main.c
>> index ce8882a45883..f868e5d906c7 100644
>> --- a/examples/ip_reassembly/main.c
>> +++ b/examples/ip_reassembly/main.c
>> @@ -162,7 +162,7 @@ static struct lcore_queue_conf
>> lcore_queue_conf[RTE_MAX_LCORE];
>>   static struct rte_eth_conf port_conf = {
>>       .rxmode = {
>>           .mq_mode        = ETH_MQ_RX_RSS,
>> -        .max_rx_pkt_len = JUMBO_FRAME_MAX_SIZE,
>> +        .mtu = JUMBO_FRAME_MAX_SIZE,
> 
> It feel likes that the replacement of max_rx_pkt_len with MTU is inappropriate.
> 
> Because "max_rx_pkt_len " is the sum of  "mtu" and "overhead_len".

You are right, it is not same thing. I will update it to remove overhead.

<...>

>> @@ -1448,49 +1459,45 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t
>> nb_rx_q, uint16_t nb_tx_q,
>>       }
>>         /*
>> -     * If jumbo frames are enabled, check that the maximum RX packet
>> -     * length is supported by the configured device.
>> +     * Check that the maximum RX packet length is supported by the
>> +     * configured device.
>>        */
>> -    if (dev_conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) {
>> -        if (dev_conf->rxmode.max_rx_pkt_len > dev_info.max_rx_pktlen) {
>> -            RTE_ETHDEV_LOG(ERR,
>> -                "Ethdev port_id=%u max_rx_pkt_len %u > max valid value %u\n",
>> -                port_id, dev_conf->rxmode.max_rx_pkt_len,
>> -                dev_info.max_rx_pktlen);
>> -            ret = -EINVAL;
>> -            goto rollback;
>> -        } else if (dev_conf->rxmode.max_rx_pkt_len < RTE_ETHER_MIN_LEN) {
>> -            RTE_ETHDEV_LOG(ERR,
>> -                "Ethdev port_id=%u max_rx_pkt_len %u < min valid value %u\n",
>> -                port_id, dev_conf->rxmode.max_rx_pkt_len,
>> -                (unsigned int)RTE_ETHER_MIN_LEN);
>> -            ret = -EINVAL;
>> -            goto rollback;
>> -        }
>> +    if (dev_conf->rxmode.mtu == 0)
>> +        dev->data->dev_conf.rxmode.mtu = RTE_ETHER_MTU;
> Here, it will cause a case that the user configuration is inconsistent with the
> configuration saved in the framework .

What is the framework you mentioned?

Previously 'max_rx_pkt_len' was mandatory when jumbo frame is configured even
user doesn't really case about it and it was causing additional complexity in
the configuration.
This check is required to use defaults when application doesn't need a specific
value, I believe this is a good usability improvement.
Application who cares about a specific value can set it explicitly and it will
be in sync with application.

> Is it more reasonable to provide a prompt message?

Not sure about it. We are not changing a user configured value, but using
default value when application doesn't set it, and that kind of log will be
printed by most of the applications, this may cause noise.

>> +    max_rx_pktlen = dev->data->dev_conf.rxmode.mtu + overhead_len;
>> +    if (max_rx_pktlen > dev_info.max_rx_pktlen) {
>> +        RTE_ETHDEV_LOG(ERR,
>> +            "Ethdev port_id=%u max_rx_pktlen %u > max valid value %u\n",
>> +            port_id, max_rx_pktlen, dev_info.max_rx_pktlen);
>> +        ret = -EINVAL;
>> +        goto rollback;
>> +    } else if (max_rx_pktlen < RTE_ETHER_MIN_LEN) {
>> +        RTE_ETHDEV_LOG(ERR,
>> +            "Ethdev port_id=%u max_rx_pktlen %u < min valid value %u\n",
>> +            port_id, max_rx_pktlen, RTE_ETHER_MIN_LEN);
>> +        ret = -EINVAL;
>> +        goto rollback;
>> +    }
> 
> Above "max_rx_pktlen < RTE_ETHER_MIN_LEN " case will be  inconsistent with
> dev_set_mtu() API.
> 
> The reasons are as follows:
> 
> The value of RTE_ETHER_MIN_LEN is 64. If "overhead_len" is 26 caculated by
> eth_dev_get_overhead_len(), it means
> 
> that dev->data->dev_conf.rxmode.mtu equal to 38 is reasonable.
> 
> But, in  dev_set_mtu() API, the check for mtu is:
> 
> @@ -3643,12 +3644,27 @@ rte_eth_dev_set_mtu(uint16_t port_id, uint16_t mtu)
>  
>          if (mtu < dev_info.min_mtu || mtu > dev_info.max_mtu)
>              return -EINVAL;
> 
> It should be noted that dev_info.min_mtu is RTE_ETHER_MIN_MTU (68).
> 

Agree on the inconsistency.

RTE_ETHER_MIN_MTU is 68, that is min MTU for IPv4
RTE_ETHER_MIN_LEN is 64, and min MTU for Ethernet frame

Although we are talking about MTU, we are mainly concerned about Ethernet frame
payload, not IPv4.

I suggest only using RTE_ETHER_MIN_LEN.
Since this inconsistency was already there before this patch, I will update it
in seperate patch instead of fixing in this one.

  reply	other threads:[~2021-07-21 15:30 UTC|newest]

Thread overview: 112+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-09 17:29 Ferruh Yigit
2021-07-09 17:29 ` [dpdk-dev] [PATCH 2/4] ethdev: move jumbo frame offload check to library Ferruh Yigit
2021-07-13 13:48   ` Andrew Rybchenko
2021-07-21 12:26     ` Ferruh Yigit
2021-07-18  7:49   ` Xu, Rosen
2021-07-19 14:38   ` Ajit Khaparde
2021-07-09 17:29 ` [dpdk-dev] [PATCH 3/4] ethdev: move check to library for MTU set Ferruh Yigit
2021-07-13 13:56   ` Andrew Rybchenko
2021-07-18  7:52   ` Xu, Rosen
2021-07-09 17:29 ` [dpdk-dev] [PATCH 4/4] ethdev: remove jumbo offload flag Ferruh Yigit
2021-07-13 14:07   ` Andrew Rybchenko
2021-07-21 12:26     ` Ferruh Yigit
2021-07-21 12:39     ` Ferruh Yigit
2021-07-18  7:53   ` Xu, Rosen
2021-07-13 12:47 ` [dpdk-dev] [PATCH 1/4] ethdev: fix max Rx packet length Andrew Rybchenko
2021-07-21 16:46   ` Ferruh Yigit
2021-07-22  1:31     ` Ajit Khaparde
2021-07-22 10:27       ` Ferruh Yigit
2021-07-22 10:38         ` Andrew Rybchenko
2021-07-18  7:45 ` Xu, Rosen
2021-07-19  3:35 ` Huisong Li
2021-07-21 15:29   ` Ferruh Yigit [this message]
2021-07-22  7:21     ` Huisong Li
2021-07-22 10:12       ` Ferruh Yigit
2021-07-22 10:15         ` Andrew Rybchenko
2021-07-22 14:43           ` Stephen Hemminger
2021-09-17  1:08             ` Min Hu (Connor)
2021-09-17  8:04               ` Ferruh Yigit
2021-09-17  8:16                 ` Min Hu (Connor)
2021-09-17  8:17                 ` Min Hu (Connor)
2021-07-22 17:21 ` [dpdk-dev] [PATCH v2 1/6] " Ferruh Yigit
2021-07-22 17:21   ` [dpdk-dev] [PATCH v2 2/6] ethdev: move jumbo frame offload check to library Ferruh Yigit
2021-07-22 17:21   ` [dpdk-dev] [PATCH v2 3/6] ethdev: move check to library for MTU set Ferruh Yigit
2021-07-22 17:21   ` [dpdk-dev] [PATCH v2 4/6] ethdev: remove jumbo offload flag Ferruh Yigit
2021-07-22 17:21   ` [dpdk-dev] [PATCH v2 5/6] ethdev: unify MTU checks Ferruh Yigit
2021-07-23  3:29     ` Huisong Li
2021-07-22 17:21   ` [dpdk-dev] [PATCH v2 6/6] examples/ip_reassembly: remove unused parameter Ferruh Yigit
2021-10-01 14:36   ` [dpdk-dev] [PATCH v3 1/6] ethdev: fix max Rx packet length Ferruh Yigit
2021-10-01 14:36     ` [dpdk-dev] [PATCH v3 2/6] ethdev: move jumbo frame offload check to library Ferruh Yigit
2021-10-04  5:08       ` Somnath Kotur
2021-10-01 14:36     ` [dpdk-dev] [PATCH v3 3/6] ethdev: move check to library for MTU set Ferruh Yigit
2021-10-04  5:09       ` Somnath Kotur
2021-10-01 14:36     ` [dpdk-dev] [PATCH v3 4/6] ethdev: remove jumbo offload flag Ferruh Yigit
     [not found]       ` <CAOBf=muYkU2dwgi3iC8Q7pdSNTJsMUwWYdXj14KeN_=_mUGa0w@mail.gmail.com>
2021-10-04  7:55         ` Somnath Kotur
2021-10-05 16:48           ` Ferruh Yigit
2021-10-01 14:36     ` [dpdk-dev] [PATCH v3 5/6] ethdev: unify MTU checks Ferruh Yigit
2021-10-01 14:36     ` [dpdk-dev] [PATCH v3 6/6] examples/ip_reassembly: remove unused parameter Ferruh Yigit
2021-10-01 15:07     ` [dpdk-dev] [PATCH v3 1/6] ethdev: fix max Rx packet length Stephen Hemminger
2021-10-05 16:46       ` Ferruh Yigit
2021-10-05 17:16     ` [dpdk-dev] [PATCH v4 " Ferruh Yigit
2021-10-05 17:16       ` [dpdk-dev] [PATCH v4 2/6] ethdev: move jumbo frame offload check to library Ferruh Yigit
2021-10-08  8:39         ` Xu, Rosen
2021-10-05 17:16       ` [dpdk-dev] [PATCH v4 3/6] ethdev: move check to library for MTU set Ferruh Yigit
2021-10-05 17:16       ` [dpdk-dev] [PATCH v4 4/6] ethdev: remove jumbo offload flag Ferruh Yigit
2021-10-08  8:38         ` Xu, Rosen
2021-10-05 17:16       ` [dpdk-dev] [PATCH v4 5/6] ethdev: unify MTU checks Ferruh Yigit
2021-10-05 17:16       ` [dpdk-dev] [PATCH v4 6/6] examples/ip_reassembly: remove unused parameter Ferruh Yigit
2021-10-05 22:07       ` [dpdk-dev] [PATCH v4 1/6] ethdev: fix max Rx packet length Ajit Khaparde
2021-10-06  6:08         ` Somnath Kotur
2021-10-08  8:36       ` Xu, Rosen
2021-10-10  6:30       ` Matan Azrad
2021-10-11 21:59         ` Ferruh Yigit
2021-10-12  7:03           ` Matan Azrad
2021-10-12 11:03             ` Ferruh Yigit
2021-10-07 16:56     ` [dpdk-dev] [PATCH v5 " Ferruh Yigit
2021-10-07 16:56       ` [dpdk-dev] [PATCH v5 2/6] ethdev: move jumbo frame offload check to library Ferruh Yigit
2021-10-08 17:20         ` Ananyev, Konstantin
2021-10-09 10:58         ` lihuisong (C)
2021-10-07 16:56       ` [dpdk-dev] [PATCH v5 3/6] ethdev: move check to library for MTU set Ferruh Yigit
2021-10-08 17:19         ` Ananyev, Konstantin
2021-10-07 16:56       ` [dpdk-dev] [PATCH v5 4/6] ethdev: remove jumbo offload flag Ferruh Yigit
2021-10-08 17:11         ` Ananyev, Konstantin
2021-10-09 11:09           ` lihuisong (C)
2021-10-10  5:46         ` Matan Azrad
2021-10-07 16:56       ` [dpdk-dev] [PATCH v5 5/6] ethdev: unify MTU checks Ferruh Yigit
2021-10-08 16:51         ` Ananyev, Konstantin
2021-10-11 19:50           ` Ferruh Yigit
2021-10-09 11:43         ` lihuisong (C)
2021-10-11 20:15           ` Ferruh Yigit
2021-10-12  4:02             ` lihuisong (C)
2021-10-07 16:56       ` [dpdk-dev] [PATCH v5 6/6] examples/ip_reassembly: remove unused parameter Ferruh Yigit
2021-10-08 16:53         ` Ananyev, Konstantin
2021-10-08 15:57       ` [dpdk-dev] [PATCH v5 1/6] ethdev: fix max Rx packet length Ananyev, Konstantin
2021-10-11 19:47         ` Ferruh Yigit
2021-10-09 10:56       ` lihuisong (C)
2021-10-11 23:53     ` [dpdk-dev] [PATCH v6 " Ferruh Yigit
2021-10-11 23:53       ` [dpdk-dev] [PATCH v6 2/6] ethdev: move jumbo frame offload check to library Ferruh Yigit
2021-10-11 23:53       ` [dpdk-dev] [PATCH v6 3/6] ethdev: move check to library for MTU set Ferruh Yigit
2021-10-11 23:53       ` [dpdk-dev] [PATCH v6 4/6] ethdev: remove jumbo offload flag Ferruh Yigit
2021-10-12 17:20         ` Hyong Youb Kim (hyonkim)
2021-10-13  7:16         ` Michał Krawczyk
2021-10-11 23:53       ` [dpdk-dev] [PATCH v6 5/6] ethdev: unify MTU checks Ferruh Yigit
2021-10-12  5:58         ` Andrew Rybchenko
2021-10-11 23:53       ` [dpdk-dev] [PATCH v6 6/6] examples/ip_reassembly: remove unused parameter Ferruh Yigit
2021-10-12  6:02       ` [dpdk-dev] [PATCH v6 1/6] ethdev: fix max Rx packet length Andrew Rybchenko
2021-10-12  9:42       ` Ananyev, Konstantin
2021-10-13  7:08       ` Xu, Rosen
2021-10-15  1:31       ` Hyong Youb Kim (hyonkim)
2021-10-16  0:24       ` Ferruh Yigit
2021-10-18  8:54         ` Ferruh Yigit
2021-10-18 13:48     ` [dpdk-dev] [PATCH v7 " Ferruh Yigit
2021-10-18 13:48       ` [dpdk-dev] [PATCH v7 2/6] ethdev: move jumbo frame offload check to library Ferruh Yigit
2021-10-18 13:48       ` [dpdk-dev] [PATCH v7 3/6] ethdev: move check to library for MTU set Ferruh Yigit
2021-10-18 13:48       ` [dpdk-dev] [PATCH v7 4/6] ethdev: remove jumbo offload flag Ferruh Yigit
2021-10-21  0:43         ` Thomas Monjalon
2021-10-22 11:25           ` Ferruh Yigit
2021-10-22 11:29             ` Andrew Rybchenko
2021-10-18 13:48       ` [dpdk-dev] [PATCH v7 5/6] ethdev: unify MTU checks Ferruh Yigit
2021-10-18 13:48       ` [dpdk-dev] [PATCH v7 6/6] examples/ip_reassembly: remove unused parameter Ferruh Yigit
2021-10-18 17:31       ` [dpdk-dev] [PATCH v7 1/6] ethdev: fix max Rx packet length Ferruh Yigit
2021-11-05 14:19         ` Xueming(Steven) Li
2021-11-05 14:39           ` Ferruh Yigit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4e1ae26c-197b-ea45-0860-66c195d1f820@intel.com \
    --to=ferruh.yigit@intel.com \
    --cc=dev@dpdk.org \
    --cc=lihuisong@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).