From: Zhe Tao <zhe.tao@intel.com>
To: dev@dpdk.org
Cc: zhe.tao@intel.com, jingjing.wu@intel.com
Subject: [dpdk-dev] [PATCH v15 1/2] i40e: add floating VEB support
Date: Wed, 29 Jun 2016 21:06:02 +0800 [thread overview]
Message-ID: <1467205563-25901-2-git-send-email-zhe.tao@intel.com> (raw)
In-Reply-To: <1467205563-25901-1-git-send-email-zhe.tao@intel.com>
The standard Virtual Ethernet Bridge(VEB) definition in 1Qbg is a bridge
which has an uplink port to the outside world (maybe another bridge),
but a "floating" VEB is a special VEB without an uplink port to the
outside. Instead, traffic can be sent from one VF to another using the
floating VEB - even when the physical link on the NIC port is down.
VFs VSIs connect either to the standard VEB/VEPA or to the floating VEB,
they cannot connect to both of them. The PF, VMDQ and FD VSIs still
connect to the normal VEB/VEPA.
Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
drivers/net/i40e/i40e_ethdev.c | 113 +++++++++++++++++++++++++++++++++--------
drivers/net/i40e/i40e_ethdev.h | 7 +++
drivers/net/i40e/i40e_pf.c | 12 ++++-
3 files changed, 108 insertions(+), 24 deletions(-)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index f94ad87..5efcbc2 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3768,21 +3768,27 @@ i40e_veb_release(struct i40e_veb *veb)
struct i40e_vsi *vsi;
struct i40e_hw *hw;
- if (veb == NULL || veb->associate_vsi == NULL)
+ if (veb == NULL)
return -EINVAL;
if (!TAILQ_EMPTY(&veb->head)) {
PMD_DRV_LOG(ERR, "VEB still has VSI attached, can't remove");
return -EACCES;
}
+ /* associate_vsi field is NULL for floating VEB */
+ if (veb->associate_vsi != NULL) {
+ vsi = veb->associate_vsi;
+ hw = I40E_VSI_TO_HW(vsi);
- vsi = veb->associate_vsi;
- hw = I40E_VSI_TO_HW(vsi);
+ vsi->uplink_seid = veb->uplink_seid;
+ vsi->veb = NULL;
+ } else {
+ veb->associate_pf->main_vsi->floating_veb = NULL;
+ hw = I40E_VSI_TO_HW(veb->associate_pf->main_vsi);
+ }
- vsi->uplink_seid = veb->uplink_seid;
i40e_aq_delete_element(hw, veb->seid, NULL);
rte_free(veb);
- vsi->veb = NULL;
return I40E_SUCCESS;
}
@@ -3794,9 +3800,9 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
int ret;
struct i40e_hw *hw;
- if (NULL == pf || vsi == NULL) {
- PMD_DRV_LOG(ERR, "veb setup failed, "
- "associated VSI shouldn't null");
+ if (pf == NULL) {
+ PMD_DRV_LOG(ERR,
+ "veb setup failed, associated PF shouldn't null");
return NULL;
}
hw = I40E_PF_TO_HW(pf);
@@ -3808,11 +3814,19 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
}
veb->associate_vsi = vsi;
+ veb->associate_pf = pf;
TAILQ_INIT(&veb->head);
- veb->uplink_seid = vsi->uplink_seid;
+ veb->uplink_seid = vsi ? vsi->uplink_seid : 0;
- ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
- I40E_DEFAULT_TCMAP, false, &veb->seid, false, NULL);
+ /* create floating veb if vsi is NULL */
+ if (vsi != NULL) {
+ ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
+ I40E_DEFAULT_TCMAP, false,
+ &veb->seid, false, NULL);
+ } else {
+ ret = i40e_aq_add_veb(hw, 0, 0, I40E_DEFAULT_TCMAP,
+ true, &veb->seid, false, NULL);
+ }
if (ret != I40E_SUCCESS) {
PMD_DRV_LOG(ERR, "Add veb failed, aq_err: %d",
@@ -3828,10 +3842,10 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
hw->aq.asq_last_status);
goto fail;
}
-
/* Get VEB bandwidth, to be implemented */
/* Now associated vsi binding to the VEB, set uplink to this VEB */
- vsi->uplink_seid = veb->seid;
+ if (vsi)
+ vsi->uplink_seid = veb->seid;
return veb;
fail:
@@ -3847,6 +3861,7 @@ i40e_vsi_release(struct i40e_vsi *vsi)
struct i40e_vsi_list *vsi_list;
int ret;
struct i40e_mac_filter *f;
+ uint16_t user_param = vsi->user_param;
if (!vsi)
return I40E_SUCCESS;
@@ -3864,12 +3879,22 @@ i40e_vsi_release(struct i40e_vsi *vsi)
i40e_veb_release(vsi->veb);
}
+ if (vsi->floating_veb) {
+ TAILQ_FOREACH(vsi_list, &vsi->floating_veb->head, list) {
+ if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
+ return -1;
+ TAILQ_REMOVE(&vsi->floating_veb->head, vsi_list, list);
+ }
+ }
+
/* Remove all macvlan filters of the VSI */
i40e_vsi_remove_all_macvlan_filter(vsi);
TAILQ_FOREACH(f, &vsi->mac_list, next)
rte_free(f);
- if (vsi->type != I40E_VSI_MAIN) {
+ if (vsi->type != I40E_VSI_MAIN &&
+ ((vsi->type != I40E_VSI_SRIOV) ||
+ !pf->floating_veb_list[user_param])) {
/* Remove vsi from parent's sibling list */
if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
@@ -3883,6 +3908,24 @@ i40e_vsi_release(struct i40e_vsi *vsi)
if (ret != I40E_SUCCESS)
PMD_DRV_LOG(ERR, "Failed to delete element");
}
+
+ if ((vsi->type == I40E_VSI_SRIOV) &&
+ pf->floating_veb_list[user_param]) {
+ /* Remove vsi from parent's sibling list */
+ if (vsi->parent_vsi == NULL ||
+ vsi->parent_vsi->floating_veb == NULL) {
+ PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
+ return I40E_ERR_PARAM;
+ }
+ TAILQ_REMOVE(&vsi->parent_vsi->floating_veb->head,
+ &vsi->sib_vsi_list, list);
+
+ /* Remove all switch element of the VSI */
+ ret = i40e_aq_delete_element(hw, vsi->seid, NULL);
+ if (ret != I40E_SUCCESS)
+ PMD_DRV_LOG(ERR, "Failed to delete element");
+ }
+
i40e_res_pool_free(&pf->qp_pool, vsi->base_queue);
if (vsi->type != I40E_VSI_SRIOV)
@@ -4051,7 +4094,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
struct ether_addr broadcast =
{.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
- if (type != I40E_VSI_MAIN && uplink_vsi == NULL) {
+ if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
+ uplink_vsi == NULL) {
PMD_DRV_LOG(ERR, "VSI setup failed, "
"VSI link shouldn't be NULL");
return NULL;
@@ -4063,11 +4107,18 @@ i40e_vsi_setup(struct i40e_pf *pf,
return NULL;
}
- /* If uplink vsi didn't setup VEB, create one first */
- if (type != I40E_VSI_MAIN && uplink_vsi->veb == NULL) {
+ /* two situations
+ * 1.type is not MAIN and uplink vsi is not NULL
+ * If uplink vsi didn't setup VEB, create one first under veb field
+ * 2.type is SRIOV and the uplink is NULL
+ * If floating VEB is NULL, create one veb under floating veb field
+ */
+
+ if (type != I40E_VSI_MAIN && uplink_vsi != NULL &&
+ uplink_vsi->veb == NULL) {
uplink_vsi->veb = i40e_veb_setup(pf, uplink_vsi);
- if (NULL == uplink_vsi->veb) {
+ if (uplink_vsi->veb == NULL) {
PMD_DRV_LOG(ERR, "VEB setup failed");
return NULL;
}
@@ -4075,6 +4126,16 @@ i40e_vsi_setup(struct i40e_pf *pf,
i40e_enable_pf_lb(pf);
}
+ if (type == I40E_VSI_SRIOV && uplink_vsi == NULL &&
+ pf->main_vsi->floating_veb == NULL) {
+ pf->main_vsi->floating_veb = i40e_veb_setup(pf, uplink_vsi);
+
+ if (pf->main_vsi->floating_veb == NULL) {
+ PMD_DRV_LOG(ERR, "VEB setup failed");
+ return NULL;
+ }
+ }
+
vsi = rte_zmalloc("i40e_vsi", sizeof(struct i40e_vsi), 0);
if (!vsi) {
PMD_DRV_LOG(ERR, "Failed to allocate memory for vsi");
@@ -4084,7 +4145,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
vsi->type = type;
vsi->adapter = I40E_PF_TO_ADAPTER(pf);
vsi->max_macaddrs = I40E_NUM_MACADDR_MAX;
- vsi->parent_vsi = uplink_vsi;
+ vsi->parent_vsi = uplink_vsi ? uplink_vsi : pf->main_vsi;
vsi->user_param = user_param;
/* Allocate queues */
switch (vsi->type) {
@@ -4238,7 +4299,10 @@ i40e_vsi_setup(struct i40e_pf *pf,
* For other VSI, the uplink_seid equals to uplink VSI's
* uplink_seid since they share same VEB
*/
- vsi->uplink_seid = uplink_vsi->uplink_seid;
+ if (uplink_vsi == NULL)
+ vsi->uplink_seid = pf->main_vsi->floating_veb->seid;
+ else
+ vsi->uplink_seid = uplink_vsi->uplink_seid;
ctxt.pf_num = hw->pf_id;
ctxt.vf_num = hw->func_caps.vf_base_id + user_param;
ctxt.uplink_seid = vsi->uplink_seid;
@@ -4346,8 +4410,13 @@ i40e_vsi_setup(struct i40e_pf *pf,
vsi->seid = ctxt.seid;
vsi->vsi_id = ctxt.vsi_number;
vsi->sib_vsi_list.vsi = vsi;
- TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
- &vsi->sib_vsi_list, list);
+ if (vsi->type == I40E_VSI_SRIOV && uplink_vsi == NULL) {
+ TAILQ_INSERT_TAIL(&pf->main_vsi->floating_veb->head,
+ &vsi->sib_vsi_list, list);
+ } else {
+ TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
+ &vsi->sib_vsi_list, list);
+ }
}
/* MAC/VLAN configuration */
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index cfd2399..19c9dea 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -55,6 +55,8 @@
#define I40E_VFTA_SIZE (4096 / I40E_UINT32_BIT_SIZE)
/* Maximun number of MAC addresses */
#define I40E_NUM_MACADDR_MAX 64
+/* Maximum number of VFs */
+#define I40E_MAX_VF 128
/*
* vlan_id is a 12 bit number.
@@ -219,6 +221,7 @@ struct i40e_bw_info {
struct i40e_veb {
struct i40e_vsi_list_head head;
struct i40e_vsi *associate_vsi; /* Associate VSI who owns the VEB */
+ struct i40e_pf *associate_pf; /* Associate PF who owns the VEB */
uint16_t seid; /* The seid of VEB itself */
uint16_t uplink_seid; /* The uplink seid of this VEB */
uint16_t stats_idx;
@@ -259,6 +262,7 @@ struct i40e_vsi {
struct i40e_vsi_list sib_vsi_list; /* sibling vsi list */
struct i40e_vsi *parent_vsi;
struct i40e_veb *veb; /* Associated veb, could be null */
+ struct i40e_veb *floating_veb; /* Associated floating veb */
bool offset_loaded;
enum i40e_vsi_type type; /* VSI types */
uint16_t vlan_num; /* Total VLAN number */
@@ -450,6 +454,9 @@ struct i40e_pf {
struct i40e_fc_conf fc_conf; /* Flow control conf */
struct i40e_mirror_rule_list mirror_list;
uint16_t nb_mirror_rule; /* The number of mirror rules */
+ bool floating_veb; /* The flag to use the floating VEB */
+ /* The floating enable flag for the specific VF */
+ bool floating_veb_list[I40E_MAX_VF];
};
enum pending_msg {
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 5afd61a..dc5b079 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -124,6 +124,7 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
{
uint32_t val, i;
struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
+ struct i40e_pf *pf;
uint16_t vf_id, abs_vf_id, vf_msix_num;
int ret;
struct i40e_virtchnl_queue_select qsel;
@@ -131,6 +132,7 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
if (vf == NULL)
return -EINVAL;
+ pf = vf->pf;
vf_id = vf->vf_idx;
abs_vf_id = vf_id + hw->func_caps.vf_base_id;
@@ -224,8 +226,14 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
I40E_WRITE_FLUSH(hw);
/* Allocate resource again */
- vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
- vf->pf->main_vsi, vf->vf_idx);
+ if (pf->floating_veb && pf->floating_veb_list[vf_id]) {
+ vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+ NULL, vf->vf_idx);
+ } else {
+ vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+ vf->pf->main_vsi, vf->vf_idx);
+ }
+
if (vf->vsi == NULL) {
PMD_DRV_LOG(ERR, "Add vsi failed");
return -EFAULT;
--
2.1.4
next prev parent reply other threads:[~2016-06-29 13:07 UTC|newest]
Thread overview: 79+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-21 7:24 [dpdk-dev] [PATCH 0/2] Add floating VEB support for i40e Zhe Tao
2016-01-21 7:24 ` [dpdk-dev] PATCH 1/2] i40e: support floating VEB config Zhe Tao
2016-01-21 7:29 ` David Marchand
2016-01-21 7:53 ` Vincent JARDIN
2016-02-03 8:53 ` Xu, Qian Q
2016-02-23 9:13 ` [dpdk-dev] [PATCH 0/2 v2] i40e: Add floating VEB support for i40e Zhe Tao
2016-02-23 9:13 ` [dpdk-dev] [PATCH 1/2 v2] i40e: support floating VEB config Zhe Tao
2016-02-25 0:55 ` Wu, Jingjing
2016-02-23 9:13 ` [dpdk-dev] [PATCH 2/2 v2] i40e: Add floating VEB support in i40e Zhe Tao
2016-02-25 1:15 ` Wu, Jingjing
2016-02-25 6:31 ` [dpdk-dev] [PATCH 0/2 v3] i40e: Add floating VEB support for i40e Zhe Tao
2016-02-25 6:31 ` [dpdk-dev] [PATCH 1/2 v3] i40e: support floating VEB config Zhe Tao
2016-02-25 6:31 ` [dpdk-dev] [PATCH 2/2 v3] i40e: Add floating VEB support in i40e Zhe Tao
2016-03-02 2:31 ` Xu, Qian Q
2016-03-02 8:08 ` [dpdk-dev] [PATCH 0/2 v4] i40e: Add floating VEB support for i40e Zhe Tao
2016-03-02 8:08 ` [dpdk-dev] [PATCH 1/2 v4] i40e: support floating VEB config Zhe Tao
2016-03-02 8:08 ` [dpdk-dev] [PATCH 2/2 v4] i40e: Add floating VEB support in i40e Zhe Tao
2016-03-23 12:27 ` [dpdk-dev] [PATCH 0/2 v5] i40e: Add floating VEB support for i40e Zhe Tao
2016-03-23 12:27 ` [dpdk-dev] [PATCH 1/2 v5] i40e: support floating VEB config Zhe Tao
2016-03-23 12:51 ` Thomas Monjalon
2016-03-24 2:31 ` Zhe Tao
2016-03-23 12:27 ` [dpdk-dev] [PATCH 2/2 v5] i40e: Add floating VEB support in i40e Zhe Tao
2016-03-24 10:48 ` [dpdk-dev] [PATCH 0/2 v6] i40e: Add floating VEB support for i40e Zhe Tao
2016-03-24 10:48 ` [dpdk-dev] [PATCH 1/2 v6] i40e: support floating VEB config Zhe Tao
2016-03-24 10:48 ` [dpdk-dev] [PATCH 2/2 v6] i40e: Add floating VEB support in i40e Zhe Tao
2016-03-25 8:41 ` [dpdk-dev] [PATCH 0/3 v7] i40e: Add floating VEB support for i40e Zhe Tao
2016-03-25 8:41 ` [dpdk-dev] [PATCH 1/3 v7] i40e: support floating VEB config Zhe Tao
2016-03-28 2:23 ` Xu, Qian Q
2016-03-25 8:41 ` [dpdk-dev] [PATCH 2/3 v7] i40e: Add floating VEB support in i40e Zhe Tao
2016-04-20 7:31 ` Wu, Jingjing
2016-03-25 8:42 ` [dpdk-dev] [PATCH 3/3 v7] i40e: Add global reset support for i40e Zhe Tao
2016-04-20 10:15 ` Wu, Jingjing
2016-03-25 15:28 ` [dpdk-dev] [PATCH 0/3 v7] i40e: Add floating VEB " Bruce Richardson
2016-04-20 14:22 ` Bruce Richardson
2016-05-24 17:28 ` [dpdk-dev] [PATCH v8 0/3] " Zhe Tao
2016-05-24 17:28 ` [dpdk-dev] [PATCH v8 1/3] i40e: support floating VEB config Zhe Tao
2016-06-09 15:50 ` Bruce Richardson
2016-05-24 17:28 ` [dpdk-dev] [PATCH v8 2/3] i40e: Add floating VEB support in i40e Zhe Tao
2016-06-09 15:55 ` Bruce Richardson
2016-05-24 17:28 ` [dpdk-dev] [PATCH v8 3/3] i40e: add floating VEB extension support Zhe Tao
2016-05-30 15:49 ` Peng, Yuan
2016-06-09 15:57 ` Bruce Richardson
2016-05-24 19:22 ` [dpdk-dev] [PATCH v8 0/3] i40e: Add floating VEB support for i40e Stephen Hemminger
2016-05-25 10:05 ` Thomas Monjalon
2016-05-31 2:25 ` Wu, Jingjing
2016-06-13 6:45 ` [dpdk-dev] [PATCH v9 0/3] i40e: add " Zhe Tao
2016-06-13 6:45 ` [dpdk-dev] [PATCH v9 1/3] i40e: support floating VEB config Zhe Tao
2016-06-13 6:45 ` [dpdk-dev] [PATCH v9 2/3] i40e: add floating VEB support in i40e Zhe Tao
2016-06-13 6:45 ` [dpdk-dev] [PATCH v9 3/3] i40e: add floating VEB extension support Zhe Tao
2016-06-13 8:02 ` [dpdk-dev] [PATCH v10 0/3] i40e: add floating VEB support for i40e Zhe Tao
2016-06-13 8:02 ` [dpdk-dev] [PATCH v10 1/3] i40e: support floating VEB config Zhe Tao
2016-06-13 8:02 ` [dpdk-dev] [PATCH v10 2/3] i40e: add floating VEB support in i40e Zhe Tao
2016-06-13 8:02 ` [dpdk-dev] [PATCH v10 3/3] i40e: add floating VEB extension support Zhe Tao
2016-06-14 3:38 ` [dpdk-dev] [PATCH v10 0/3] i40e: add floating VEB support for i40e Wu, Jingjing
2016-06-14 5:57 ` [dpdk-dev] [PATCH v11 " Zhe Tao
2016-06-13 21:44 ` Zhe Tao
2016-06-14 5:57 ` [dpdk-dev] [PATCH v11 1/3] i40e: support floating VEB config Zhe Tao
2016-06-14 5:57 ` [dpdk-dev] [PATCH v11 2/3] i40e: add floating VEB support in i40e Zhe Tao
2016-06-14 5:57 ` [dpdk-dev] [PATCH v11 3/3] i40e: add floating VEB extension support Zhe Tao
2016-06-24 8:29 ` [dpdk-dev] [PATCH v12 0/2] i40e: add floating VEB support for i40e Zhe Tao
2016-06-24 8:29 ` [dpdk-dev] [PATCH v12 1/2] i40e: support floating VEB config Zhe Tao
2016-06-24 9:27 ` Bruce Richardson
2016-06-24 11:14 ` Ferruh Yigit
2016-06-26 20:28 ` Zhe Tao
2016-06-24 8:29 ` [dpdk-dev] [PATCH v12 2/2] i40e: add floating VEB support in i40e Zhe Tao
2016-06-27 5:12 ` [dpdk-dev] [PATCH v13 0/2] i40e: add floating VEB support for i40e Zhe Tao
2016-06-27 5:12 ` [dpdk-dev] [PATCH v13 1/2] i40e: support floating VEB config Zhe Tao
2016-06-27 5:12 ` [dpdk-dev] [PATCH v13 2/2] i40e: add floating VEB support in i40e Zhe Tao
2016-06-27 7:20 ` [dpdk-dev] [PATCH v14 0/2] i40e: add floating VEB support for i40e Zhe Tao
2016-06-27 7:20 ` [dpdk-dev] [PATCH v14 1/2] i40e: support floating VEB config Zhe Tao
2016-06-27 7:20 ` [dpdk-dev] [PATCH v14 2/2] i40e: add floating VEB support in i40e Zhe Tao
2016-06-27 13:22 ` [dpdk-dev] [PATCH v14 0/2] i40e: add floating VEB support for i40e Ferruh Yigit
2016-06-29 9:42 ` Bruce Richardson
2016-06-29 13:06 ` [dpdk-dev] [PATCH v15 " Zhe Tao
2016-06-29 13:06 ` Zhe Tao [this message]
2016-06-29 13:06 ` [dpdk-dev] [PATCH v15 2/2] i40e: add device args to enable a floating VEB Zhe Tao
2016-06-29 13:47 ` Mcnamara, John
2016-06-29 14:22 ` Bruce Richardson
2016-01-21 7:24 ` [dpdk-dev] [PATCH 2/2] i40e: Add floating VEB support in i40e Zhe Tao
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=1467205563-25901-2-git-send-email-zhe.tao@intel.com \
--to=zhe.tao@intel.com \
--cc=dev@dpdk.org \
--cc=jingjing.wu@intel.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).