From: Dongdong Liu <hidden> Date: 2021-07-23 11:08:33
10-Bit Tag capability, introduced in PCIe-4.0 increases the total Tag
field size from 8 bits to 10 bits.
This patchset is to enable 10-Bit tag for PCIe EP devices (include VF) and
RP device.
V5->V6:
- Rebased on v5.14-rc2.
- Add Reviewed-by: Christoph Hellwig [off-list ref] in [PATCH V6 2/8].
- PCI: Add "pci=disable_10bit_tag=" parameter for peer-to-peer support.
- Add a 10-bit tag check in P2PDMA.
- Simplified implementation in [PATCH V6 6/8].
- Fix some comments in [PATCH V6 4/8].
V4->V5:
- Fix warning variable 'capa' is uninitialized.
- Fix warning unused variable 'pchild'.
V3->V4:
- Get the value of pcie_devcap2 in set_pcie_port_type().
- Add Reviewed-by: Christoph Hellwig [off-list ref] in [PATCH V4 1/6],
[PATCH V4 3/6], [PATCH V4 4/6], [PATCH V4 5/6].
- Fix some code style.
- Rebased on v5.13-rc6.
V2->V3:
- Use cached Device Capabilities Register suggested by Christoph.
- Fix code style to avoid > 80 char lines.
- Renamve devcap2 to pcie_devcap2.
V1->V2: Fix some comments by Christoph.
- Store the devcap2 value in the pci_dev instead of reading it multiple
times.
- Change pci_info to pci_dbg to avoid the noisy log.
- Rename ext_10bit_tag_comp_path to ext_10bit_tag.
- Fix the compile error.
- Rebased on v5.13-rc1.
Dongdong Liu (8):
PCI: Use cached Device Capabilities Register
PCI: Use cached Device Capabilities 2 Register
PCI: Add 10-Bit Tag register definitions
PCI: Enable 10-Bit tag support for PCIe Endpoint devices
PCI/IOV: Enable 10-Bit tag support for PCIe VF devices
PCI: Enable 10-Bit tag support for PCIe RP devices
PCI: Add "pci=disable_10bit_tag=" parameter for peer-to-peer support
PCI/P2PDMA: Add a 10-bit tag check in P2PDMA
Documentation/admin-guide/kernel-parameters.txt | 7 +++
drivers/media/pci/cobalt/cobalt-driver.c | 5 +-
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 4 +-
drivers/pci/iov.c | 8 +++
drivers/pci/p2pdma.c | 38 +++++++++++++
drivers/pci/pci.c | 70 ++++++++++++++++++++----
drivers/pci/pci.h | 1 +
drivers/pci/pcie/aspm.c | 11 ++--
drivers/pci/pcie/portdrv_pci.c | 72 +++++++++++++++++++++++++
drivers/pci/probe.c | 69 +++++++++++++++++++-----
drivers/pci/quirks.c | 3 +-
include/linux/pci.h | 5 ++
include/uapi/linux/pci_regs.h | 5 ++
13 files changed, 261 insertions(+), 37 deletions(-)
--
2.7.4
From: Dongdong Liu <hidden> Date: 2021-07-23 11:08:33
Add 10-Bit Tag register definitions for use in subsequen patches.
See the PCIe 5.0 spec section 7.5.3.15 and 9.3.3.2.
Signed-off-by: Dongdong Liu <redacted>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
include/uapi/linux/pci_regs.h | 5 +++++
1 file changed, 5 insertions(+)
From: Dongdong Liu <hidden> Date: 2021-07-23 11:08:37
PCIe spec 5.0r1.0 section 2.2.6.2 implementation note, In configurations
where a Requester with 10-Bit Tag Requester capability needs to target
multiple Completers, one needs to ensure that the Requester sends 10-Bit
Tag Requests only to Completers that have 10-Bit Tag Completer capability.
So we enable 10-Bit Tag Requester for root port only when the devices
under the root port support 10-Bit Tag Completer.
Signed-off-by: Dongdong Liu <redacted>
---
drivers/pci/pcie/portdrv_pci.c | 69 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
@@ -90,6 +90,72 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = {#define PCIE_PORTDRV_PM_OPS NULL#endif /* !PM */+staticintpci_10bit_tag_comp_support(structpci_dev*dev,void*data)+{+bool*support=(bool*)data;++if(!pci_is_pcie(dev)){+*support=false;+return1;+}++/*+*PCIespec5.0r1.0section2.2.6.2implementationnote.+*ForconfigurationswhereaRequesterwith10-BitTagRequester+*capabilitytargetsCompleterswheresomedoandsomedonothave+*10-BitTagCompletercapability,howtheRequesterdetermineswhich+*NPRsinclude10-BitTagsisoutsidethescopeofthisspecification.+*Sowedonotconsiderhotplugscenario.+*/+if(dev->is_hotplug_bridge){+*support=false;+return1;+}++if(!(dev->pcie_devcap2&PCI_EXP_DEVCAP2_10BIT_TAG_COMP)){+*support=false;+return1;+}++return0;+}++staticvoidpci_configure_rp_10bit_tag(structpci_dev*dev)+{+boolsupport=true;++if(dev->subordinate==NULL)+return;++/* If no devices under the root port, no need to enable 10-Bit Tag. */+if(list_empty(&dev->subordinate->devices))+return;++pci_10bit_tag_comp_support(dev,&support);+if(!support)+return;++/*+*PCIespec5.0r1.0section2.2.6.2implementationnote.+*InconfigurationswhereaRequesterwith10-BitTagRequester+*capabilityneedstotargetmultipleCompleters,oneneedstoensure+*thattheRequestersends10-BitTagRequestsonlytoCompleters+*thathave10-BitTagCompletercapability.Soweenable10-BitTag+*Requesterforrootportonlywhenthedevicesundertherootport+*support10-BitTagCompleter.+*/+pci_walk_bus(dev->subordinate,pci_10bit_tag_comp_support,&support);+if(!support)+return;++if(!(dev->pcie_devcap2&PCI_EXP_DEVCAP2_10BIT_TAG_REQ))+return;++pci_dbg(dev,"enabling 10-Bit Tag Requester\n");+pcie_capability_set_word(dev,PCI_EXP_DEVCTL2,+PCI_EXP_DEVCTL2_10BIT_TAG_REQ_EN);+}+/**pcie_portdrv_probe-ProbePCI-Expressportdevices*@dev:PCI-Expressportdevicebeingprobed
@@ -111,6 +177,9 @@ static int pcie_portdrv_probe(struct pci_dev *dev,(type!=PCI_EXP_TYPE_RC_EC)))return-ENODEV;+if(type==PCI_EXP_TYPE_ROOT_PORT)+pci_configure_rp_10bit_tag(dev);+if(type==PCI_EXP_TYPE_RC_EC)pcie_link_rcec(dev);
From: Dongdong Liu <hidden> Date: 2021-07-23 11:08:37
PCIe spec 5.0 r1.0 section 2.2.6.2 says that if an Endpoint supports
sending Requests to other Endpoints (as opposed to host memory), the
Endpoint must not send 10-Bit Tag Requests to another given Endpoint
unless an implementation-specific mechanism determines that the Endpoint
supports 10-Bit Tag Completer capability. Add "pci=disable_10bit_tag="
parameter to disable 10-Bit Tag Requester if the peer device does not
support the 10-Bit Tag Completer. This will make P2P traffic safe.
Signed-off-by: Dongdong Liu <redacted>
---
Documentation/admin-guide/kernel-parameters.txt | 7 ++++
drivers/pci/pci.c | 56 +++++++++++++++++++++++++
drivers/pci/pci.h | 1 +
drivers/pci/pcie/portdrv_pci.c | 13 +++---
drivers/pci/probe.c | 9 ++--
5 files changed, 78 insertions(+), 8 deletions(-)
@@ -4019,6 +4019,13 @@ bridges without forcing it upstream. Note: this removes isolation between devices and may put more devices in an IOMMU group.+ disable_10bit_tag=<pci_dev>[; ...]+ Specify one or more PCI devices (in the format+ specified above) separated by semicolons.+ Disable 10-Bit Tag Requester if the peer+ device does not support the 10-Bit Tag+ Completer.This will make P2P traffic safe.+ force_floating [S390] Force usage of floating interrupts. nomio [S390] Do not use MIO instructions. norid [S390] ignore the RID field and force use of
@@ -6568,6 +6568,59 @@ int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent)}#endif+staticconstchar*disable_10bit_tag_param;++voidpci_disable_10bit_tag(structpci_dev*dev)+{+intret=0;+constchar*p;+#ifdef CONFIG_PCI_IOV+structpci_sriov*iov;+#endif++if(!disable_10bit_tag_param)+return;++p=disable_10bit_tag_param;+while(*p){+ret=pci_dev_str_match(dev,p,&p);+if(ret<0){+pr_info_once("PCI: Can't parse disable_10bit_tag parameter: %s\n",+disable_10bit_tag_param);++break;+}elseif(ret==1){+/* Found a match */+break;+}++if(*p!=';'&&*p!=','){+/* End of param or invalid format */+break;+}+p++;+}++if(ret!=1)+return;++#ifdef CONFIG_PCI_IOV+if(dev->is_virtfn){+iov=dev->physfn->sriov;+iov->ctrl&=~PCI_SRIOV_CTRL_VF_10BIT_TAG_REQ_EN;+pci_write_config_word(dev,iov->pos+PCI_SRIOV_CTRL,+iov->ctrl);+pci_info(dev,"disabled PF SRIOV 10-Bit Tag Requester\n");+return;+#endif+}++pcie_capability_clear_word(dev,PCI_EXP_DEVCTL2,+PCI_EXP_DEVCTL2_10BIT_TAG_REQ_EN);++pci_info(dev,"disabled 10-Bit Tag Requester\n");+}+/***pci_ext_cfg_avail-canweaccessextendedPCIconfigspace?*
@@ -125,15 +125,15 @@ static void pci_configure_rp_10bit_tag(struct pci_dev *dev)boolsupport=true;if(dev->subordinate==NULL)-return;+gotodisable_10bit_tag_req;/* If no devices under the root port, no need to enable 10-Bit Tag. */if(list_empty(&dev->subordinate->devices))-return;+gotodisable_10bit_tag_req;pci_10bit_tag_comp_support(dev,&support);if(!support)-return;+gotodisable_10bit_tag_req;/**PCIespec5.0r1.0section2.2.6.2implementationnote.
From: Dongdong Liu <hidden> Date: 2021-07-23 11:08:38
Add a 10-Bit Tag check in the P2PDMA code to ensure that a device with
10-Bit Tag Requester doesn't interact with a device that does not
support 10-BIT tag Completer. Before that happens, the kernel should
emit a warning saying to enable a ”pci=disable_10bit_tag=“ kernel
parameter.
Signed-off-by: Dongdong Liu <redacted>
---
drivers/pci/p2pdma.c | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
@@ -541,6 +542,39 @@ calc_map_type_and_dist(struct pci_dev *provider, struct pci_dev *client,returnmap_type;}++staticboolcheck_10bit_tags_vaild(structpci_dev*a,structpci_dev*b,+boolverbose)+{+boolreq;+boolcomp;+u16ctl2;++if(a->is_virtfn){+#ifdef CONFIG_PCI_IOV+req=!!(a->physfn->sriov->ctrl&+PCI_SRIOV_CTRL_VF_10BIT_TAG_REQ_EN);+#endif+}else{+pcie_capability_read_word(a,PCI_EXP_DEVCTL2,&ctl2);+req=!!(ctl2&PCI_EXP_DEVCTL2_10BIT_TAG_REQ_EN);+}++comp=!!(b->pcie_devcap2&PCI_EXP_DEVCAP2_10BIT_TAG_COMP);+if(req&&(!comp)){+if(verbose){+pci_warn(a,"cannot be used for peer-to-peer DMA as 10-Bit Tag Requester enable is set in device (%s), but peer device (%s) does not support the 10-Bit Tag Completer\n",+pci_name(a),pci_name(b));++pci_warn(a,"to disable 10-Bit Tag Requester for this device, add the kernel parameter: pci=disable_10bit_tag=%s\n",+pci_name(a));+}+returnfalse;+}++returntrue;+}+/***pci_p2pdma_distance_many-Determinethecumulativedistancebetween*ap2pdmaproviderandtheclientsinuse.
From: Dongdong Liu <hidden> Date: 2021-07-23 11:08:40
10-Bit Tag capability, introduced in PCIe-4.0 increases the total Tag
field size from 8 bits to 10 bits.
PCIe spec 5.0 r1.0 section 2.2.6.2 "Considerations for Implementing
10-Bit Tag Capabilities" Implementation Note.
For platforms where the RC supports 10-Bit Tag Completer capability,
it is highly recommended for platform firmware or operating software
that configures PCIe hierarchies to Set the 10-Bit Tag Requester Enable
bit automatically in Endpoints with 10-Bit Tag Requester capability. This
enables the important class of 10-Bit Tag capable adapters that send
Memory Read Requests only to host memory.
Signed-off-by: Dongdong Liu <redacted>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
drivers/pci/probe.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
include/linux/pci.h | 2 ++
2 files changed, 48 insertions(+), 1 deletion(-)
From: Dongdong Liu <hidden> Date: 2021-07-23 11:08:44
It will make sense to store the pcie_devcap value in the pci_dev
structure instead of reading Device Capabilities Register multiple
times. The fisrt place to use pcie_devcap is in set_pcie_port_type(),
get the pcie_devcap value here, then use cached pcie_devcap in the
needed place.
Acked-by: Hans Verkuil <redacted>
Signed-off-by: Dongdong Liu <redacted>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
drivers/media/pci/cobalt/cobalt-driver.c | 5 +++--
drivers/pci/pci.c | 5 +----
drivers/pci/pcie/aspm.c | 11 ++++-------
drivers/pci/probe.c | 11 +++--------
drivers/pci/quirks.c | 3 +--
include/linux/pci.h | 1 +
6 files changed, 13 insertions(+), 23 deletions(-)
@@ -831,8 +829,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)*DisableASPMforpre-1.1PCIedevice,wefollowMStouse*RBERbittodetermineifafunctionis1.1versiondevice*/-pcie_capability_read_dword(child,PCI_EXP_DEVCAP,®32);-if(!(reg32&PCI_EXP_DEVCAP_RBER)&&!aspm_force){+if(!(child->pcie_devcap&PCI_EXP_DEVCAP_RBER)&&!aspm_force){pci_info(child,"disabling ASPM on pre-1.1 PCIe device. You can enable it with 'pcie_aspm=force'\n");return-EINVAL;}
From: Dongdong Liu <hidden> Date: 2021-07-23 11:08:46
It will make sense to store the pcie_devcap2 value in the pci_dev
structure instead of reading Device Capabilities 2 Register multiple
times. Get the pcie_devcap2 value set_pcie_port_type(), then use
cached pcie_devcap2 in the needed place.
Signed-off-by: Dongdong Liu <redacted>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 4 +---
drivers/pci/pci.c | 9 ++++-----
drivers/pci/probe.c | 10 ++++------
include/linux/pci.h | 2 ++
4 files changed, 11 insertions(+), 14 deletions(-)
@@ -6304,7 +6304,6 @@ static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs)structpci_dev*pbridge;structport_info*pi;charname[IFNAMSIZ];-u32devcap2;u16flags;/* If we want to instantiate Virtual Functions, then our
@@ -6314,10 +6313,9 @@ static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs)*/pbridge=pdev->bus->self;pcie_capability_read_word(pbridge,PCI_EXP_FLAGS,&flags);-pcie_capability_read_dword(pbridge,PCI_EXP_DEVCAP2,&devcap2);if((flags&PCI_EXP_FLAGS_VERS)<2||-!(devcap2&PCI_EXP_DEVCAP2_ARI)){+!(pbridge->pcie_devcap2&PCI_EXP_DEVCAP2_ARI)){/* Our parent bridge does not support ARI so issue a*warningandskipinstantiatingtheVFs.They*won'tbereachable.
@@ -3700,7 +3700,7 @@ int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask){structpci_bus*bus=dev->bus;structpci_dev*bridge;-u32cap,ctl2;+u32ctl2;if(!pci_is_pcie(dev))return-EINVAL;
@@ -3724,19 +3724,18 @@ int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask)while(bus->parent){bridge=bus->self;-pcie_capability_read_dword(bridge,PCI_EXP_DEVCAP2,&cap);-switch(pci_pcie_type(bridge)){/* Ensure switch ports support AtomicOp routing */casePCI_EXP_TYPE_UPSTREAM:casePCI_EXP_TYPE_DOWNSTREAM:-if(!(cap&PCI_EXP_DEVCAP2_ATOMIC_ROUTE))+if(!(bridge->pcie_devcap2&+PCI_EXP_DEVCAP2_ATOMIC_ROUTE))return-EINVAL;break;/* Ensure root port supports all the sizes we care about */casePCI_EXP_TYPE_ROOT_PORT:-if((cap&cap_mask)!=cap_mask)+if((bridge->pcie_devcap2&cap_mask)!=cap_mask)return-EINVAL;break;}
From: Leon Romanovsky <leon@kernel.org> Date: 2021-07-23 11:33:02
On Fri, Jul 23, 2021 at 07:06:41PM +0800, Dongdong Liu wrote:
quoted hunk
PCIe spec 5.0 r1.0 section 2.2.6.2 says that if an Endpoint supports
sending Requests to other Endpoints (as opposed to host memory), the
Endpoint must not send 10-Bit Tag Requests to another given Endpoint
unless an implementation-specific mechanism determines that the Endpoint
supports 10-Bit Tag Completer capability. Add "pci=disable_10bit_tag="
parameter to disable 10-Bit Tag Requester if the peer device does not
support the 10-Bit Tag Completer. This will make P2P traffic safe.
Signed-off-by: Dongdong Liu <redacted>
---
Documentation/admin-guide/kernel-parameters.txt | 7 ++++
drivers/pci/pci.c | 56 +++++++++++++++++++++++++
drivers/pci/pci.h | 1 +
drivers/pci/pcie/portdrv_pci.c | 13 +++---
drivers/pci/probe.c | 9 ++--
5 files changed, 78 insertions(+), 8 deletions(-)
@@ -4019,6 +4019,13 @@ bridges without forcing it upstream. Note: this removes isolation between devices and may put more devices in an IOMMU group.+ disable_10bit_tag=<pci_dev>[; ...]+ Specify one or more PCI devices (in the format+ specified above) separated by semicolons.+ Disable 10-Bit Tag Requester if the peer+ device does not support the 10-Bit Tag+ Completer.This will make P2P traffic safe.
I can't imagine more awkward user experience than such kernel parameter.
As a user, I will need to boot the system, hope for the best that system
works, write down all PCI device numbers, guess which one doesn't work
properly, update grub with new command line argument and reboot the
system. Any HW change and this dance should be repeated.
Thanks
On Fri, Jul 23, 2021 at 07:06:41PM +0800, Dongdong Liu wrote:
quoted
PCIe spec 5.0 r1.0 section 2.2.6.2 says that if an Endpoint supports
sending Requests to other Endpoints (as opposed to host memory), the
Endpoint must not send 10-Bit Tag Requests to another given Endpoint
unless an implementation-specific mechanism determines that the Endpoint
supports 10-Bit Tag Completer capability. Add "pci=disable_10bit_tag="
parameter to disable 10-Bit Tag Requester if the peer device does not
support the 10-Bit Tag Completer. This will make P2P traffic safe.
Signed-off-by: Dongdong Liu <redacted>
---
Documentation/admin-guide/kernel-parameters.txt | 7 ++++
drivers/pci/pci.c | 56 +++++++++++++++++++++++++
drivers/pci/pci.h | 1 +
drivers/pci/pcie/portdrv_pci.c | 13 +++---
drivers/pci/probe.c | 9 ++--
5 files changed, 78 insertions(+), 8 deletions(-)
@@ -4019,6 +4019,13 @@ bridges without forcing it upstream. Note: this removes isolation between devices and may put more devices in an IOMMU group.+ disable_10bit_tag=<pci_dev>[; ...]+ Specify one or more PCI devices (in the format+ specified above) separated by semicolons.+ Disable 10-Bit Tag Requester if the peer+ device does not support the 10-Bit Tag+ Completer.This will make P2P traffic safe.
I can't imagine more awkward user experience than such kernel parameter.
As a user, I will need to boot the system, hope for the best that system
works, write down all PCI device numbers, guess which one doesn't work
properly, update grub with new command line argument and reboot the
system. Any HW change and this dance should be repeated.
There are already two such PCI parameters with this pattern and they are
not that awkward. pci_dev may be specified with either vendor/device IDS
or with a path of BDFs (which protects against renumbering).
This flag is only useful in P2PDMA traffic, and if the user attempts
such a transfer, it prints a warning (see the next patch) with the exact
parameter that needs to be added to the command line.
This has worked well for disable_acs_redir and was used for
resource_alignment before that for quite some time. So save a better
suggestion I think this is more than acceptable.
Logan
Add a 10-Bit Tag check in the P2PDMA code to ensure that a device with
10-Bit Tag Requester doesn't interact with a device that does not
support 10-BIT tag Completer. Before that happens, the kernel should
emit a warning saying to enable a ”pci=disable_10bit_tag=“ kernel
parameter.
Signed-off-by: Dongdong Liu <redacted>
---
drivers/pci/p2pdma.c | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
@@ -541,6 +542,39 @@ calc_map_type_and_dist(struct pci_dev *provider, struct pci_dev *client,returnmap_type;}++staticboolcheck_10bit_tags_vaild(structpci_dev*a,structpci_dev*b,+boolverbose)+{+boolreq;+boolcomp;+u16ctl2;++if(a->is_virtfn){+#ifdef CONFIG_PCI_IOV+req=!!(a->physfn->sriov->ctrl&+PCI_SRIOV_CTRL_VF_10BIT_TAG_REQ_EN);+#endif+}else{+pcie_capability_read_word(a,PCI_EXP_DEVCTL2,&ctl2);+req=!!(ctl2&PCI_EXP_DEVCTL2_10BIT_TAG_REQ_EN);+}++comp=!!(b->pcie_devcap2&PCI_EXP_DEVCAP2_10BIT_TAG_COMP);+if(req&&(!comp)){+if(verbose){+pci_warn(a,"cannot be used for peer-to-peer DMA as 10-Bit Tag Requester enable is set in device (%s), but peer device (%s) does not support the 10-Bit Tag Completer\n",+pci_name(a),pci_name(b));++pci_warn(a,"to disable 10-Bit Tag Requester for this device, add the kernel parameter: pci=disable_10bit_tag=%s\n",+pci_name(a));+}+returnfalse;+}++returntrue;+}+/***pci_p2pdma_distance_many-Determinethecumulativedistancebetween*ap2pdmaproviderandtheclientsinuse.
This check needs to be done in calc_map_type_and_dist(). The mapping
type needs to be correctly stored in the xarray cache as other functions
rely on the cached value (and upcoming work will be calling
calc_map_type_and_dist() without pci_p2pdma_distance_many()).
Logan
From: kernel test robot <hidden> Date: 2021-07-23 16:59:06
Hi Dongdong,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on pci/next]
[also build test WARNING on linuxtv-media/master linus/master v5.14-rc2 next-20210723]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Dongdong-Liu/PCI-Enable-10-Bit-tag-support-for-PCIe-devices/20210723-190930
base: https://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git next
config: x86_64-randconfig-b001-20210723 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 9625ca5b602616b2f5584e8a49ba93c52c141e40)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# https://github.com/0day-ci/linux/commit/2ff0b803971a3df5815c96c5c4874f4eef64fa2f
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Dongdong-Liu/PCI-Enable-10-Bit-tag-support-for-PCIe-devices/20210723-190930
git checkout 2ff0b803971a3df5815c96c5c4874f4eef64fa2f
# save the attached .config to linux build tree
mkdir build_dir
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/pci/
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <redacted>
All warnings (new ones prefixed by >>):
drivers/pci/pci.c:6618:34: error: expected identifier
pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2,
^
include/uapi/linux/pci_regs.h:657:26: note: expanded from macro 'PCI_EXP_DEVCTL2'
#define PCI_EXP_DEVCTL2 40 /* Device Control 2 */
^
quoted
drivers/pci/pci.c:6618:2: warning: declaration specifier missing, defaulting to 'int'
pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2,
^
int
drivers/pci/pci.c:6618:28: error: this function declaration is not a prototype [-Werror,-Wstrict-prototypes]
pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2,
^
drivers/pci/pci.c:6618:2: error: conflicting types for 'pcie_capability_clear_word'
pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2,
^
include/linux/pci.h:1161:19: note: previous definition is here
static inline int pcie_capability_clear_word(struct pci_dev *dev, int pos,
^
drivers/pci/pci.c:6621:2: error: expected parameter declarator
pci_info(dev, "disabled 10-Bit Tag Requester\n");
^
include/linux/pci.h:2472:46: note: expanded from macro 'pci_info'
#define pci_info(pdev, fmt, arg...) dev_info(&(pdev)->dev, fmt, ##arg)
^
drivers/pci/pci.c:6621:2: error: expected ')'
include/linux/pci.h:2472:46: note: expanded from macro 'pci_info'
#define pci_info(pdev, fmt, arg...) dev_info(&(pdev)->dev, fmt, ##arg)
^
drivers/pci/pci.c:6621:2: note: to match this '('
include/linux/pci.h:2472:37: note: expanded from macro 'pci_info'
#define pci_info(pdev, fmt, arg...) dev_info(&(pdev)->dev, fmt, ##arg)
^
include/linux/dev_printk.h:118:11: note: expanded from macro 'dev_info'
_dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__)
^
drivers/pci/pci.c:6621:2: warning: declaration specifier missing, defaulting to 'int'
pci_info(dev, "disabled 10-Bit Tag Requester\n");
^
int
include/linux/pci.h:2472:37: note: expanded from macro 'pci_info'
#define pci_info(pdev, fmt, arg...) dev_info(&(pdev)->dev, fmt, ##arg)
^
include/linux/dev_printk.h:118:2: note: expanded from macro 'dev_info'
_dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__)
^
drivers/pci/pci.c:6621:2: error: this function declaration is not a prototype [-Werror,-Wstrict-prototypes]
include/linux/pci.h:2472:37: note: expanded from macro 'pci_info'
#define pci_info(pdev, fmt, arg...) dev_info(&(pdev)->dev, fmt, ##arg)
^
include/linux/dev_printk.h:118:11: note: expanded from macro 'dev_info'
_dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__)
^
drivers/pci/pci.c:6621:2: error: conflicting types for '_dev_info'
include/linux/pci.h:2472:37: note: expanded from macro 'pci_info'
#define pci_info(pdev, fmt, arg...) dev_info(&(pdev)->dev, fmt, ##arg)
^
include/linux/dev_printk.h:118:2: note: expanded from macro 'dev_info'
_dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__)
^
include/linux/dev_printk.h:56:6: note: previous declaration is here
void _dev_info(const struct device *dev, const char *fmt, ...);
^
drivers/pci/pci.c:6622:1: error: extraneous closing brace ('}')
}
^
2 warnings and 8 errors generated.
vim +/int +6618 drivers/pci/pci.c
6580
6581 if (!disable_10bit_tag_param)
6582 return;
6583
6584 p = disable_10bit_tag_param;
6585 while (*p) {
6586 ret = pci_dev_str_match(dev, p, &p);
6587 if (ret < 0) {
6588 pr_info_once("PCI: Can't parse disable_10bit_tag parameter: %s\n",
6589 disable_10bit_tag_param);
6590
6591 break;
6592 } else if (ret == 1) {
6593 /* Found a match */
6594 break;
6595 }
6596
6597 if (*p != ';' && *p != ',') {
6598 /* End of param or invalid format */
6599 break;
6600 }
6601 p++;
6602 }
6603
6604 if (ret != 1)
6605 return;
6606
6607 #ifdef CONFIG_PCI_IOV
6608 if (dev->is_virtfn) {
6609 iov = dev->physfn->sriov;
6610 iov->ctrl &= ~PCI_SRIOV_CTRL_VF_10BIT_TAG_REQ_EN;
6611 pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL,
6612 iov->ctrl);
6613 pci_info(dev, "disabled PF SRIOV 10-Bit Tag Requester\n");
6614 return;
6615 #endif
6616 }
6617
From: Dongdong Liu <hidden> Date: 2021-07-24 10:35:14
On 2021/7/24 0:58, kernel test robot wrote:
Hi Dongdong,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on pci/next]
[also build test WARNING on linuxtv-media/master linus/master v5.14-rc2 next-20210723]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Dongdong-Liu/PCI-Enable-10-Bit-tag-support-for-PCIe-devices/20210723-190930
base: https://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git next
config: x86_64-randconfig-b001-20210723 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 9625ca5b602616b2f5584e8a49ba93c52c141e40)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# https://github.com/0day-ci/linux/commit/2ff0b803971a3df5815c96c5c4874f4eef64fa2f
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Dongdong-Liu/PCI-Enable-10-Bit-tag-support-for-PCIe-devices/20210723-190930
git checkout 2ff0b803971a3df5815c96c5c4874f4eef64fa2f
# save the attached .config to linux build tree
mkdir build_dir
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/pci/
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <redacted>
All warnings (new ones prefixed by >>):
drivers/pci/pci.c:6618:34: error: expected identifier
pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2,
^
include/uapi/linux/pci_regs.h:657:26: note: expanded from macro 'PCI_EXP_DEVCTL2'
#define PCI_EXP_DEVCTL2 40 /* Device Control 2 */
^
quoted
quoted
drivers/pci/pci.c:6618:2: warning: declaration specifier missing, defaulting to 'int'
pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2,
^
int
drivers/pci/pci.c:6618:28: error: this function declaration is not a prototype [-Werror,-Wstrict-prototypes]
pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2,
^
drivers/pci/pci.c:6618:2: error: conflicting types for 'pcie_capability_clear_word'
pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2,
^
include/linux/pci.h:1161:19: note: previous definition is here
static inline int pcie_capability_clear_word(struct pci_dev *dev, int pos,
^
drivers/pci/pci.c:6621:2: error: expected parameter declarator
pci_info(dev, "disabled 10-Bit Tag Requester\n");
^
include/linux/pci.h:2472:46: note: expanded from macro 'pci_info'
#define pci_info(pdev, fmt, arg...) dev_info(&(pdev)->dev, fmt, ##arg)
^
drivers/pci/pci.c:6621:2: error: expected ')'
include/linux/pci.h:2472:46: note: expanded from macro 'pci_info'
#define pci_info(pdev, fmt, arg...) dev_info(&(pdev)->dev, fmt, ##arg)
^
drivers/pci/pci.c:6621:2: note: to match this '('
include/linux/pci.h:2472:37: note: expanded from macro 'pci_info'
#define pci_info(pdev, fmt, arg...) dev_info(&(pdev)->dev, fmt, ##arg)
^
include/linux/dev_printk.h:118:11: note: expanded from macro 'dev_info'
_dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__)
^
drivers/pci/pci.c:6621:2: warning: declaration specifier missing, defaulting to 'int'
pci_info(dev, "disabled 10-Bit Tag Requester\n");
^
int
include/linux/pci.h:2472:37: note: expanded from macro 'pci_info'
#define pci_info(pdev, fmt, arg...) dev_info(&(pdev)->dev, fmt, ##arg)
^
include/linux/dev_printk.h:118:2: note: expanded from macro 'dev_info'
_dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__)
^
drivers/pci/pci.c:6621:2: error: this function declaration is not a prototype [-Werror,-Wstrict-prototypes]
include/linux/pci.h:2472:37: note: expanded from macro 'pci_info'
#define pci_info(pdev, fmt, arg...) dev_info(&(pdev)->dev, fmt, ##arg)
^
include/linux/dev_printk.h:118:11: note: expanded from macro 'dev_info'
_dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__)
^
drivers/pci/pci.c:6621:2: error: conflicting types for '_dev_info'
include/linux/pci.h:2472:37: note: expanded from macro 'pci_info'
#define pci_info(pdev, fmt, arg...) dev_info(&(pdev)->dev, fmt, ##arg)
^
include/linux/dev_printk.h:118:2: note: expanded from macro 'dev_info'
_dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__)
^
include/linux/dev_printk.h:56:6: note: previous declaration is here
void _dev_info(const struct device *dev, const char *fmt, ...);
^
drivers/pci/pci.c:6622:1: error: extraneous closing brace ('}')
}
^
2 warnings and 8 errors generated.
vim +/int +6618 drivers/pci/pci.c
6580
6581 if (!disable_10bit_tag_param)
6582 return;
6583
6584 p = disable_10bit_tag_param;
6585 while (*p) {
6586 ret = pci_dev_str_match(dev, p, &p);
6587 if (ret < 0) {
6588 pr_info_once("PCI: Can't parse disable_10bit_tag parameter: %s\n",
6589 disable_10bit_tag_param);
6590
6591 break;
6592 } else if (ret == 1) {
6593 /* Found a match */
6594 break;
6595 }
6596
6597 if (*p != ';' && *p != ',') {
6598 /* End of param or invalid format */
6599 break;
6600 }
6601 p++;
6602 }
6603
6604 if (ret != 1)
6605 return;
6606
6607 #ifdef CONFIG_PCI_IOV
6608 if (dev->is_virtfn) {
6609 iov = dev->physfn->sriov;
6610 iov->ctrl &= ~PCI_SRIOV_CTRL_VF_10BIT_TAG_REQ_EN;
6611 pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL,
6612 iov->ctrl);
6613 pci_info(dev, "disabled PF SRIOV 10-Bit Tag Requester\n");
6614 return;
6615 #endif
6616 }
From: Dongdong Liu <hidden> Date: 2021-07-24 10:36:13
Hi Logan
Many thanks for your review.
On 2021/7/24 0:25, Logan Gunthorpe wrote:
On 2021-07-23 5:06 a.m., Dongdong Liu wrote:
quoted
Add a 10-Bit Tag check in the P2PDMA code to ensure that a device with
10-Bit Tag Requester doesn't interact with a device that does not
support 10-BIT tag Completer. Before that happens, the kernel should
emit a warning saying to enable a ”pci=disable_10bit_tag=“ kernel
parameter.
Signed-off-by: Dongdong Liu <redacted>
---
drivers/pci/p2pdma.c | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
@@ -541,6 +542,39 @@ calc_map_type_and_dist(struct pci_dev *provider, struct pci_dev *client,returnmap_type;}++staticboolcheck_10bit_tags_vaild(structpci_dev*a,structpci_dev*b,+boolverbose)+{+boolreq;+boolcomp;+u16ctl2;++if(a->is_virtfn){+#ifdef CONFIG_PCI_IOV+req=!!(a->physfn->sriov->ctrl&+PCI_SRIOV_CTRL_VF_10BIT_TAG_REQ_EN);+#endif+}else{+pcie_capability_read_word(a,PCI_EXP_DEVCTL2,&ctl2);+req=!!(ctl2&PCI_EXP_DEVCTL2_10BIT_TAG_REQ_EN);+}++comp=!!(b->pcie_devcap2&PCI_EXP_DEVCAP2_10BIT_TAG_COMP);+if(req&&(!comp)){+if(verbose){+pci_warn(a,"cannot be used for peer-to-peer DMA as 10-Bit Tag Requester enable is set in device (%s), but peer device (%s) does not support the 10-Bit Tag Completer\n",+pci_name(a),pci_name(b));++pci_warn(a,"to disable 10-Bit Tag Requester for this device, add the kernel parameter: pci=disable_10bit_tag=%s\n",+pci_name(a));+}+returnfalse;+}++returntrue;+}+/***pci_p2pdma_distance_many-Determinethecumulativedistancebetween*ap2pdmaproviderandtheclientsinuse.
This check needs to be done in calc_map_type_and_dist(). The mapping
type needs to be correctly stored in the xarray cache as other functions
rely on the cached value (and upcoming work will be calling
calc_map_type_and_dist() without pci_p2pdma_distance_many()).
From: Leon Romanovsky <leon@kernel.org> Date: 2021-07-25 06:40:00
On Fri, Jul 23, 2021 at 10:20:50AM -0600, Logan Gunthorpe wrote:
On 2021-07-23 5:32 a.m., Leon Romanovsky wrote:
quoted
On Fri, Jul 23, 2021 at 07:06:41PM +0800, Dongdong Liu wrote:
quoted
PCIe spec 5.0 r1.0 section 2.2.6.2 says that if an Endpoint supports
sending Requests to other Endpoints (as opposed to host memory), the
Endpoint must not send 10-Bit Tag Requests to another given Endpoint
unless an implementation-specific mechanism determines that the Endpoint
supports 10-Bit Tag Completer capability. Add "pci=disable_10bit_tag="
parameter to disable 10-Bit Tag Requester if the peer device does not
support the 10-Bit Tag Completer. This will make P2P traffic safe.
Signed-off-by: Dongdong Liu <redacted>
---
Documentation/admin-guide/kernel-parameters.txt | 7 ++++
drivers/pci/pci.c | 56 +++++++++++++++++++++++++
drivers/pci/pci.h | 1 +
drivers/pci/pcie/portdrv_pci.c | 13 +++---
drivers/pci/probe.c | 9 ++--
5 files changed, 78 insertions(+), 8 deletions(-)
@@ -4019,6 +4019,13 @@ bridges without forcing it upstream. Note: this removes isolation between devices and may put more devices in an IOMMU group.+ disable_10bit_tag=<pci_dev>[; ...]+ Specify one or more PCI devices (in the format+ specified above) separated by semicolons.+ Disable 10-Bit Tag Requester if the peer+ device does not support the 10-Bit Tag+ Completer.This will make P2P traffic safe.
I can't imagine more awkward user experience than such kernel parameter.
As a user, I will need to boot the system, hope for the best that system
works, write down all PCI device numbers, guess which one doesn't work
properly, update grub with new command line argument and reboot the
system. Any HW change and this dance should be repeated.
There are already two such PCI parameters with this pattern and they are
not that awkward. pci_dev may be specified with either vendor/device IDS
or with a path of BDFs (which protects against renumbering).
Unfortunately, in the real world, BDF is not so stable. It changes with
addition of new hardware, BIOS upgrades and even broken servers.
Vendor/device IDs doesn't work if you have multiple devices of same
vendor in the system.
This flag is only useful in P2PDMA traffic, and if the user attempts
such a transfer, it prints a warning (see the next patch) with the exact
parameter that needs to be added to the command line.
Dongdong citied PCI spec and it was very clear - don't enable this
feature unless you clearly know that it is safe to enable. This is
completely opposite to the proposal here - always enable and disable
if something is printed to the dmesg.
This has worked well for disable_acs_redir and was used for
resource_alignment before that for quite some time. So save a better
suggestion I think this is more than acceptable.
I don't know about other parameters and their history, but we are not in
90s anymore and addition of modules parameters (for the PCI it is kernel
cmdline arguments) are better to be changed to some configuration tool/sysfs.
Even FW upgrade with such kernel parameter can be problematic.
Thanks
On Fri, Jul 23, 2021 at 10:20:50AM -0600, Logan Gunthorpe wrote:
quoted
On 2021-07-23 5:32 a.m., Leon Romanovsky wrote:
quoted
On Fri, Jul 23, 2021 at 07:06:41PM +0800, Dongdong Liu wrote:
quoted
PCIe spec 5.0 r1.0 section 2.2.6.2 says that if an Endpoint supports
sending Requests to other Endpoints (as opposed to host memory), the
Endpoint must not send 10-Bit Tag Requests to another given Endpoint
unless an implementation-specific mechanism determines that the Endpoint
supports 10-Bit Tag Completer capability. Add "pci=disable_10bit_tag="
parameter to disable 10-Bit Tag Requester if the peer device does not
support the 10-Bit Tag Completer. This will make P2P traffic safe.
Signed-off-by: Dongdong Liu <redacted>
---
Documentation/admin-guide/kernel-parameters.txt | 7 ++++
drivers/pci/pci.c | 56 +++++++++++++++++++++++++
drivers/pci/pci.h | 1 +
drivers/pci/pcie/portdrv_pci.c | 13 +++---
drivers/pci/probe.c | 9 ++--
5 files changed, 78 insertions(+), 8 deletions(-)
@@ -4019,6 +4019,13 @@ bridges without forcing it upstream. Note: this removes isolation between devices and may put more devices in an IOMMU group.+ disable_10bit_tag=<pci_dev>[; ...]+ Specify one or more PCI devices (in the format+ specified above) separated by semicolons.+ Disable 10-Bit Tag Requester if the peer+ device does not support the 10-Bit Tag+ Completer.This will make P2P traffic safe.
I can't imagine more awkward user experience than such kernel parameter.
As a user, I will need to boot the system, hope for the best that system
works, write down all PCI device numbers, guess which one doesn't work
properly, update grub with new command line argument and reboot the
system. Any HW change and this dance should be repeated.
There are already two such PCI parameters with this pattern and they are
not that awkward. pci_dev may be specified with either vendor/device IDS
or with a path of BDFs (which protects against renumbering).
Unfortunately, in the real world, BDF is not so stable. It changes with
addition of new hardware, BIOS upgrades and even broken servers.
That's why it supports using a *path* of BDFs which tends not to catch
the wrong device if the topology changes.
Vendor/device IDs doesn't work if you have multiple devices of same
vendor in the system.
Yes, but it's fine for some use cases. That's why there's a range of
options.
quoted
This flag is only useful in P2PDMA traffic, and if the user attempts
such a transfer, it prints a warning (see the next patch) with the exact
parameter that needs to be added to the command line.
Dongdong citied PCI spec and it was very clear - don't enable this
feature unless you clearly know that it is safe to enable. This is
completely opposite to the proposal here - always enable and disable
if something is printed to the dmesg.
Quoting from patch 4:
"For platforms where the RC supports 10-Bit Tag Completer capability,
it is highly recommended for platform firmware or operating software
that configures PCIe hierarchies to Set the 10-Bit Tag Requester Enable
bit automatically in Endpoints with 10-Bit Tag Requester capability.
This enables the important class of 10-Bit Tag capable adapters that
send Memory Read Requests only to host memory."
Notice the last sentence. It's saying that devices who only talk to host
memory should have 10-bit tags enabled. In the kernel we call devices
that talk to things besides host memory "P2PDMA". So the spec is saying
not to enable 10bit tags for devices participating in P2PDMA. The kernel
needs a way to allow users to do that. The kernel parameter only stops
the feature from being enabled for a specific device, and the only
use-case is P2PDMA which is not that common and requires the user to be
aware of their topology. So I really don't think this is that big a problem.
quoted
This has worked well for disable_acs_redir and was used for
resource_alignment before that for quite some time. So save a better
suggestion I think this is more than acceptable.
I don't know about other parameters and their history, but we are not in
90s anymore and addition of modules parameters (for the PCI it is kernel
cmdline arguments) are better to be changed to some configuration tool/sysfs.
The problem was that the ACS bits had to be set before the kernel
enumerated the devices. The IOMMU code simply was not able to support
dynamic adjustments to its groups. I assume changing 10bit tags
dynamically is similarly tricky -- but if it's not then, yes a sysfs
interface in addition to the kernel parameter would be a good idea.
Logan
From: Leon Romanovsky <leon@kernel.org> Date: 2021-07-27 11:05:07
On Mon, Jul 26, 2021 at 09:48:57AM -0600, Logan Gunthorpe wrote:
On 2021-07-25 12:39 a.m., Leon Romanovsky wrote:
quoted
On Fri, Jul 23, 2021 at 10:20:50AM -0600, Logan Gunthorpe wrote:
quoted
On 2021-07-23 5:32 a.m., Leon Romanovsky wrote:
quoted
On Fri, Jul 23, 2021 at 07:06:41PM +0800, Dongdong Liu wrote:
quoted
PCIe spec 5.0 r1.0 section 2.2.6.2 says that if an Endpoint supports
sending Requests to other Endpoints (as opposed to host memory), the
Endpoint must not send 10-Bit Tag Requests to another given Endpoint
unless an implementation-specific mechanism determines that the Endpoint
supports 10-Bit Tag Completer capability. Add "pci=disable_10bit_tag="
parameter to disable 10-Bit Tag Requester if the peer device does not
support the 10-Bit Tag Completer. This will make P2P traffic safe.
Signed-off-by: Dongdong Liu <redacted>
---
Documentation/admin-guide/kernel-parameters.txt | 7 ++++
drivers/pci/pci.c | 56 +++++++++++++++++++++++++
drivers/pci/pci.h | 1 +
drivers/pci/pcie/portdrv_pci.c | 13 +++---
drivers/pci/probe.c | 9 ++--
5 files changed, 78 insertions(+), 8 deletions(-)
@@ -4019,6 +4019,13 @@ bridges without forcing it upstream. Note: this removes isolation between devices and may put more devices in an IOMMU group.+ disable_10bit_tag=<pci_dev>[; ...]+ Specify one or more PCI devices (in the format+ specified above) separated by semicolons.+ Disable 10-Bit Tag Requester if the peer+ device does not support the 10-Bit Tag+ Completer.This will make P2P traffic safe.
I can't imagine more awkward user experience than such kernel parameter.
As a user, I will need to boot the system, hope for the best that system
works, write down all PCI device numbers, guess which one doesn't work
properly, update grub with new command line argument and reboot the
system. Any HW change and this dance should be repeated.
There are already two such PCI parameters with this pattern and they are
not that awkward. pci_dev may be specified with either vendor/device IDS
or with a path of BDFs (which protects against renumbering).
Unfortunately, in the real world, BDF is not so stable. It changes with
addition of new hardware, BIOS upgrades and even broken servers.
That's why it supports using a *path* of BDFs which tends not to catch
the wrong device if the topology changes.
quoted
Vendor/device IDs doesn't work if you have multiple devices of same
vendor in the system.
Yes, but it's fine for some use cases. That's why there's a range of
options.
The thing is that you are adding PCI parameter that is applicable to everyone.
We probably see different usage models for this feature. In my world, users
have thousands of servers that runs 24x7, with VMs on top, some of them perform
FW upgrades without stopping anything. The idea that you can reboot such server
any time, simply doesn't exist.
So if I need to enable/disable this feature for one of the VFs, I will be stuck.
quoted
quoted
This flag is only useful in P2PDMA traffic, and if the user attempts
such a transfer, it prints a warning (see the next patch) with the exact
parameter that needs to be added to the command line.
Dongdong citied PCI spec and it was very clear - don't enable this
feature unless you clearly know that it is safe to enable. This is
completely opposite to the proposal here - always enable and disable
if something is printed to the dmesg.
Quoting from patch 4:
"For platforms where the RC supports 10-Bit Tag Completer capability,
it is highly recommended for platform firmware or operating software
that configures PCIe hierarchies to Set the 10-Bit Tag Requester Enable
bit automatically in Endpoints with 10-Bit Tag Requester capability.
This enables the important class of 10-Bit Tag capable adapters that
send Memory Read Requests only to host memory."
Notice the last sentence. It's saying that devices who only talk to host
memory should have 10-bit tags enabled. In the kernel we call devices
that talk to things besides host memory "P2PDMA". So the spec is saying
not to enable 10bit tags for devices participating in P2PDMA. The kernel
needs a way to allow users to do that. The kernel parameter only stops
the feature from being enabled for a specific device, and the only
use-case is P2PDMA which is not that common and requires the user to be
aware of their topology. So I really don't think this is that big a problem.
I'm not question the feature and the need of configuration. My concern
is just *how* this feature is configured.
quoted
quoted
This has worked well for disable_acs_redir and was used for
resource_alignment before that for quite some time. So save a better
suggestion I think this is more than acceptable.
I don't know about other parameters and their history, but we are not in
90s anymore and addition of modules parameters (for the PCI it is kernel
cmdline arguments) are better to be changed to some configuration tool/sysfs.
The problem was that the ACS bits had to be set before the kernel
enumerated the devices. The IOMMU code simply was not able to support
dynamic adjustments to its groups. I assume changing 10bit tags
dynamically is similarly tricky -- but if it's not then, yes a sysfs
interface in addition to the kernel parameter would be a good idea.
I think that it is doable with combination of drivers_autoprobe disable
and some sysfs knob to enable/disable this feature before driver bind.
It should be very similar to that we did for the dynamic MSI-X, see
/sys/bus/pci/devices/.../sriov_vf_msix_count
Thanks
From: Dongdong Liu <hidden> Date: 2021-07-27 14:00:44
On 2021/7/26 23:48, Logan Gunthorpe wrote:
On 2021-07-25 12:39 a.m., Leon Romanovsky wrote:
quoted
On Fri, Jul 23, 2021 at 10:20:50AM -0600, Logan Gunthorpe wrote:
quoted
On 2021-07-23 5:32 a.m., Leon Romanovsky wrote:
quoted
On Fri, Jul 23, 2021 at 07:06:41PM +0800, Dongdong Liu wrote:
quoted
PCIe spec 5.0 r1.0 section 2.2.6.2 says that if an Endpoint supports
sending Requests to other Endpoints (as opposed to host memory), the
Endpoint must not send 10-Bit Tag Requests to another given Endpoint
unless an implementation-specific mechanism determines that the Endpoint
supports 10-Bit Tag Completer capability. Add "pci=disable_10bit_tag="
parameter to disable 10-Bit Tag Requester if the peer device does not
support the 10-Bit Tag Completer. This will make P2P traffic safe.
Signed-off-by: Dongdong Liu <redacted>
---
Documentation/admin-guide/kernel-parameters.txt | 7 ++++
drivers/pci/pci.c | 56 +++++++++++++++++++++++++
drivers/pci/pci.h | 1 +
drivers/pci/pcie/portdrv_pci.c | 13 +++---
drivers/pci/probe.c | 9 ++--
5 files changed, 78 insertions(+), 8 deletions(-)
@@ -4019,6 +4019,13 @@ bridges without forcing it upstream. Note: this removes isolation between devices and may put more devices in an IOMMU group.+ disable_10bit_tag=<pci_dev>[; ...]+ Specify one or more PCI devices (in the format+ specified above) separated by semicolons.+ Disable 10-Bit Tag Requester if the peer+ device does not support the 10-Bit Tag+ Completer.This will make P2P traffic safe.
I can't imagine more awkward user experience than such kernel parameter.
As a user, I will need to boot the system, hope for the best that system
works, write down all PCI device numbers, guess which one doesn't work
properly, update grub with new command line argument and reboot the
system. Any HW change and this dance should be repeated.
There are already two such PCI parameters with this pattern and they are
not that awkward. pci_dev may be specified with either vendor/device IDS
or with a path of BDFs (which protects against renumbering).
Unfortunately, in the real world, BDF is not so stable. It changes with
addition of new hardware, BIOS upgrades and even broken servers.
That's why it supports using a *path* of BDFs which tends not to catch
the wrong device if the topology changes.
quoted
Vendor/device IDs doesn't work if you have multiple devices of same
vendor in the system.
Yes, but it's fine for some use cases. That's why there's a range of
options.
quoted
quoted
This flag is only useful in P2PDMA traffic, and if the user attempts
such a transfer, it prints a warning (see the next patch) with the exact
parameter that needs to be added to the command line.
Dongdong citied PCI spec and it was very clear - don't enable this
feature unless you clearly know that it is safe to enable. This is
completely opposite to the proposal here - always enable and disable
if something is printed to the dmesg.
Quoting from patch 4:
"For platforms where the RC supports 10-Bit Tag Completer capability,
it is highly recommended for platform firmware or operating software
that configures PCIe hierarchies to Set the 10-Bit Tag Requester Enable
bit automatically in Endpoints with 10-Bit Tag Requester capability.
This enables the important class of 10-Bit Tag capable adapters that
send Memory Read Requests only to host memory."
Notice the last sentence. It's saying that devices who only talk to host
memory should have 10-bit tags enabled. In the kernel we call devices
that talk to things besides host memory "P2PDMA". So the spec is saying
not to enable 10bit tags for devices participating in P2PDMA. The kernel
needs a way to allow users to do that. The kernel parameter only stops
the feature from being enabled for a specific device, and the only
use-case is P2PDMA which is not that common and requires the user to be
aware of their topology. So I really don't think this is that big a problem.
quoted
quoted
This has worked well for disable_acs_redir and was used for
resource_alignment before that for quite some time. So save a better
suggestion I think this is more than acceptable.
I don't know about other parameters and their history, but we are not in
90s anymore and addition of modules parameters (for the PCI it is kernel
cmdline arguments) are better to be changed to some configuration tool/sysfs.
The problem was that the ACS bits had to be set before the kernel
enumerated the devices. The IOMMU code simply was not able to support
dynamic adjustments to its groups. I assume changing 10bit tags
dynamically is similarly tricky -- but if it's not then, yes a sysfs
interface in addition to the kernel parameter would be a good idea.
PCIe spec 5.0 section 7.5.3.16 Device Control 2 Register
10-Bit Tag Requester Enable says that
If software changes the value of this bit while the Function
has outstanding Non-Posted Requests, the result is undefined.
So 10-Bit Tag Requester Enable should be set before probe the device
driver.
Thanks,
Dongdong
From: Dongdong Liu <hidden> Date: 2021-07-27 14:30:46
On 2021/7/27 19:05, Leon Romanovsky wrote:
On Mon, Jul 26, 2021 at 09:48:57AM -0600, Logan Gunthorpe wrote:
quoted
On 2021-07-25 12:39 a.m., Leon Romanovsky wrote:
quoted
On Fri, Jul 23, 2021 at 10:20:50AM -0600, Logan Gunthorpe wrote:
quoted
On 2021-07-23 5:32 a.m., Leon Romanovsky wrote:
quoted
On Fri, Jul 23, 2021 at 07:06:41PM +0800, Dongdong Liu wrote:
quoted
PCIe spec 5.0 r1.0 section 2.2.6.2 says that if an Endpoint supports
sending Requests to other Endpoints (as opposed to host memory), the
Endpoint must not send 10-Bit Tag Requests to another given Endpoint
unless an implementation-specific mechanism determines that the Endpoint
supports 10-Bit Tag Completer capability. Add "pci=disable_10bit_tag="
parameter to disable 10-Bit Tag Requester if the peer device does not
support the 10-Bit Tag Completer. This will make P2P traffic safe.
Signed-off-by: Dongdong Liu <redacted>
---
Documentation/admin-guide/kernel-parameters.txt | 7 ++++
drivers/pci/pci.c | 56 +++++++++++++++++++++++++
drivers/pci/pci.h | 1 +
drivers/pci/pcie/portdrv_pci.c | 13 +++---
drivers/pci/probe.c | 9 ++--
5 files changed, 78 insertions(+), 8 deletions(-)
@@ -4019,6 +4019,13 @@ bridges without forcing it upstream. Note: this removes isolation between devices and may put more devices in an IOMMU group.+ disable_10bit_tag=<pci_dev>[; ...]+ Specify one or more PCI devices (in the format+ specified above) separated by semicolons.+ Disable 10-Bit Tag Requester if the peer+ device does not support the 10-Bit Tag+ Completer.This will make P2P traffic safe.
I can't imagine more awkward user experience than such kernel parameter.
As a user, I will need to boot the system, hope for the best that system
works, write down all PCI device numbers, guess which one doesn't work
properly, update grub with new command line argument and reboot the
system. Any HW change and this dance should be repeated.
There are already two such PCI parameters with this pattern and they are
not that awkward. pci_dev may be specified with either vendor/device IDS
or with a path of BDFs (which protects against renumbering).
Unfortunately, in the real world, BDF is not so stable. It changes with
addition of new hardware, BIOS upgrades and even broken servers.
That's why it supports using a *path* of BDFs which tends not to catch
the wrong device if the topology changes.
quoted
Vendor/device IDs doesn't work if you have multiple devices of same
vendor in the system.
Yes, but it's fine for some use cases. That's why there's a range of
options.
The thing is that you are adding PCI parameter that is applicable to everyone.
We probably see different usage models for this feature. In my world, users
have thousands of servers that runs 24x7, with VMs on top, some of them perform
FW upgrades without stopping anything. The idea that you can reboot such server
any time, simply doesn't exist.
So if I need to enable/disable this feature for one of the VFs, I will be stuck.
quoted
quoted
quoted
This flag is only useful in P2PDMA traffic, and if the user attempts
such a transfer, it prints a warning (see the next patch) with the exact
parameter that needs to be added to the command line.
Dongdong citied PCI spec and it was very clear - don't enable this
feature unless you clearly know that it is safe to enable. This is
completely opposite to the proposal here - always enable and disable
if something is printed to the dmesg.
Quoting from patch 4:
"For platforms where the RC supports 10-Bit Tag Completer capability,
it is highly recommended for platform firmware or operating software
that configures PCIe hierarchies to Set the 10-Bit Tag Requester Enable
bit automatically in Endpoints with 10-Bit Tag Requester capability.
This enables the important class of 10-Bit Tag capable adapters that
send Memory Read Requests only to host memory."
Notice the last sentence. It's saying that devices who only talk to host
memory should have 10-bit tags enabled. In the kernel we call devices
that talk to things besides host memory "P2PDMA". So the spec is saying
not to enable 10bit tags for devices participating in P2PDMA. The kernel
needs a way to allow users to do that. The kernel parameter only stops
the feature from being enabled for a specific device, and the only
use-case is P2PDMA which is not that common and requires the user to be
aware of their topology. So I really don't think this is that big a problem.
I'm not question the feature and the need of configuration. My concern
is just *how* this feature is configured.
quoted
quoted
quoted
This has worked well for disable_acs_redir and was used for
resource_alignment before that for quite some time. So save a better
suggestion I think this is more than acceptable.
I don't know about other parameters and their history, but we are not in
90s anymore and addition of modules parameters (for the PCI it is kernel
cmdline arguments) are better to be changed to some configuration tool/sysfs.
The problem was that the ACS bits had to be set before the kernel
enumerated the devices. The IOMMU code simply was not able to support
dynamic adjustments to its groups. I assume changing 10bit tags
dynamically is similarly tricky -- but if it's not then, yes a sysfs
interface in addition to the kernel parameter would be a good idea.
I think that it is doable with combination of drivers_autoprobe disable
and some sysfs knob to enable/disable this feature before driver bind.
It should be very similar to that we did for the dynamic MSI-X, see
/sys/bus/pci/devices/.../sriov_vf_msix_count
Many thanks for your suggestion.
Seems a sysfs could be work ok, but need to make sure 10-Bit Tag
Requester to be set before binding the device driver as
PCIe spec 5.0 section 7.5.3.16 Device Control 2 Register
10-Bit Tag Requester Enable says that
If software changes the value of this bit while the Function
has outstanding Non-Posted Requests, the result is undefined.
Thanks,
Dongdong
From: Leon Romanovsky <leon@kernel.org> Date: 2021-07-27 15:41:31
On Tue, Jul 27, 2021 at 10:30:40PM +0800, Dongdong Liu wrote:
On 2021/7/27 19:05, Leon Romanovsky wrote:
quoted
On Mon, Jul 26, 2021 at 09:48:57AM -0600, Logan Gunthorpe wrote:
quoted
On 2021-07-25 12:39 a.m., Leon Romanovsky wrote:
quoted
On Fri, Jul 23, 2021 at 10:20:50AM -0600, Logan Gunthorpe wrote:
quoted
On 2021-07-23 5:32 a.m., Leon Romanovsky wrote:
quoted
On Fri, Jul 23, 2021 at 07:06:41PM +0800, Dongdong Liu wrote:
quoted
PCIe spec 5.0 r1.0 section 2.2.6.2 says that if an Endpoint supports
sending Requests to other Endpoints (as opposed to host memory), the
Endpoint must not send 10-Bit Tag Requests to another given Endpoint
unless an implementation-specific mechanism determines that the Endpoint
supports 10-Bit Tag Completer capability. Add "pci=disable_10bit_tag="
parameter to disable 10-Bit Tag Requester if the peer device does not
support the 10-Bit Tag Completer. This will make P2P traffic safe.
Signed-off-by: Dongdong Liu <redacted>
---
Documentation/admin-guide/kernel-parameters.txt | 7 ++++
drivers/pci/pci.c | 56 +++++++++++++++++++++++++
drivers/pci/pci.h | 1 +
drivers/pci/pcie/portdrv_pci.c | 13 +++---
drivers/pci/probe.c | 9 ++--
5 files changed, 78 insertions(+), 8 deletions(-)
@@ -4019,6 +4019,13 @@ bridges without forcing it upstream. Note: this removes isolation between devices and may put more devices in an IOMMU group.+ disable_10bit_tag=<pci_dev>[; ...]+ Specify one or more PCI devices (in the format+ specified above) separated by semicolons.+ Disable 10-Bit Tag Requester if the peer+ device does not support the 10-Bit Tag+ Completer.This will make P2P traffic safe.
I can't imagine more awkward user experience than such kernel parameter.
As a user, I will need to boot the system, hope for the best that system
works, write down all PCI device numbers, guess which one doesn't work
properly, update grub with new command line argument and reboot the
system. Any HW change and this dance should be repeated.
There are already two such PCI parameters with this pattern and they are
not that awkward. pci_dev may be specified with either vendor/device IDS
or with a path of BDFs (which protects against renumbering).
Unfortunately, in the real world, BDF is not so stable. It changes with
addition of new hardware, BIOS upgrades and even broken servers.
That's why it supports using a *path* of BDFs which tends not to catch
the wrong device if the topology changes.
quoted
Vendor/device IDs doesn't work if you have multiple devices of same
vendor in the system.
Yes, but it's fine for some use cases. That's why there's a range of
options.
The thing is that you are adding PCI parameter that is applicable to everyone.
We probably see different usage models for this feature. In my world, users
have thousands of servers that runs 24x7, with VMs on top, some of them perform
FW upgrades without stopping anything. The idea that you can reboot such server
any time, simply doesn't exist.
So if I need to enable/disable this feature for one of the VFs, I will be stuck.
quoted
quoted
quoted
This flag is only useful in P2PDMA traffic, and if the user attempts
such a transfer, it prints a warning (see the next patch) with the exact
parameter that needs to be added to the command line.
Dongdong citied PCI spec and it was very clear - don't enable this
feature unless you clearly know that it is safe to enable. This is
completely opposite to the proposal here - always enable and disable
if something is printed to the dmesg.
Quoting from patch 4:
"For platforms where the RC supports 10-Bit Tag Completer capability,
it is highly recommended for platform firmware or operating software
that configures PCIe hierarchies to Set the 10-Bit Tag Requester Enable
bit automatically in Endpoints with 10-Bit Tag Requester capability.
This enables the important class of 10-Bit Tag capable adapters that
send Memory Read Requests only to host memory."
Notice the last sentence. It's saying that devices who only talk to host
memory should have 10-bit tags enabled. In the kernel we call devices
that talk to things besides host memory "P2PDMA". So the spec is saying
not to enable 10bit tags for devices participating in P2PDMA. The kernel
needs a way to allow users to do that. The kernel parameter only stops
the feature from being enabled for a specific device, and the only
use-case is P2PDMA which is not that common and requires the user to be
aware of their topology. So I really don't think this is that big a problem.
I'm not question the feature and the need of configuration. My concern
is just *how* this feature is configured.
quoted
quoted
quoted
This has worked well for disable_acs_redir and was used for
resource_alignment before that for quite some time. So save a better
suggestion I think this is more than acceptable.
I don't know about other parameters and their history, but we are not in
90s anymore and addition of modules parameters (for the PCI it is kernel
cmdline arguments) are better to be changed to some configuration tool/sysfs.
The problem was that the ACS bits had to be set before the kernel
enumerated the devices. The IOMMU code simply was not able to support
dynamic adjustments to its groups. I assume changing 10bit tags
dynamically is similarly tricky -- but if it's not then, yes a sysfs
interface in addition to the kernel parameter would be a good idea.
I think that it is doable with combination of drivers_autoprobe disable
and some sysfs knob to enable/disable this feature before driver bind.
It should be very similar to that we did for the dynamic MSI-X, see
/sys/bus/pci/devices/.../sriov_vf_msix_count
Many thanks for your suggestion.
Seems a sysfs could be work ok, but need to make sure 10-Bit Tag Requester
to be set before binding the device driver as
PCIe spec 5.0 section 7.5.3.16 Device Control 2 Register
10-Bit Tag Requester Enable says that
If software changes the value of this bit while the Function
has outstanding Non-Posted Requests, the result is undefined.