* [PATCH v3 1/6] powerpc/powernv: don't enable SRIOV when VF BAR has non 64bit-prefetchable BAR
2015-08-13 14:11 [PATCH v3 0/6] Redesign SR-IOV on PowerNV Wei Yang
@ 2015-08-13 14:11 ` Wei Yang
2015-08-14 0:30 ` Gavin Shan
2015-08-13 14:11 ` [PATCH v3 2/6] powerpc/powernv: simplify the calculation of iov resource alignment Wei Yang
` (4 subsequent siblings)
5 siblings, 1 reply; 22+ messages in thread
From: Wei Yang @ 2015-08-13 14:11 UTC (permalink / raw)
To: aik, gwshan, benh; +Cc: linuxppc-dev, Wei Yang
On PHB_IODA2, we enable SRIOV devices by mapping IOV BAR with M64 BARs. If
a SRIOV device's IOV BAR is not 64bit-prefetchable, this is not assigned
from 64bit prefetchable window, which means M64 BAR can't work on it.
This patch makes this explicit.
Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
---
arch/powerpc/platforms/powernv/pci-ioda.c | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 5738d31..9ac324e 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -908,9 +908,6 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset)
if (!res->flags || !res->parent)
continue;
- if (!pnv_pci_is_mem_pref_64(res->flags))
- continue;
-
/*
* The actual IOV BAR range is determined by the start address
* and the actual size for num_vfs VFs BAR. This check is to
@@ -939,9 +936,6 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset)
if (!res->flags || !res->parent)
continue;
- if (!pnv_pci_is_mem_pref_64(res->flags))
- continue;
-
size = pci_iov_resource_size(dev, i + PCI_IOV_RESOURCES);
res2 = *res;
res->start += size * offset;
@@ -1221,9 +1215,6 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
if (!res->flags || !res->parent)
continue;
- if (!pnv_pci_is_mem_pref_64(res->flags))
- continue;
-
for (j = 0; j < vf_groups; j++) {
do {
win = find_next_zero_bit(&phb->ioda.m64_bar_alloc,
@@ -1510,6 +1501,12 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
pdn = pci_get_pdn(pdev);
if (phb->type == PNV_PHB_IODA2) {
+ if (!pdn->vfs_expanded) {
+ dev_info(&pdev->dev, "don't support this SRIOV device"
+ " with non 64bit-prefetchable IOV BAR\n");
+ return -ENOSPC;
+ }
+
/* Calculate available PE for required VFs */
mutex_lock(&phb->ioda.pe_alloc_mutex);
pdn->offset = bitmap_find_next_zero_area(
@@ -2774,9 +2771,10 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
if (!res->flags || res->parent)
continue;
if (!pnv_pci_is_mem_pref_64(res->flags)) {
- dev_warn(&pdev->dev, " non M64 VF BAR%d: %pR\n",
+ dev_warn(&pdev->dev, "Don't support SR-IOV with"
+ " non M64 VF BAR%d: %pR. \n",
i, res);
- continue;
+ return;
}
size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
@@ -2795,11 +2793,6 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
res = &pdev->resource[i + PCI_IOV_RESOURCES];
if (!res->flags || res->parent)
continue;
- if (!pnv_pci_is_mem_pref_64(res->flags)) {
- dev_warn(&pdev->dev, "Skipping expanding VF BAR%d: %pR\n",
- i, res);
- continue;
- }
dev_dbg(&pdev->dev, " Fixing VF BAR%d: %pR to\n", i, res);
size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v3 1/6] powerpc/powernv: don't enable SRIOV when VF BAR has non 64bit-prefetchable BAR
2015-08-13 14:11 ` [PATCH v3 1/6] powerpc/powernv: don't enable SRIOV when VF BAR has non 64bit-prefetchable BAR Wei Yang
@ 2015-08-14 0:30 ` Gavin Shan
0 siblings, 0 replies; 22+ messages in thread
From: Gavin Shan @ 2015-08-14 0:30 UTC (permalink / raw)
To: Wei Yang; +Cc: aik, gwshan, benh, linuxppc-dev
On Thu, Aug 13, 2015 at 10:11:06PM +0800, Wei Yang wrote:
>On PHB_IODA2, we enable SRIOV devices by mapping IOV BAR with M64 BARs. If
>a SRIOV device's IOV BAR is not 64bit-prefetchable, this is not assigned
>from 64bit prefetchable window, which means M64 BAR can't work on it.
>
>This patch makes this explicit.
>
>Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
Reviewed-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
>---
> arch/powerpc/platforms/powernv/pci-ioda.c | 25 +++++++++----------------
> 1 file changed, 9 insertions(+), 16 deletions(-)
>
>diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
>index 5738d31..9ac324e 100644
>--- a/arch/powerpc/platforms/powernv/pci-ioda.c
>+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
>@@ -908,9 +908,6 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset)
> if (!res->flags || !res->parent)
> continue;
>
>- if (!pnv_pci_is_mem_pref_64(res->flags))
>- continue;
>-
> /*
> * The actual IOV BAR range is determined by the start address
> * and the actual size for num_vfs VFs BAR. This check is to
>@@ -939,9 +936,6 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset)
> if (!res->flags || !res->parent)
> continue;
>
>- if (!pnv_pci_is_mem_pref_64(res->flags))
>- continue;
>-
> size = pci_iov_resource_size(dev, i + PCI_IOV_RESOURCES);
> res2 = *res;
> res->start += size * offset;
>@@ -1221,9 +1215,6 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
> if (!res->flags || !res->parent)
> continue;
>
>- if (!pnv_pci_is_mem_pref_64(res->flags))
>- continue;
>-
> for (j = 0; j < vf_groups; j++) {
> do {
> win = find_next_zero_bit(&phb->ioda.m64_bar_alloc,
>@@ -1510,6 +1501,12 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
> pdn = pci_get_pdn(pdev);
>
> if (phb->type == PNV_PHB_IODA2) {
>+ if (!pdn->vfs_expanded) {
>+ dev_info(&pdev->dev, "don't support this SRIOV device"
>+ " with non 64bit-prefetchable IOV BAR\n");
>+ return -ENOSPC;
>+ }
>+
> /* Calculate available PE for required VFs */
> mutex_lock(&phb->ioda.pe_alloc_mutex);
> pdn->offset = bitmap_find_next_zero_area(
>@@ -2774,9 +2771,10 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
> if (!res->flags || res->parent)
> continue;
> if (!pnv_pci_is_mem_pref_64(res->flags)) {
>- dev_warn(&pdev->dev, " non M64 VF BAR%d: %pR\n",
>+ dev_warn(&pdev->dev, "Don't support SR-IOV with"
>+ " non M64 VF BAR%d: %pR. \n",
> i, res);
>- continue;
>+ return;
> }
>
> size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
>@@ -2795,11 +2793,6 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
> res = &pdev->resource[i + PCI_IOV_RESOURCES];
> if (!res->flags || res->parent)
> continue;
>- if (!pnv_pci_is_mem_pref_64(res->flags)) {
>- dev_warn(&pdev->dev, "Skipping expanding VF BAR%d: %pR\n",
>- i, res);
>- continue;
>- }
>
> dev_dbg(&pdev->dev, " Fixing VF BAR%d: %pR to\n", i, res);
> size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
>--
>1.7.9.5
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v3 2/6] powerpc/powernv: simplify the calculation of iov resource alignment
2015-08-13 14:11 [PATCH v3 0/6] Redesign SR-IOV on PowerNV Wei Yang
2015-08-13 14:11 ` [PATCH v3 1/6] powerpc/powernv: don't enable SRIOV when VF BAR has non 64bit-prefetchable BAR Wei Yang
@ 2015-08-13 14:11 ` Wei Yang
2015-08-14 1:04 ` Gavin Shan
2015-08-13 14:11 ` [PATCH v3 3/6] powerpc/powernv: use one M64 BAR in Single PE mode for one VF BAR Wei Yang
` (3 subsequent siblings)
5 siblings, 1 reply; 22+ messages in thread
From: Wei Yang @ 2015-08-13 14:11 UTC (permalink / raw)
To: aik, gwshan, benh; +Cc: linuxppc-dev, Wei Yang
The alignment of IOV BAR on PowerNV platform is the total size of the IOV
BAR. No matter whether the IOV BAR is extended with number of
roundup_pow_of_two(total_vfs) or number of max PE number (256), the total
size could be calculated by (vfs_expanded * VF_BAR_size).
This patch simplifies the pnv_pci_iov_resource_alignment() by removing the
first case.
Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
Reviewed-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
arch/powerpc/platforms/powernv/pci-ioda.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 9ac324e..67b8f72 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -2987,12 +2987,16 @@ static resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev,
int resno)
{
struct pci_dn *pdn = pci_get_pdn(pdev);
- resource_size_t align, iov_align;
-
- iov_align = resource_size(&pdev->resource[resno]);
- if (iov_align)
- return iov_align;
+ resource_size_t align;
+ /*
+ * On PowerNV platform, IOV BAR is mapped by M64 BAR to enable the
+ * SR-IOV. While from hardware perspective, the range mapped by M64
+ * BAR should be size aligned.
+ *
+ * This function return the total IOV BAR size if expanded or just the
+ * individual size if not.
+ */
align = pci_iov_resource_size(pdev, resno);
if (pdn->vfs_expanded)
return pdn->vfs_expanded * align;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v3 2/6] powerpc/powernv: simplify the calculation of iov resource alignment
2015-08-13 14:11 ` [PATCH v3 2/6] powerpc/powernv: simplify the calculation of iov resource alignment Wei Yang
@ 2015-08-14 1:04 ` Gavin Shan
2015-08-14 3:39 ` Wei Yang
0 siblings, 1 reply; 22+ messages in thread
From: Gavin Shan @ 2015-08-14 1:04 UTC (permalink / raw)
To: Wei Yang; +Cc: aik, gwshan, benh, linuxppc-dev
On Thu, Aug 13, 2015 at 10:11:07PM +0800, Wei Yang wrote:
>The alignment of IOV BAR on PowerNV platform is the total size of the IOV
>BAR. No matter whether the IOV BAR is extended with number of
>roundup_pow_of_two(total_vfs) or number of max PE number (256), the total
>size could be calculated by (vfs_expanded * VF_BAR_size).
>
>This patch simplifies the pnv_pci_iov_resource_alignment() by removing the
>first case.
>
>Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
>Reviewed-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
>---
> arch/powerpc/platforms/powernv/pci-ioda.c | 14 +++++++++-----
> 1 file changed, 9 insertions(+), 5 deletions(-)
>
>diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
>index 9ac324e..67b8f72 100644
>--- a/arch/powerpc/platforms/powernv/pci-ioda.c
>+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
>@@ -2987,12 +2987,16 @@ static resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev,
> int resno)
> {
> struct pci_dn *pdn = pci_get_pdn(pdev);
>- resource_size_t align, iov_align;
>-
>- iov_align = resource_size(&pdev->resource[resno]);
>- if (iov_align)
>- return iov_align;
>+ resource_size_t align;
>
>+ /*
>+ * On PowerNV platform, IOV BAR is mapped by M64 BAR to enable the
>+ * SR-IOV. While from hardware perspective, the range mapped by M64
>+ * BAR should be size aligned.
>+ *
>+ * This function return the total IOV BAR size if expanded or just the
>+ * individual size if not.
>+ */
s/return/returns
> align = pci_iov_resource_size(pdev, resno);
> if (pdn->vfs_expanded)
> return pdn->vfs_expanded * align;
>--
>1.7.9.5
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v3 2/6] powerpc/powernv: simplify the calculation of iov resource alignment
2015-08-14 1:04 ` Gavin Shan
@ 2015-08-14 3:39 ` Wei Yang
0 siblings, 0 replies; 22+ messages in thread
From: Wei Yang @ 2015-08-14 3:39 UTC (permalink / raw)
To: Gavin Shan; +Cc: Wei Yang, aik, benh, linuxppc-dev
On Fri, Aug 14, 2015 at 11:04:58AM +1000, Gavin Shan wrote:
>On Thu, Aug 13, 2015 at 10:11:07PM +0800, Wei Yang wrote:
>>The alignment of IOV BAR on PowerNV platform is the total size of the IOV
>>BAR. No matter whether the IOV BAR is extended with number of
>>roundup_pow_of_two(total_vfs) or number of max PE number (256), the total
>>size could be calculated by (vfs_expanded * VF_BAR_size).
>>
>>This patch simplifies the pnv_pci_iov_resource_alignment() by removing the
>>first case.
>>
>>Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
>>Reviewed-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
>>---
>> arch/powerpc/platforms/powernv/pci-ioda.c | 14 +++++++++-----
>> 1 file changed, 9 insertions(+), 5 deletions(-)
>>
>>diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
>>index 9ac324e..67b8f72 100644
>>--- a/arch/powerpc/platforms/powernv/pci-ioda.c
>>+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
>>@@ -2987,12 +2987,16 @@ static resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev,
>> int resno)
>> {
>> struct pci_dn *pdn = pci_get_pdn(pdev);
>>- resource_size_t align, iov_align;
>>-
>>- iov_align = resource_size(&pdev->resource[resno]);
>>- if (iov_align)
>>- return iov_align;
>>+ resource_size_t align;
>>
>>+ /*
>>+ * On PowerNV platform, IOV BAR is mapped by M64 BAR to enable the
>>+ * SR-IOV. While from hardware perspective, the range mapped by M64
>>+ * BAR should be size aligned.
>>+ *
>>+ * This function return the total IOV BAR size if expanded or just the
>>+ * individual size if not.
>>+ */
>
>s/return/returns
>
Thanks :-)
>> align = pci_iov_resource_size(pdev, resno);
>> if (pdn->vfs_expanded)
>> return pdn->vfs_expanded * align;
>>--
>>1.7.9.5
>>
--
Richard Yang
Help you, Help me
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v3 3/6] powerpc/powernv: use one M64 BAR in Single PE mode for one VF BAR
2015-08-13 14:11 [PATCH v3 0/6] Redesign SR-IOV on PowerNV Wei Yang
2015-08-13 14:11 ` [PATCH v3 1/6] powerpc/powernv: don't enable SRIOV when VF BAR has non 64bit-prefetchable BAR Wei Yang
2015-08-13 14:11 ` [PATCH v3 2/6] powerpc/powernv: simplify the calculation of iov resource alignment Wei Yang
@ 2015-08-13 14:11 ` Wei Yang
2015-08-14 0:52 ` Gavin Shan
2015-08-13 14:11 ` [PATCH v3 4/6] powerpc/powernv: replace the hard coded boundary with gate Wei Yang
` (2 subsequent siblings)
5 siblings, 1 reply; 22+ messages in thread
From: Wei Yang @ 2015-08-13 14:11 UTC (permalink / raw)
To: aik, gwshan, benh; +Cc: linuxppc-dev, Wei Yang
In current implementation, when VF BAR is bigger than 64MB, it uses 4 M64
BARs in Single PE mode to cover the number of VFs required to be enabled.
By doing so, several VFs would be in one VF Group and leads to interference
between VFs in the same group.
This patch changes the design by using one M64 BAR in Single PE mode for
one VF BAR. This gives absolute isolation for VFs.
Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/pci-bridge.h | 6 +-
arch/powerpc/platforms/powernv/pci-ioda.c | 163 +++++++++++------------------
2 files changed, 62 insertions(+), 107 deletions(-)
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 712add5..9d33ada 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -187,6 +187,7 @@ static inline int isa_vaddr_is_ioport(void __iomem *address)
*/
struct iommu_table;
+#define MAX_M64_BAR 16
struct pci_dn {
int flags;
#define PCI_DN_FLAG_IOV_VF 0x01
@@ -214,10 +215,9 @@ struct pci_dn {
u16 vfs_expanded; /* number of VFs IOV BAR expanded */
u16 num_vfs; /* number of VFs enabled*/
int offset; /* PE# for the first VF PE */
-#define M64_PER_IOV 4
- int m64_per_iov;
+ bool m64_single_mode; /* Use M64 BAR in Single Mode */
#define IODA_INVALID_M64 (-1)
- int m64_wins[PCI_SRIOV_NUM_BARS][M64_PER_IOV];
+ int m64_map[PCI_SRIOV_NUM_BARS][MAX_M64_BAR];
#endif /* CONFIG_PCI_IOV */
#endif
struct list_head child_list;
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 67b8f72..4da0f50 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1162,15 +1162,14 @@ static int pnv_pci_vf_release_m64(struct pci_dev *pdev)
pdn = pci_get_pdn(pdev);
for (i = 0; i < PCI_SRIOV_NUM_BARS; i++)
- for (j = 0; j < M64_PER_IOV; j++) {
- if (pdn->m64_wins[i][j] == IODA_INVALID_M64)
+ for (j = 0; j < MAX_M64_BAR; j++) {
+ if (pdn->m64_map[i][j] == IODA_INVALID_M64)
continue;
opal_pci_phb_mmio_enable(phb->opal_id,
- OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 0);
- clear_bit(pdn->m64_wins[i][j], &phb->ioda.m64_bar_alloc);
- pdn->m64_wins[i][j] = IODA_INVALID_M64;
+ OPAL_M64_WINDOW_TYPE, pdn->m64_map[i][j], 0);
+ clear_bit(pdn->m64_map[i][j], &phb->ioda.m64_bar_alloc);
+ pdn->m64_map[i][j] = IODA_INVALID_M64;
}
-
return 0;
}
@@ -1187,8 +1186,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
int total_vfs;
resource_size_t size, start;
int pe_num;
- int vf_groups;
- int vf_per_group;
+ int m64_bars;
bus = pdev->bus;
hose = pci_bus_to_host(bus);
@@ -1196,26 +1194,23 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
pdn = pci_get_pdn(pdev);
total_vfs = pci_sriov_get_totalvfs(pdev);
- /* Initialize the m64_wins to IODA_INVALID_M64 */
- for (i = 0; i < PCI_SRIOV_NUM_BARS; i++)
- for (j = 0; j < M64_PER_IOV; j++)
- pdn->m64_wins[i][j] = IODA_INVALID_M64;
+ if (pdn->m64_single_mode)
+ m64_bars = num_vfs;
+ else
+ m64_bars = 1;
+
+ /* Initialize the m64_map to IODA_INVALID_M64 */
+ for (i = 0; i < PCI_SRIOV_NUM_BARS ; i++)
+ for (j = 0; j < MAX_M64_BAR; j++)
+ pdn->m64_map[i][j] = IODA_INVALID_M64;
- if (pdn->m64_per_iov == M64_PER_IOV) {
- vf_groups = (num_vfs <= M64_PER_IOV) ? num_vfs: M64_PER_IOV;
- vf_per_group = (num_vfs <= M64_PER_IOV)? 1:
- roundup_pow_of_two(num_vfs) / pdn->m64_per_iov;
- } else {
- vf_groups = 1;
- vf_per_group = 1;
- }
for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
res = &pdev->resource[i + PCI_IOV_RESOURCES];
if (!res->flags || !res->parent)
continue;
- for (j = 0; j < vf_groups; j++) {
+ for (j = 0; j < m64_bars; j++) {
do {
win = find_next_zero_bit(&phb->ioda.m64_bar_alloc,
phb->ioda.m64_bar_idx + 1, 0);
@@ -1224,12 +1219,11 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
goto m64_failed;
} while (test_and_set_bit(win, &phb->ioda.m64_bar_alloc));
- pdn->m64_wins[i][j] = win;
+ pdn->m64_map[i][j] = win;
- if (pdn->m64_per_iov == M64_PER_IOV) {
+ if (pdn->m64_single_mode) {
size = pci_iov_resource_size(pdev,
PCI_IOV_RESOURCES + i);
- size = size * vf_per_group;
start = res->start + size * j;
} else {
size = resource_size(res);
@@ -1237,16 +1231,16 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
}
/* Map the M64 here */
- if (pdn->m64_per_iov == M64_PER_IOV) {
+ if (pdn->m64_single_mode) {
pe_num = pdn->offset + j;
rc = opal_pci_map_pe_mmio_window(phb->opal_id,
pe_num, OPAL_M64_WINDOW_TYPE,
- pdn->m64_wins[i][j], 0);
+ pdn->m64_map[i][j], 0);
}
rc = opal_pci_set_phb_mem_window(phb->opal_id,
OPAL_M64_WINDOW_TYPE,
- pdn->m64_wins[i][j],
+ pdn->m64_map[i][j],
start,
0, /* unused */
size);
@@ -1258,12 +1252,12 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
goto m64_failed;
}
- if (pdn->m64_per_iov == M64_PER_IOV)
+ if (pdn->m64_single_mode)
rc = opal_pci_phb_mmio_enable(phb->opal_id,
- OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 2);
+ OPAL_M64_WINDOW_TYPE, pdn->m64_map[i][j], 2);
else
rc = opal_pci_phb_mmio_enable(phb->opal_id,
- OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 1);
+ OPAL_M64_WINDOW_TYPE, pdn->m64_map[i][j], 1);
if (rc != OPAL_SUCCESS) {
dev_err(&pdev->dev, "Failed to enable M64 window #%d: %llx\n",
@@ -1302,15 +1296,13 @@ static void pnv_pci_ioda2_release_dma_pe(struct pci_dev *dev, struct pnv_ioda_pe
iommu_free_table(tbl, of_node_full_name(dev->dev.of_node));
}
-static void pnv_ioda_release_vf_PE(struct pci_dev *pdev, u16 num_vfs)
+static void pnv_ioda_release_vf_PE(struct pci_dev *pdev)
{
struct pci_bus *bus;
struct pci_controller *hose;
struct pnv_phb *phb;
struct pnv_ioda_pe *pe, *pe_n;
struct pci_dn *pdn;
- u16 vf_index;
- int64_t rc;
bus = pdev->bus;
hose = pci_bus_to_host(bus);
@@ -1320,35 +1312,6 @@ static void pnv_ioda_release_vf_PE(struct pci_dev *pdev, u16 num_vfs)
if (!pdev->is_physfn)
return;
- if (pdn->m64_per_iov == M64_PER_IOV && num_vfs > M64_PER_IOV) {
- int vf_group;
- int vf_per_group;
- int vf_index1;
-
- vf_per_group = roundup_pow_of_two(num_vfs) / pdn->m64_per_iov;
-
- for (vf_group = 0; vf_group < M64_PER_IOV; vf_group++)
- for (vf_index = vf_group * vf_per_group;
- vf_index < (vf_group + 1) * vf_per_group &&
- vf_index < num_vfs;
- vf_index++)
- for (vf_index1 = vf_group * vf_per_group;
- vf_index1 < (vf_group + 1) * vf_per_group &&
- vf_index1 < num_vfs;
- vf_index1++){
-
- rc = opal_pci_set_peltv(phb->opal_id,
- pdn->offset + vf_index,
- pdn->offset + vf_index1,
- OPAL_REMOVE_PE_FROM_DOMAIN);
-
- if (rc)
- dev_warn(&pdev->dev, "%s: Failed to unlink same group PE#%d(%lld)\n",
- __func__,
- pdn->offset + vf_index1, rc);
- }
- }
-
list_for_each_entry_safe(pe, pe_n, &phb->ioda.pe_list, list) {
if (pe->parent_dev != pdev)
continue;
@@ -1383,10 +1346,10 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev)
num_vfs = pdn->num_vfs;
/* Release VF PEs */
- pnv_ioda_release_vf_PE(pdev, num_vfs);
+ pnv_ioda_release_vf_PE(pdev);
if (phb->type == PNV_PHB_IODA2) {
- if (pdn->m64_per_iov == 1)
+ if (!pdn->m64_single_mode)
pnv_pci_vf_resource_shift(pdev, -pdn->offset);
/* Release M64 windows */
@@ -1409,7 +1372,6 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)
int pe_num;
u16 vf_index;
struct pci_dn *pdn;
- int64_t rc;
bus = pdev->bus;
hose = pci_bus_to_host(bus);
@@ -1454,37 +1416,6 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)
pnv_pci_ioda2_setup_dma_pe(phb, pe);
}
-
- if (pdn->m64_per_iov == M64_PER_IOV && num_vfs > M64_PER_IOV) {
- int vf_group;
- int vf_per_group;
- int vf_index1;
-
- vf_per_group = roundup_pow_of_two(num_vfs) / pdn->m64_per_iov;
-
- for (vf_group = 0; vf_group < M64_PER_IOV; vf_group++) {
- for (vf_index = vf_group * vf_per_group;
- vf_index < (vf_group + 1) * vf_per_group &&
- vf_index < num_vfs;
- vf_index++) {
- for (vf_index1 = vf_group * vf_per_group;
- vf_index1 < (vf_group + 1) * vf_per_group &&
- vf_index1 < num_vfs;
- vf_index1++) {
-
- rc = opal_pci_set_peltv(phb->opal_id,
- pdn->offset + vf_index,
- pdn->offset + vf_index1,
- OPAL_ADD_PE_TO_DOMAIN);
-
- if (rc)
- dev_warn(&pdev->dev, "%s: Failed to link same group PE#%d(%lld)\n",
- __func__,
- pdn->offset + vf_index1, rc);
- }
- }
- }
- }
}
int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
@@ -1507,6 +1438,15 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
return -ENOSPC;
}
+ /*
+ * When M64 BAR functions in Single PE mode, the number of VFs
+ * could be enabled must be less than the number of M64 BARs.
+ */
+ if (pdn->m64_single_mode && num_vfs > phb->ioda.m64_bar_idx) {
+ dev_info(&pdev->dev, "Not enough M64 BAR for VFs\n");
+ return -EBUSY;
+ }
+
/* Calculate available PE for required VFs */
mutex_lock(&phb->ioda.pe_alloc_mutex);
pdn->offset = bitmap_find_next_zero_area(
@@ -1534,7 +1474,7 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
* the IOV BAR according to the PE# allocated to the VFs.
* Otherwise, the PE# for the VF will conflict with others.
*/
- if (pdn->m64_per_iov == 1) {
+ if (!pdn->m64_single_mode) {
ret = pnv_pci_vf_resource_shift(pdev, pdn->offset);
if (ret)
goto m64_failed;
@@ -1567,8 +1507,7 @@ int pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
/* Allocate PCI data */
add_dev_pci_data(pdev);
- pnv_pci_sriov_enable(pdev, num_vfs);
- return 0;
+ return pnv_pci_sriov_enable(pdev, num_vfs);
}
#endif /* CONFIG_PCI_IOV */
@@ -2761,9 +2700,9 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
pdn = pci_get_pdn(pdev);
pdn->vfs_expanded = 0;
+ pdn->m64_single_mode = false;
total_vfs = pci_sriov_get_totalvfs(pdev);
- pdn->m64_per_iov = 1;
mul = phb->ioda.total_pe;
for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
@@ -2783,8 +2722,8 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
if (size > (1 << 26)) {
dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size is bigger than 64M, roundup power2\n",
i, res);
- pdn->m64_per_iov = M64_PER_IOV;
mul = roundup_pow_of_two(total_vfs);
+ pdn->m64_single_mode = true;
break;
}
}
@@ -2986,6 +2925,8 @@ static resource_size_t pnv_pci_window_alignment(struct pci_bus *bus,
static resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev,
int resno)
{
+ struct pci_controller *hose = pci_bus_to_host(pdev->bus);
+ struct pnv_phb *phb = hose->private_data;
struct pci_dn *pdn = pci_get_pdn(pdev);
resource_size_t align;
@@ -2994,12 +2935,26 @@ static resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev,
* SR-IOV. While from hardware perspective, the range mapped by M64
* BAR should be size aligned.
*
+ * When IOV BAR is mapped with M64 BAR in Single PE mode, the extra
+ * powernv-specific hardware restriction is gone. But if just use the
+ * VF BAR size as the alignment, PF BAR / VF BAR may be allocated with
+ * in one segment of M64 #15, which introduces the PE conflict between
+ * PF and VF. Based on this, the minimum alignment of an IOV BAR is
+ * m64_segsize.
+ *
* This function return the total IOV BAR size if expanded or just the
- * individual size if not.
+ * individual size if not, when M64 BAR is in Shared PE mode.
+ * If the M64 BAR is in Single PE mode, return the VF BAR size or
+ * m64_size if IOV BAR size is less.
*/
align = pci_iov_resource_size(pdev, resno);
- if (pdn->vfs_expanded)
- return pdn->vfs_expanded * align;
+ if (pdn->vfs_expanded) {
+ if (pdn->m64_single_mode)
+ return max(align,
+ (resource_size_t)phb->ioda.m64_segsize);
+ else
+ return pdn->vfs_expanded * align;
+ }
return align;
}
--
1.7.9.5
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v3 3/6] powerpc/powernv: use one M64 BAR in Single PE mode for one VF BAR
2015-08-13 14:11 ` [PATCH v3 3/6] powerpc/powernv: use one M64 BAR in Single PE mode for one VF BAR Wei Yang
@ 2015-08-14 0:52 ` Gavin Shan
2015-08-14 3:54 ` Wei Yang
0 siblings, 1 reply; 22+ messages in thread
From: Gavin Shan @ 2015-08-14 0:52 UTC (permalink / raw)
To: Wei Yang; +Cc: aik, gwshan, benh, linuxppc-dev
On Thu, Aug 13, 2015 at 10:11:08PM +0800, Wei Yang wrote:
>In current implementation, when VF BAR is bigger than 64MB, it uses 4 M64
>BARs in Single PE mode to cover the number of VFs required to be enabled.
>By doing so, several VFs would be in one VF Group and leads to interference
>between VFs in the same group.
>
>This patch changes the design by using one M64 BAR in Single PE mode for
>one VF BAR. This gives absolute isolation for VFs.
>
>Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
>---
> arch/powerpc/include/asm/pci-bridge.h | 6 +-
> arch/powerpc/platforms/powernv/pci-ioda.c | 163 +++++++++++------------------
> 2 files changed, 62 insertions(+), 107 deletions(-)
>
>diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
>index 712add5..9d33ada 100644
>--- a/arch/powerpc/include/asm/pci-bridge.h
>+++ b/arch/powerpc/include/asm/pci-bridge.h
>@@ -187,6 +187,7 @@ static inline int isa_vaddr_is_ioport(void __iomem *address)
> */
> struct iommu_table;
>
>+#define MAX_M64_BAR 16
struct pnv_phb::m64_bar_idx is initialized to 15. Another macro is defined here
as 16. Both of them can be used as maximal M64 BAR number. Obviously, they're
duplicated. On the other hand, I don't think it's a good idea to have the static
"m64_map" because @pdn is created for every PCI devices, including VFs. non-PF
don't "m64_map", together other fields like "m64_per_iov" at all. It's obviously
wasting memory. So it would be allocated dynamically when the PF's pdn is created
or in pnv_pci_ioda_fixup_iov_resources().
In long run, it might be reasonable to move all SRIOV related fields in pci_dn
to another data struct (struct pci_iov_dn?) and allocate that dynamically.
> int flags;
> #define PCI_DN_FLAG_IOV_VF 0x01
>@@ -214,10 +215,9 @@ struct pci_dn {
> u16 vfs_expanded; /* number of VFs IOV BAR expanded */
> u16 num_vfs; /* number of VFs enabled*/
> int offset; /* PE# for the first VF PE */
>-#define M64_PER_IOV 4
>- int m64_per_iov;
>+ bool m64_single_mode; /* Use M64 BAR in Single Mode */
> #define IODA_INVALID_M64 (-1)
>- int m64_wins[PCI_SRIOV_NUM_BARS][M64_PER_IOV];
>+ int m64_map[PCI_SRIOV_NUM_BARS][MAX_M64_BAR];
> #endif /* CONFIG_PCI_IOV */
> #endif
> struct list_head child_list;
>diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
>index 67b8f72..4da0f50 100644
>--- a/arch/powerpc/platforms/powernv/pci-ioda.c
>+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
>@@ -1162,15 +1162,14 @@ static int pnv_pci_vf_release_m64(struct pci_dev *pdev)
> pdn = pci_get_pdn(pdev);
>
> for (i = 0; i < PCI_SRIOV_NUM_BARS; i++)
>- for (j = 0; j < M64_PER_IOV; j++) {
>- if (pdn->m64_wins[i][j] == IODA_INVALID_M64)
>+ for (j = 0; j < MAX_M64_BAR; j++) {
>+ if (pdn->m64_map[i][j] == IODA_INVALID_M64)
> continue;
> opal_pci_phb_mmio_enable(phb->opal_id,
>- OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 0);
>- clear_bit(pdn->m64_wins[i][j], &phb->ioda.m64_bar_alloc);
>- pdn->m64_wins[i][j] = IODA_INVALID_M64;
>+ OPAL_M64_WINDOW_TYPE, pdn->m64_map[i][j], 0);
>+ clear_bit(pdn->m64_map[i][j], &phb->ioda.m64_bar_alloc);
>+ pdn->m64_map[i][j] = IODA_INVALID_M64;
> }
>-
> return 0;
> }
>
>@@ -1187,8 +1186,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
> int total_vfs;
> resource_size_t size, start;
> int pe_num;
>- int vf_groups;
>- int vf_per_group;
>+ int m64_bars;
>
> bus = pdev->bus;
> hose = pci_bus_to_host(bus);
>@@ -1196,26 +1194,23 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
> pdn = pci_get_pdn(pdev);
> total_vfs = pci_sriov_get_totalvfs(pdev);
>
>- /* Initialize the m64_wins to IODA_INVALID_M64 */
>- for (i = 0; i < PCI_SRIOV_NUM_BARS; i++)
>- for (j = 0; j < M64_PER_IOV; j++)
>- pdn->m64_wins[i][j] = IODA_INVALID_M64;
>+ if (pdn->m64_single_mode)
>+ m64_bars = num_vfs;
>+ else
>+ m64_bars = 1;
>+
>+ /* Initialize the m64_map to IODA_INVALID_M64 */
>+ for (i = 0; i < PCI_SRIOV_NUM_BARS ; i++)
>+ for (j = 0; j < MAX_M64_BAR; j++)
>+ pdn->m64_map[i][j] = IODA_INVALID_M64;
It would be done in pnv_pci_ioda_fixup_iov_resources(). That means it will
be done for once if hotplug isn't considered. The code here will be called
on every attempt to enable SRIOV capability, which isn't necessary, right?
>
>- if (pdn->m64_per_iov == M64_PER_IOV) {
>- vf_groups = (num_vfs <= M64_PER_IOV) ? num_vfs: M64_PER_IOV;
>- vf_per_group = (num_vfs <= M64_PER_IOV)? 1:
>- roundup_pow_of_two(num_vfs) / pdn->m64_per_iov;
>- } else {
>- vf_groups = 1;
>- vf_per_group = 1;
>- }
>
> for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
> res = &pdev->resource[i + PCI_IOV_RESOURCES];
> if (!res->flags || !res->parent)
> continue;
>
>- for (j = 0; j < vf_groups; j++) {
>+ for (j = 0; j < m64_bars; j++) {
> do {
> win = find_next_zero_bit(&phb->ioda.m64_bar_alloc,
> phb->ioda.m64_bar_idx + 1, 0);
>@@ -1224,12 +1219,11 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
> goto m64_failed;
> } while (test_and_set_bit(win, &phb->ioda.m64_bar_alloc));
>
>- pdn->m64_wins[i][j] = win;
>+ pdn->m64_map[i][j] = win;
>
>- if (pdn->m64_per_iov == M64_PER_IOV) {
>+ if (pdn->m64_single_mode) {
> size = pci_iov_resource_size(pdev,
> PCI_IOV_RESOURCES + i);
>- size = size * vf_per_group;
> start = res->start + size * j;
> } else {
> size = resource_size(res);
>@@ -1237,16 +1231,16 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
> }
>
> /* Map the M64 here */
>- if (pdn->m64_per_iov == M64_PER_IOV) {
>+ if (pdn->m64_single_mode) {
> pe_num = pdn->offset + j;
> rc = opal_pci_map_pe_mmio_window(phb->opal_id,
> pe_num, OPAL_M64_WINDOW_TYPE,
>- pdn->m64_wins[i][j], 0);
>+ pdn->m64_map[i][j], 0);
> }
>
> rc = opal_pci_set_phb_mem_window(phb->opal_id,
> OPAL_M64_WINDOW_TYPE,
>- pdn->m64_wins[i][j],
>+ pdn->m64_map[i][j],
> start,
> 0, /* unused */
> size);
>@@ -1258,12 +1252,12 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
> goto m64_failed;
> }
>
>- if (pdn->m64_per_iov == M64_PER_IOV)
>+ if (pdn->m64_single_mode)
> rc = opal_pci_phb_mmio_enable(phb->opal_id,
>- OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 2);
>+ OPAL_M64_WINDOW_TYPE, pdn->m64_map[i][j], 2);
> else
> rc = opal_pci_phb_mmio_enable(phb->opal_id,
>- OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 1);
>+ OPAL_M64_WINDOW_TYPE, pdn->m64_map[i][j], 1);
>
> if (rc != OPAL_SUCCESS) {
> dev_err(&pdev->dev, "Failed to enable M64 window #%d: %llx\n",
>@@ -1302,15 +1296,13 @@ static void pnv_pci_ioda2_release_dma_pe(struct pci_dev *dev, struct pnv_ioda_pe
> iommu_free_table(tbl, of_node_full_name(dev->dev.of_node));
> }
>
>-static void pnv_ioda_release_vf_PE(struct pci_dev *pdev, u16 num_vfs)
>+static void pnv_ioda_release_vf_PE(struct pci_dev *pdev)
> {
> struct pci_bus *bus;
> struct pci_controller *hose;
> struct pnv_phb *phb;
> struct pnv_ioda_pe *pe, *pe_n;
> struct pci_dn *pdn;
>- u16 vf_index;
>- int64_t rc;
>
> bus = pdev->bus;
> hose = pci_bus_to_host(bus);
>@@ -1320,35 +1312,6 @@ static void pnv_ioda_release_vf_PE(struct pci_dev *pdev, u16 num_vfs)
> if (!pdev->is_physfn)
> return;
>
>- if (pdn->m64_per_iov == M64_PER_IOV && num_vfs > M64_PER_IOV) {
>- int vf_group;
>- int vf_per_group;
>- int vf_index1;
>-
>- vf_per_group = roundup_pow_of_two(num_vfs) / pdn->m64_per_iov;
>-
>- for (vf_group = 0; vf_group < M64_PER_IOV; vf_group++)
>- for (vf_index = vf_group * vf_per_group;
>- vf_index < (vf_group + 1) * vf_per_group &&
>- vf_index < num_vfs;
>- vf_index++)
>- for (vf_index1 = vf_group * vf_per_group;
>- vf_index1 < (vf_group + 1) * vf_per_group &&
>- vf_index1 < num_vfs;
>- vf_index1++){
>-
>- rc = opal_pci_set_peltv(phb->opal_id,
>- pdn->offset + vf_index,
>- pdn->offset + vf_index1,
>- OPAL_REMOVE_PE_FROM_DOMAIN);
>-
>- if (rc)
>- dev_warn(&pdev->dev, "%s: Failed to unlink same group PE#%d(%lld)\n",
>- __func__,
>- pdn->offset + vf_index1, rc);
>- }
>- }
>-
> list_for_each_entry_safe(pe, pe_n, &phb->ioda.pe_list, list) {
> if (pe->parent_dev != pdev)
> continue;
>@@ -1383,10 +1346,10 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev)
> num_vfs = pdn->num_vfs;
>
> /* Release VF PEs */
>- pnv_ioda_release_vf_PE(pdev, num_vfs);
>+ pnv_ioda_release_vf_PE(pdev);
>
> if (phb->type == PNV_PHB_IODA2) {
>- if (pdn->m64_per_iov == 1)
>+ if (!pdn->m64_single_mode)
> pnv_pci_vf_resource_shift(pdev, -pdn->offset);
>
> /* Release M64 windows */
>@@ -1409,7 +1372,6 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)
> int pe_num;
> u16 vf_index;
> struct pci_dn *pdn;
>- int64_t rc;
>
> bus = pdev->bus;
> hose = pci_bus_to_host(bus);
>@@ -1454,37 +1416,6 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)
>
> pnv_pci_ioda2_setup_dma_pe(phb, pe);
> }
>-
>- if (pdn->m64_per_iov == M64_PER_IOV && num_vfs > M64_PER_IOV) {
>- int vf_group;
>- int vf_per_group;
>- int vf_index1;
>-
>- vf_per_group = roundup_pow_of_two(num_vfs) / pdn->m64_per_iov;
>-
>- for (vf_group = 0; vf_group < M64_PER_IOV; vf_group++) {
>- for (vf_index = vf_group * vf_per_group;
>- vf_index < (vf_group + 1) * vf_per_group &&
>- vf_index < num_vfs;
>- vf_index++) {
>- for (vf_index1 = vf_group * vf_per_group;
>- vf_index1 < (vf_group + 1) * vf_per_group &&
>- vf_index1 < num_vfs;
>- vf_index1++) {
>-
>- rc = opal_pci_set_peltv(phb->opal_id,
>- pdn->offset + vf_index,
>- pdn->offset + vf_index1,
>- OPAL_ADD_PE_TO_DOMAIN);
>-
>- if (rc)
>- dev_warn(&pdev->dev, "%s: Failed to link same group PE#%d(%lld)\n",
>- __func__,
>- pdn->offset + vf_index1, rc);
>- }
>- }
>- }
>- }
> }
>
> int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
>@@ -1507,6 +1438,15 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
> return -ENOSPC;
> }
>
>+ /*
>+ * When M64 BAR functions in Single PE mode, the number of VFs
>+ * could be enabled must be less than the number of M64 BARs.
>+ */
>+ if (pdn->m64_single_mode && num_vfs > phb->ioda.m64_bar_idx) {
>+ dev_info(&pdev->dev, "Not enough M64 BAR for VFs\n");
>+ return -EBUSY;
>+ }
s/M64 BAR/M64 BARs
>+
> /* Calculate available PE for required VFs */
> mutex_lock(&phb->ioda.pe_alloc_mutex);
> pdn->offset = bitmap_find_next_zero_area(
>@@ -1534,7 +1474,7 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
> * the IOV BAR according to the PE# allocated to the VFs.
> * Otherwise, the PE# for the VF will conflict with others.
> */
>- if (pdn->m64_per_iov == 1) {
>+ if (!pdn->m64_single_mode) {
> ret = pnv_pci_vf_resource_shift(pdev, pdn->offset);
> if (ret)
> goto m64_failed;
>@@ -1567,8 +1507,7 @@ int pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
> /* Allocate PCI data */
> add_dev_pci_data(pdev);
>
>- pnv_pci_sriov_enable(pdev, num_vfs);
>- return 0;
>+ return pnv_pci_sriov_enable(pdev, num_vfs);
> }
> #endif /* CONFIG_PCI_IOV */
>
>@@ -2761,9 +2700,9 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
>
> pdn = pci_get_pdn(pdev);
> pdn->vfs_expanded = 0;
>+ pdn->m64_single_mode = false;
>
> total_vfs = pci_sriov_get_totalvfs(pdev);
>- pdn->m64_per_iov = 1;
> mul = phb->ioda.total_pe;
>
> for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
>@@ -2783,8 +2722,8 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
> if (size > (1 << 26)) {
> dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size is bigger than 64M, roundup power2\n",
> i, res);
>- pdn->m64_per_iov = M64_PER_IOV;
> mul = roundup_pow_of_two(total_vfs);
>+ pdn->m64_single_mode = true;
> break;
> }
> }
>@@ -2986,6 +2925,8 @@ static resource_size_t pnv_pci_window_alignment(struct pci_bus *bus,
> static resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev,
> int resno)
> {
>+ struct pci_controller *hose = pci_bus_to_host(pdev->bus);
>+ struct pnv_phb *phb = hose->private_data;
> struct pci_dn *pdn = pci_get_pdn(pdev);
> resource_size_t align;
>
>@@ -2994,12 +2935,26 @@ static resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev,
> * SR-IOV. While from hardware perspective, the range mapped by M64
> * BAR should be size aligned.
> *
>+ * When IOV BAR is mapped with M64 BAR in Single PE mode, the extra
>+ * powernv-specific hardware restriction is gone. But if just use the
>+ * VF BAR size as the alignment, PF BAR / VF BAR may be allocated with
>+ * in one segment of M64 #15, which introduces the PE conflict between
>+ * PF and VF. Based on this, the minimum alignment of an IOV BAR is
>+ * m64_segsize.
>+ *
> * This function return the total IOV BAR size if expanded or just the
>- * individual size if not.
>+ * individual size if not, when M64 BAR is in Shared PE mode.
>+ * If the M64 BAR is in Single PE mode, return the VF BAR size or
>+ * m64_size if IOV BAR size is less.
> */
s/return/returns
s/m64_size/M64 segment size
> align = pci_iov_resource_size(pdev, resno);
>- if (pdn->vfs_expanded)
>- return pdn->vfs_expanded * align;
>+ if (pdn->vfs_expanded) {
>+ if (pdn->m64_single_mode)
>+ return max(align,
>+ (resource_size_t)phb->ioda.m64_segsize);
>+ else
>+ return pdn->vfs_expanded * align;
>+ }
>
> return align;
> }
>--
>1.7.9.5
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v3 3/6] powerpc/powernv: use one M64 BAR in Single PE mode for one VF BAR
2015-08-14 0:52 ` Gavin Shan
@ 2015-08-14 3:54 ` Wei Yang
2015-08-15 10:10 ` Alexey Kardashevskiy
0 siblings, 1 reply; 22+ messages in thread
From: Wei Yang @ 2015-08-14 3:54 UTC (permalink / raw)
To: Gavin Shan; +Cc: Wei Yang, aik, benh, linuxppc-dev
On Fri, Aug 14, 2015 at 10:52:21AM +1000, Gavin Shan wrote:
>On Thu, Aug 13, 2015 at 10:11:08PM +0800, Wei Yang wrote:
>>In current implementation, when VF BAR is bigger than 64MB, it uses 4 M64
>>BARs in Single PE mode to cover the number of VFs required to be enabled.
>>By doing so, several VFs would be in one VF Group and leads to interference
>>between VFs in the same group.
>>
>>This patch changes the design by using one M64 BAR in Single PE mode for
>>one VF BAR. This gives absolute isolation for VFs.
>>
>>Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
>>---
>> arch/powerpc/include/asm/pci-bridge.h | 6 +-
>> arch/powerpc/platforms/powernv/pci-ioda.c | 163 +++++++++++------------------
>> 2 files changed, 62 insertions(+), 107 deletions(-)
>>
>>diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
>>index 712add5..9d33ada 100644
>>--- a/arch/powerpc/include/asm/pci-bridge.h
>>+++ b/arch/powerpc/include/asm/pci-bridge.h
>>@@ -187,6 +187,7 @@ static inline int isa_vaddr_is_ioport(void __iomem *address)
>> */
>> struct iommu_table;
>>
>>+#define MAX_M64_BAR 16
>
>struct pnv_phb::m64_bar_idx is initialized to 15. Another macro is defined here
>as 16. Both of them can be used as maximal M64 BAR number. Obviously, they're
>duplicated. On the other hand, I don't think it's a good idea to have the static
>"m64_map" because @pdn is created for every PCI devices, including VFs. non-PF
>don't "m64_map", together other fields like "m64_per_iov" at all. It's obviously
>wasting memory. So it would be allocated dynamically when the PF's pdn is created
>or in pnv_pci_ioda_fixup_iov_resources().
>
I prefer the dynamic one.
Alexey,
I changed to static defined based on your comments. So do you have some
concern on the dynamic version?
>In long run, it might be reasonable to move all SRIOV related fields in pci_dn
>to another data struct (struct pci_iov_dn?) and allocate that dynamically.
>
>> int flags;
>> #define PCI_DN_FLAG_IOV_VF 0x01
>>@@ -214,10 +215,9 @@ struct pci_dn {
>> u16 vfs_expanded; /* number of VFs IOV BAR expanded */
>> u16 num_vfs; /* number of VFs enabled*/
>> int offset; /* PE# for the first VF PE */
>>-#define M64_PER_IOV 4
>>- int m64_per_iov;
>>+ bool m64_single_mode; /* Use M64 BAR in Single Mode */
>> #define IODA_INVALID_M64 (-1)
>>- int m64_wins[PCI_SRIOV_NUM_BARS][M64_PER_IOV];
>>+ int m64_map[PCI_SRIOV_NUM_BARS][MAX_M64_BAR];
>> #endif /* CONFIG_PCI_IOV */
>> #endif
>> struct list_head child_list;
>>diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
>>index 67b8f72..4da0f50 100644
>>--- a/arch/powerpc/platforms/powernv/pci-ioda.c
>>+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
>>@@ -1162,15 +1162,14 @@ static int pnv_pci_vf_release_m64(struct pci_dev *pdev)
>> pdn = pci_get_pdn(pdev);
>>
>> for (i = 0; i < PCI_SRIOV_NUM_BARS; i++)
>>- for (j = 0; j < M64_PER_IOV; j++) {
>>- if (pdn->m64_wins[i][j] == IODA_INVALID_M64)
>>+ for (j = 0; j < MAX_M64_BAR; j++) {
>>+ if (pdn->m64_map[i][j] == IODA_INVALID_M64)
>> continue;
>> opal_pci_phb_mmio_enable(phb->opal_id,
>>- OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 0);
>>- clear_bit(pdn->m64_wins[i][j], &phb->ioda.m64_bar_alloc);
>>- pdn->m64_wins[i][j] = IODA_INVALID_M64;
>>+ OPAL_M64_WINDOW_TYPE, pdn->m64_map[i][j], 0);
>>+ clear_bit(pdn->m64_map[i][j], &phb->ioda.m64_bar_alloc);
>>+ pdn->m64_map[i][j] = IODA_INVALID_M64;
>> }
>>-
>> return 0;
>> }
>>
>>@@ -1187,8 +1186,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
>> int total_vfs;
>> resource_size_t size, start;
>> int pe_num;
>>- int vf_groups;
>>- int vf_per_group;
>>+ int m64_bars;
>>
>> bus = pdev->bus;
>> hose = pci_bus_to_host(bus);
>>@@ -1196,26 +1194,23 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
>> pdn = pci_get_pdn(pdev);
>> total_vfs = pci_sriov_get_totalvfs(pdev);
>>
>>- /* Initialize the m64_wins to IODA_INVALID_M64 */
>>- for (i = 0; i < PCI_SRIOV_NUM_BARS; i++)
>>- for (j = 0; j < M64_PER_IOV; j++)
>>- pdn->m64_wins[i][j] = IODA_INVALID_M64;
>>+ if (pdn->m64_single_mode)
>>+ m64_bars = num_vfs;
>>+ else
>>+ m64_bars = 1;
>>+
>>+ /* Initialize the m64_map to IODA_INVALID_M64 */
>>+ for (i = 0; i < PCI_SRIOV_NUM_BARS ; i++)
>>+ for (j = 0; j < MAX_M64_BAR; j++)
>>+ pdn->m64_map[i][j] = IODA_INVALID_M64;
>
>It would be done in pnv_pci_ioda_fixup_iov_resources(). That means it will
>be done for once if hotplug isn't considered. The code here will be called
>on every attempt to enable SRIOV capability, which isn't necessary, right?
>
I think you are right.
--
Richard Yang
Help you, Help me
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v3 3/6] powerpc/powernv: use one M64 BAR in Single PE mode for one VF BAR
2015-08-14 3:54 ` Wei Yang
@ 2015-08-15 10:10 ` Alexey Kardashevskiy
0 siblings, 0 replies; 22+ messages in thread
From: Alexey Kardashevskiy @ 2015-08-15 10:10 UTC (permalink / raw)
To: Wei Yang, Gavin Shan; +Cc: benh, linuxppc-dev
On 08/14/2015 01:54 PM, Wei Yang wrote:
> On Fri, Aug 14, 2015 at 10:52:21AM +1000, Gavin Shan wrote:
>> On Thu, Aug 13, 2015 at 10:11:08PM +0800, Wei Yang wrote:
>>> In current implementation, when VF BAR is bigger than 64MB, it uses 4 M64
>>> BARs in Single PE mode to cover the number of VFs required to be enabled.
>>> By doing so, several VFs would be in one VF Group and leads to interference
>>> between VFs in the same group.
>>>
>>> This patch changes the design by using one M64 BAR in Single PE mode for
>>> one VF BAR. This gives absolute isolation for VFs.
>>>
>>> Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
>>> ---
>>> arch/powerpc/include/asm/pci-bridge.h | 6 +-
>>> arch/powerpc/platforms/powernv/pci-ioda.c | 163 +++++++++++------------------
>>> 2 files changed, 62 insertions(+), 107 deletions(-)
>>>
>>> diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
>>> index 712add5..9d33ada 100644
>>> --- a/arch/powerpc/include/asm/pci-bridge.h
>>> +++ b/arch/powerpc/include/asm/pci-bridge.h
>>> @@ -187,6 +187,7 @@ static inline int isa_vaddr_is_ioport(void __iomem *address)
>>> */
>>> struct iommu_table;
>>>
>>> +#define MAX_M64_BAR 16
>>
>> struct pnv_phb::m64_bar_idx is initialized to 15. Another macro is defined here
>> as 16. Both of them can be used as maximal M64 BAR number. Obviously, they're
>> duplicated. On the other hand, I don't think it's a good idea to have the static
>> "m64_map" because @pdn is created for every PCI devices, including VFs. non-PF
>> don't "m64_map", together other fields like "m64_per_iov" at all. It's obviously
>> wasting memory. So it would be allocated dynamically when the PF's pdn is created
>> or in pnv_pci_ioda_fixup_iov_resources().
>>
>
> I prefer the dynamic one.
>
> Alexey,
>
> I changed to static defined based on your comments. So do you have some
> concern on the dynamic version?
Is this map only valid for a VF and PF won't have/need one?
If so, yes, kmalloc() it.
>
>> In long run, it might be reasonable to move all SRIOV related fields in pci_dn
>> to another data struct (struct pci_iov_dn?) and allocate that dynamically.
>>
>>> int flags;
>>> #define PCI_DN_FLAG_IOV_VF 0x01
>>> @@ -214,10 +215,9 @@ struct pci_dn {
>>> u16 vfs_expanded; /* number of VFs IOV BAR expanded */
>>> u16 num_vfs; /* number of VFs enabled*/
>>> int offset; /* PE# for the first VF PE */
>>> -#define M64_PER_IOV 4
>>> - int m64_per_iov;
>>> + bool m64_single_mode; /* Use M64 BAR in Single Mode */
>>> #define IODA_INVALID_M64 (-1)
>>> - int m64_wins[PCI_SRIOV_NUM_BARS][M64_PER_IOV];
>>> + int m64_map[PCI_SRIOV_NUM_BARS][MAX_M64_BAR];
Is not here an extra space before "m64_map"?
Also the commit log does not explain why symbols were renamed (what since
you are renaming them - say a couple of words what they are).
>>> #endif /* CONFIG_PCI_IOV */
>>> #endif
>>> struct list_head child_list;
>>> diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
>>> index 67b8f72..4da0f50 100644
>>> --- a/arch/powerpc/platforms/powernv/pci-ioda.c
>>> +++ b/arch/powerpc/platforms/powernv/pci-ioda.c
>>> @@ -1162,15 +1162,14 @@ static int pnv_pci_vf_release_m64(struct pci_dev *pdev)
>>> pdn = pci_get_pdn(pdev);
>>>
>>> for (i = 0; i < PCI_SRIOV_NUM_BARS; i++)
>>> - for (j = 0; j < M64_PER_IOV; j++) {
>>> - if (pdn->m64_wins[i][j] == IODA_INVALID_M64)
>>> + for (j = 0; j < MAX_M64_BAR; j++) {
>>> + if (pdn->m64_map[i][j] == IODA_INVALID_M64)
>>> continue;
>>> opal_pci_phb_mmio_enable(phb->opal_id,
>>> - OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 0);
>>> - clear_bit(pdn->m64_wins[i][j], &phb->ioda.m64_bar_alloc);
>>> - pdn->m64_wins[i][j] = IODA_INVALID_M64;
>>> + OPAL_M64_WINDOW_TYPE, pdn->m64_map[i][j], 0);
>>> + clear_bit(pdn->m64_map[i][j], &phb->ioda.m64_bar_alloc);
>>> + pdn->m64_map[i][j] = IODA_INVALID_M64;
>>> }
>>> -
>>> return 0;
>>> }
>>>
>>> @@ -1187,8 +1186,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
>>> int total_vfs;
>>> resource_size_t size, start;
>>> int pe_num;
>>> - int vf_groups;
>>> - int vf_per_group;
>>> + int m64_bars;
>>>
>>> bus = pdev->bus;
>>> hose = pci_bus_to_host(bus);
>>> @@ -1196,26 +1194,23 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
>>> pdn = pci_get_pdn(pdev);
>>> total_vfs = pci_sriov_get_totalvfs(pdev);
>>>
>>> - /* Initialize the m64_wins to IODA_INVALID_M64 */
>>> - for (i = 0; i < PCI_SRIOV_NUM_BARS; i++)
>>> - for (j = 0; j < M64_PER_IOV; j++)
>>> - pdn->m64_wins[i][j] = IODA_INVALID_M64;
>>> + if (pdn->m64_single_mode)
>>> + m64_bars = num_vfs;
>>> + else
>>> + m64_bars = 1;
>>> +
>>> + /* Initialize the m64_map to IODA_INVALID_M64 */
>>> + for (i = 0; i < PCI_SRIOV_NUM_BARS ; i++)
>>> + for (j = 0; j < MAX_M64_BAR; j++)
>>> + pdn->m64_map[i][j] = IODA_INVALID_M64;
>>
>> It would be done in pnv_pci_ioda_fixup_iov_resources(). That means it will
>> be done for once if hotplug isn't considered. The code here will be called
>> on every attempt to enable SRIOV capability, which isn't necessary, right?
>>
>
> I think you are right.
>
>
--
Alexey
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v3 4/6] powerpc/powernv: replace the hard coded boundary with gate
2015-08-13 14:11 [PATCH v3 0/6] Redesign SR-IOV on PowerNV Wei Yang
` (2 preceding siblings ...)
2015-08-13 14:11 ` [PATCH v3 3/6] powerpc/powernv: use one M64 BAR in Single PE mode for one VF BAR Wei Yang
@ 2015-08-13 14:11 ` Wei Yang
2015-08-14 0:54 ` Gavin Shan
2015-08-15 10:27 ` Alexey Kardashevskiy
2015-08-13 14:11 ` [PATCH v3 5/6] powerpc/powernv: boundary the total VF BAR size instead of the individual one Wei Yang
2015-08-13 14:11 ` [PATCH v3 6/6] powerpc/powernv: allocate sparse PE# when using M64 BAR in Single PE mode Wei Yang
5 siblings, 2 replies; 22+ messages in thread
From: Wei Yang @ 2015-08-13 14:11 UTC (permalink / raw)
To: aik, gwshan, benh; +Cc: linuxppc-dev, Wei Yang
At the moment 64bit-prefetchable window can be maximum 64GB, which is
currently got from device tree. This means that in shared mode the maximum
supported VF BAR size is 64GB/256=256MB. While this size could exhaust the
whole 64bit-prefetchable window. This is a design decision to set a
boundary to 64MB of the VF BAR size. Since VF BAR size with 64MB would
occupy a quarter of the 64bit-prefetchable window, this is affordable.
This patch replaces magic limit of 64MB with (m64_segsize >> 1) and adds
comment to explain the reason for it.
Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
---
arch/powerpc/platforms/powernv/pci-ioda.c | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 4da0f50..3e8c0b4 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -2688,7 +2688,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
struct pnv_phb *phb;
struct resource *res;
int i;
- resource_size_t size;
+ resource_size_t size, gate;
struct pci_dn *pdn;
int mul, total_vfs;
@@ -2704,6 +2704,17 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
total_vfs = pci_sriov_get_totalvfs(pdev);
mul = phb->ioda.total_pe;
+ /*
+ * If bigger than or equal to half of M64 segment size, just round up
+ * power of two.
+ *
+ * Generally, one M64 BAR maps one IOV BAR. To avoid conflict with
+ * other devices, IOV BAR size is expanded to be (total_pe *
+ * VF_BAR_size). When VF_BAR_size is half of M64 segment size , the
+ * expanded size would equal to half of the whole M64 Space size,
+ * which will exhaust the M64 Space and limit the system flexibility.
+ */
+ gate = phb->ioda.m64_segsize >> 1;
for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
res = &pdev->resource[i + PCI_IOV_RESOURCES];
@@ -2718,10 +2729,11 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
- /* bigger than 64M */
- if (size > (1 << 26)) {
- dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size is bigger than 64M, roundup power2\n",
- i, res);
+ /* bigger than or equal to gate */
+ if (size >= gate) {
+ dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size "
+ "is bigger than %lld, roundup power2\n",
+ i, res, gate);
mul = roundup_pow_of_two(total_vfs);
pdn->m64_single_mode = true;
break;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v3 4/6] powerpc/powernv: replace the hard coded boundary with gate
2015-08-13 14:11 ` [PATCH v3 4/6] powerpc/powernv: replace the hard coded boundary with gate Wei Yang
@ 2015-08-14 0:54 ` Gavin Shan
2015-08-15 10:27 ` Alexey Kardashevskiy
1 sibling, 0 replies; 22+ messages in thread
From: Gavin Shan @ 2015-08-14 0:54 UTC (permalink / raw)
To: Wei Yang; +Cc: aik, gwshan, benh, linuxppc-dev
On Thu, Aug 13, 2015 at 10:11:09PM +0800, Wei Yang wrote:
>At the moment 64bit-prefetchable window can be maximum 64GB, which is
>currently got from device tree. This means that in shared mode the maximum
>supported VF BAR size is 64GB/256=256MB. While this size could exhaust the
>whole 64bit-prefetchable window. This is a design decision to set a
>boundary to 64MB of the VF BAR size. Since VF BAR size with 64MB would
>occupy a quarter of the 64bit-prefetchable window, this is affordable.
>
>This patch replaces magic limit of 64MB with (m64_segsize >> 1) and adds
>comment to explain the reason for it.
>
>Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
Reviewed-by: Gavin Shan <gwshan@linux.vent.ibm.com>
>---
> arch/powerpc/platforms/powernv/pci-ioda.c | 22 +++++++++++++++++-----
> 1 file changed, 17 insertions(+), 5 deletions(-)
>
>diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
>index 4da0f50..3e8c0b4 100644
>--- a/arch/powerpc/platforms/powernv/pci-ioda.c
>+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
>@@ -2688,7 +2688,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
> struct pnv_phb *phb;
> struct resource *res;
> int i;
>- resource_size_t size;
>+ resource_size_t size, gate;
> struct pci_dn *pdn;
> int mul, total_vfs;
>
>@@ -2704,6 +2704,17 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
>
> total_vfs = pci_sriov_get_totalvfs(pdev);
> mul = phb->ioda.total_pe;
>+ /*
>+ * If bigger than or equal to half of M64 segment size, just round up
>+ * power of two.
>+ *
>+ * Generally, one M64 BAR maps one IOV BAR. To avoid conflict with
>+ * other devices, IOV BAR size is expanded to be (total_pe *
>+ * VF_BAR_size). When VF_BAR_size is half of M64 segment size , the
>+ * expanded size would equal to half of the whole M64 Space size,
>+ * which will exhaust the M64 Space and limit the system flexibility.
>+ */
s/M64 Space/M64 space
>+ gate = phb->ioda.m64_segsize >> 1;
>
> for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
> res = &pdev->resource[i + PCI_IOV_RESOURCES];
>@@ -2718,10 +2729,11 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
>
> size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
>
>- /* bigger than 64M */
>- if (size > (1 << 26)) {
>- dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size is bigger than 64M, roundup power2\n",
>- i, res);
>+ /* bigger than or equal to gate */
>+ if (size >= gate) {
>+ dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size "
>+ "is bigger than %lld, roundup power2\n",
>+ i, res, gate);
> mul = roundup_pow_of_two(total_vfs);
> pdn->m64_single_mode = true;
> break;
>--
>1.7.9.5
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v3 4/6] powerpc/powernv: replace the hard coded boundary with gate
2015-08-13 14:11 ` [PATCH v3 4/6] powerpc/powernv: replace the hard coded boundary with gate Wei Yang
2015-08-14 0:54 ` Gavin Shan
@ 2015-08-15 10:27 ` Alexey Kardashevskiy
2015-08-17 2:21 ` Wei Yang
1 sibling, 1 reply; 22+ messages in thread
From: Alexey Kardashevskiy @ 2015-08-15 10:27 UTC (permalink / raw)
To: Wei Yang, gwshan, benh; +Cc: linuxppc-dev
On 08/14/2015 12:11 AM, Wei Yang wrote:
> At the moment 64bit-prefetchable window can be maximum 64GB, which is
> currently got from device tree. This means that in shared mode the maximum
> supported VF BAR size is 64GB/256=256MB. While this size could exhaust the
> whole 64bit-prefetchable window. This is a design decision to set a
> boundary to 64MB of the VF BAR size. Since VF BAR size with 64MB would
> occupy a quarter of the 64bit-prefetchable window, this is affordable.
>
> This patch replaces magic limit of 64MB with (m64_segsize >> 1) and adds
> comment to explain the reason for it.
Having m64_segsize divided in _halves_ is also magic (or is it a "design
decision"?).
>
> Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
> ---
> arch/powerpc/platforms/powernv/pci-ioda.c | 22 +++++++++++++++++-----
> 1 file changed, 17 insertions(+), 5 deletions(-)
>
> diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
> index 4da0f50..3e8c0b4 100644
> --- a/arch/powerpc/platforms/powernv/pci-ioda.c
> +++ b/arch/powerpc/platforms/powernv/pci-ioda.c
> @@ -2688,7 +2688,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
> struct pnv_phb *phb;
> struct resource *res;
> int i;
> - resource_size_t size;
> + resource_size_t size, gate;
It should be:
const resource_size_t gate = phb->ioda.m64_segsize >> 1;
as it never changes in the function.
> struct pci_dn *pdn;
> int mul, total_vfs;
>
> @@ -2704,6 +2704,17 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
>
> total_vfs = pci_sriov_get_totalvfs(pdev);
> mul = phb->ioda.total_pe;
> + /*
> + * If bigger than or equal to half of M64 segment size, just round up
> + * power of two.
> + *
> + * Generally, one M64 BAR maps one IOV BAR. To avoid conflict with
> + * other devices, IOV BAR size is expanded to be (total_pe *
> + * VF_BAR_size). When VF_BAR_size is half of M64 segment size , the
> + * expanded size would equal to half of the whole M64 Space size,
> + * which will exhaust the M64 Space and limit the system flexibility.
> + */
> + gate = phb->ioda.m64_segsize >> 1;
>
> for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
> res = &pdev->resource[i + PCI_IOV_RESOURCES];
> @@ -2718,10 +2729,11 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
>
> size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
>
> - /* bigger than 64M */
> - if (size > (1 << 26)) {
> - dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size is bigger than 64M, roundup power2\n",
> - i, res);
> + /* bigger than or equal to gate */
That multiline comment is better to be here, I think.
> + if (size >= gate) {
> + dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size "
> + "is bigger than %lld, roundup power2\n",
> + i, res, gate);
> mul = roundup_pow_of_two(total_vfs);
> pdn->m64_single_mode = true;
> break;
>
--
Alexey
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v3 4/6] powerpc/powernv: replace the hard coded boundary with gate
2015-08-15 10:27 ` Alexey Kardashevskiy
@ 2015-08-17 2:21 ` Wei Yang
0 siblings, 0 replies; 22+ messages in thread
From: Wei Yang @ 2015-08-17 2:21 UTC (permalink / raw)
To: Alexey Kardashevskiy; +Cc: Wei Yang, gwshan, benh, linuxppc-dev
On Sat, Aug 15, 2015 at 08:27:04PM +1000, Alexey Kardashevskiy wrote:
>On 08/14/2015 12:11 AM, Wei Yang wrote:
>>At the moment 64bit-prefetchable window can be maximum 64GB, which is
>>currently got from device tree. This means that in shared mode the maximum
>>supported VF BAR size is 64GB/256=256MB. While this size could exhaust the
>>whole 64bit-prefetchable window. This is a design decision to set a
>>boundary to 64MB of the VF BAR size. Since VF BAR size with 64MB would
>>occupy a quarter of the 64bit-prefetchable window, this is affordable.
>>
>>This patch replaces magic limit of 64MB with (m64_segsize >> 1) and adds
>>comment to explain the reason for it.
>
>
>Having m64_segsize divided in _halves_ is also magic (or is it a
>"design decision"?).
>
Hmm... as the last sentence in previous paragraph said, 64MB VF BAR would
occupy a quarter of the 64bit-prefetchable window which is affordable.
Maybe I could change to this:
This patch replaces magic limit of 64MB with "gate", which is 1/4 of the
M64 Segment Size(m64_segsize >> 2) and adds comment to explain the reason
for it.
This time I use (m64_segsize >> 2) instead of (m64_segsize >> 1), since I
decide to still use ">" instead of ">=". By doing so, the explanation in
commit log is consistent with the code.
>
>>
>>Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
>>---
>> arch/powerpc/platforms/powernv/pci-ioda.c | 22 +++++++++++++++++-----
>> 1 file changed, 17 insertions(+), 5 deletions(-)
>>
>>diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
>>index 4da0f50..3e8c0b4 100644
>>--- a/arch/powerpc/platforms/powernv/pci-ioda.c
>>+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
>>@@ -2688,7 +2688,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
>> struct pnv_phb *phb;
>> struct resource *res;
>> int i;
>>- resource_size_t size;
>>+ resource_size_t size, gate;
>
>It should be:
>const resource_size_t gate = phb->ioda.m64_segsize >> 1;
>
>as it never changes in the function.
Good.
>
>
>> struct pci_dn *pdn;
>> int mul, total_vfs;
>>
>>@@ -2704,6 +2704,17 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
>>
>> total_vfs = pci_sriov_get_totalvfs(pdev);
>> mul = phb->ioda.total_pe;
>>+ /*
>>+ * If bigger than or equal to half of M64 segment size, just round up
>>+ * power of two.
>>+ *
>>+ * Generally, one M64 BAR maps one IOV BAR. To avoid conflict with
>>+ * other devices, IOV BAR size is expanded to be (total_pe *
>>+ * VF_BAR_size). When VF_BAR_size is half of M64 segment size , the
>>+ * expanded size would equal to half of the whole M64 Space size,
>>+ * which will exhaust the M64 Space and limit the system flexibility.
>>+ */
>>+ gate = phb->ioda.m64_segsize >> 1;
>>
>> for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
>> res = &pdev->resource[i + PCI_IOV_RESOURCES];
>>@@ -2718,10 +2729,11 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
>>
>> size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
>>
>>- /* bigger than 64M */
>>- if (size > (1 << 26)) {
>>- dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size is bigger than 64M, roundup power2\n",
>>- i, res);
>>+ /* bigger than or equal to gate */
>
>
>That multiline comment is better to be here, I think.
>
As you wish.
>
>>+ if (size >= gate) {
>>+ dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size "
>>+ "is bigger than %lld, roundup power2\n",
>>+ i, res, gate);
>> mul = roundup_pow_of_two(total_vfs);
>> pdn->m64_single_mode = true;
>> break;
>>
>
>
>--
>Alexey
--
Richard Yang
Help you, Help me
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v3 5/6] powerpc/powernv: boundary the total VF BAR size instead of the individual one
2015-08-13 14:11 [PATCH v3 0/6] Redesign SR-IOV on PowerNV Wei Yang
` (3 preceding siblings ...)
2015-08-13 14:11 ` [PATCH v3 4/6] powerpc/powernv: replace the hard coded boundary with gate Wei Yang
@ 2015-08-13 14:11 ` Wei Yang
2015-08-14 0:57 ` Gavin Shan
2015-08-13 14:11 ` [PATCH v3 6/6] powerpc/powernv: allocate sparse PE# when using M64 BAR in Single PE mode Wei Yang
5 siblings, 1 reply; 22+ messages in thread
From: Wei Yang @ 2015-08-13 14:11 UTC (permalink / raw)
To: aik, gwshan, benh; +Cc: linuxppc-dev, Wei Yang
Each VF could have 6 BARs at most. When the total BAR size exceeds the
gate, after expanding it will also exhaust the M64 Window.
This patch limits the boundary by checking the total VF BAR size instead of
the individual BAR.
Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
---
arch/powerpc/platforms/powernv/pci-ioda.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 3e8c0b4..1e6ac86 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -2688,7 +2688,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
struct pnv_phb *phb;
struct resource *res;
int i;
- resource_size_t size, gate;
+ resource_size_t size, gate, total_vf_bar_sz;
struct pci_dn *pdn;
int mul, total_vfs;
@@ -2715,6 +2715,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
* which will exhaust the M64 Space and limit the system flexibility.
*/
gate = phb->ioda.m64_segsize >> 1;
+ total_vf_bar_sz = 0;
for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
res = &pdev->resource[i + PCI_IOV_RESOURCES];
@@ -2727,13 +2728,13 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
return;
}
- size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
+ total_vf_bar_sz += pci_iov_resource_size(pdev,
+ i + PCI_IOV_RESOURCES);
/* bigger than or equal to gate */
- if (size >= gate) {
- dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size "
- "is bigger than %lld, roundup power2\n",
- i, res, gate);
+ if (total_vf_bar_sz >= gate) {
+ dev_info(&pdev->dev, "PowerNV: VF BAR Total IOV size "
+ "is bigger than %lld, roundup power2\n", gate);
mul = roundup_pow_of_two(total_vfs);
pdn->m64_single_mode = true;
break;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v3 5/6] powerpc/powernv: boundary the total VF BAR size instead of the individual one
2015-08-13 14:11 ` [PATCH v3 5/6] powerpc/powernv: boundary the total VF BAR size instead of the individual one Wei Yang
@ 2015-08-14 0:57 ` Gavin Shan
2015-08-15 10:21 ` Alexey Kardashevskiy
0 siblings, 1 reply; 22+ messages in thread
From: Gavin Shan @ 2015-08-14 0:57 UTC (permalink / raw)
To: Wei Yang; +Cc: aik, gwshan, benh, linuxppc-dev
On Thu, Aug 13, 2015 at 10:11:10PM +0800, Wei Yang wrote:
>Each VF could have 6 BARs at most. When the total BAR size exceeds the
>gate, after expanding it will also exhaust the M64 Window.
>
>This patch limits the boundary by checking the total VF BAR size instead of
>the individual BAR.
>
>Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
Reviewed-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
>---
> arch/powerpc/platforms/powernv/pci-ioda.c | 13 +++++++------
> 1 file changed, 7 insertions(+), 6 deletions(-)
>
>diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
>index 3e8c0b4..1e6ac86 100644
>--- a/arch/powerpc/platforms/powernv/pci-ioda.c
>+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
>@@ -2688,7 +2688,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
> struct pnv_phb *phb;
> struct resource *res;
> int i;
>- resource_size_t size, gate;
>+ resource_size_t size, gate, total_vf_bar_sz;
> struct pci_dn *pdn;
> int mul, total_vfs;
>
>@@ -2715,6 +2715,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
> * which will exhaust the M64 Space and limit the system flexibility.
> */
> gate = phb->ioda.m64_segsize >> 1;
>+ total_vf_bar_sz = 0;
>
> for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
> res = &pdev->resource[i + PCI_IOV_RESOURCES];
>@@ -2727,13 +2728,13 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
> return;
> }
>
>- size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
>+ total_vf_bar_sz += pci_iov_resource_size(pdev,
>+ i + PCI_IOV_RESOURCES);
>
> /* bigger than or equal to gate */
>- if (size >= gate) {
>- dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size "
>- "is bigger than %lld, roundup power2\n",
>- i, res, gate);
>+ if (total_vf_bar_sz >= gate) {
>+ dev_info(&pdev->dev, "PowerNV: VF BAR Total IOV size "
>+ "is bigger than %lld, roundup power2\n", gate);
dev_info(&pdev->dev, "PowerNV: Total VF BAR size %lld "
"is bigger than %lld, roundup power2\n",
total_vf_bar_sz, gate);
> mul = roundup_pow_of_two(total_vfs);
> pdn->m64_single_mode = true;
> break;
>--
>1.7.9.5
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v3 5/6] powerpc/powernv: boundary the total VF BAR size instead of the individual one
2015-08-14 0:57 ` Gavin Shan
@ 2015-08-15 10:21 ` Alexey Kardashevskiy
0 siblings, 0 replies; 22+ messages in thread
From: Alexey Kardashevskiy @ 2015-08-15 10:21 UTC (permalink / raw)
To: Gavin Shan, Wei Yang; +Cc: benh, linuxppc-dev
On 08/14/2015 10:57 AM, Gavin Shan wrote:
> On Thu, Aug 13, 2015 at 10:11:10PM +0800, Wei Yang wrote:
>> Each VF could have 6 BARs at most. When the total BAR size exceeds the
>> gate, after expanding it will also exhaust the M64 Window.
>>
>> This patch limits the boundary by checking the total VF BAR size instead of
>> the individual BAR.
>>
>> Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
>
> Reviewed-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
>
>> ---
>> arch/powerpc/platforms/powernv/pci-ioda.c | 13 +++++++------
>> 1 file changed, 7 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
>> index 3e8c0b4..1e6ac86 100644
>> --- a/arch/powerpc/platforms/powernv/pci-ioda.c
>> +++ b/arch/powerpc/platforms/powernv/pci-ioda.c
>> @@ -2688,7 +2688,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
>> struct pnv_phb *phb;
>> struct resource *res;
>> int i;
>> - resource_size_t size, gate;
>> + resource_size_t size, gate, total_vf_bar_sz;
>> struct pci_dn *pdn;
>> int mul, total_vfs;
>>
>> @@ -2715,6 +2715,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
>> * which will exhaust the M64 Space and limit the system flexibility.
>> */
>> gate = phb->ioda.m64_segsize >> 1;
>> + total_vf_bar_sz = 0;
>>
>> for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
>> res = &pdev->resource[i + PCI_IOV_RESOURCES];
>> @@ -2727,13 +2728,13 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
>> return;
>> }
>>
>> - size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
>> + total_vf_bar_sz += pci_iov_resource_size(pdev,
>> + i + PCI_IOV_RESOURCES);
>>
>> /* bigger than or equal to gate */
>> - if (size >= gate) {
>> - dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size "
>> - "is bigger than %lld, roundup power2\n",
>> - i, res, gate);
>> + if (total_vf_bar_sz >= gate) {
>> + dev_info(&pdev->dev, "PowerNV: VF BAR Total IOV size "
>> + "is bigger than %lld, roundup power2\n", gate);
>
> dev_info(&pdev->dev, "PowerNV: Total VF BAR size %lld "
> "is bigger than %lld, roundup power2\n",
> total_vf_bar_sz, gate);
Please do not split user visible lines, the 80 chars rule does not apply
for string constants. But since we are still better not to go too far from
80 symbols, remove ", roundup power2" or make the message shorter somehow
else. Like:
dev_info(&pdev->dev,
"PowerNV: Total VF BAR size %lld > %lld, roundup to %lld\n",
total_vf_bar_sz, gate, mul);
and move it after roundup_pow_of_two() call.
And "PowerNV" prefix does not seem necessary either (it is not used very
often and even without the prefix it is quite obvious that this is powernv
and you could still grep for this message in the kernel source tree).
>
>> mul = roundup_pow_of_two(total_vfs);
>> pdn->m64_single_mode = true;
>> break;
>> --
>> 1.7.9.5
>>
>
--
Alexey
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v3 6/6] powerpc/powernv: allocate sparse PE# when using M64 BAR in Single PE mode
2015-08-13 14:11 [PATCH v3 0/6] Redesign SR-IOV on PowerNV Wei Yang
` (4 preceding siblings ...)
2015-08-13 14:11 ` [PATCH v3 5/6] powerpc/powernv: boundary the total VF BAR size instead of the individual one Wei Yang
@ 2015-08-13 14:11 ` Wei Yang
2015-08-14 1:03 ` Gavin Shan
5 siblings, 1 reply; 22+ messages in thread
From: Wei Yang @ 2015-08-13 14:11 UTC (permalink / raw)
To: aik, gwshan, benh; +Cc: linuxppc-dev, Wei Yang
When M64 BAR is set to Single PE mode, the PE# assigned to VF could be
sparse.
This patch restructures the patch to allocate sparse PE# for VFs when M64
BAR is set to Single PE mode.
Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/pci-bridge.h | 2 +-
arch/powerpc/platforms/powernv/pci-ioda.c | 59 +++++++++++++++++++----------
2 files changed, 41 insertions(+), 20 deletions(-)
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 9d33ada..b026ef8 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -214,7 +214,7 @@ struct pci_dn {
#ifdef CONFIG_PCI_IOV
u16 vfs_expanded; /* number of VFs IOV BAR expanded */
u16 num_vfs; /* number of VFs enabled*/
- int offset; /* PE# for the first VF PE */
+ int pe_num_map[MAX_M64_BAR];/* PE# for the first VF PE or array */
bool m64_single_mode; /* Use M64 BAR in Single Mode */
#define IODA_INVALID_M64 (-1)
int m64_map[PCI_SRIOV_NUM_BARS][MAX_M64_BAR];
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 1e6ac86..7633538 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1232,7 +1232,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
/* Map the M64 here */
if (pdn->m64_single_mode) {
- pe_num = pdn->offset + j;
+ pe_num = pdn->pe_num_map[j];
rc = opal_pci_map_pe_mmio_window(phb->opal_id,
pe_num, OPAL_M64_WINDOW_TYPE,
pdn->m64_map[i][j], 0);
@@ -1336,7 +1336,7 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev)
struct pnv_phb *phb;
struct pci_dn *pdn;
struct pci_sriov *iov;
- u16 num_vfs;
+ u16 num_vfs, i;
bus = pdev->bus;
hose = pci_bus_to_host(bus);
@@ -1350,14 +1350,17 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev)
if (phb->type == PNV_PHB_IODA2) {
if (!pdn->m64_single_mode)
- pnv_pci_vf_resource_shift(pdev, -pdn->offset);
+ pnv_pci_vf_resource_shift(pdev, -pdn->pe_num_map[0]);
/* Release M64 windows */
pnv_pci_vf_release_m64(pdev);
/* Release PE numbers */
- bitmap_clear(phb->ioda.pe_alloc, pdn->offset, num_vfs);
- pdn->offset = 0;
+ if (pdn->m64_single_mode) {
+ for (i = 0; i < num_vfs; i++)
+ pnv_ioda_free_pe(phb, pdn->pe_num_map[i]);
+ } else
+ bitmap_clear(phb->ioda.pe_alloc, pdn->pe_num_map[0], num_vfs);
}
}
@@ -1383,7 +1386,10 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)
/* Reserve PE for each VF */
for (vf_index = 0; vf_index < num_vfs; vf_index++) {
- pe_num = pdn->offset + vf_index;
+ if (pdn->m64_single_mode)
+ pe_num = pdn->pe_num_map[vf_index];
+ else
+ pe_num = pdn->pe_num_map[0] + vf_index;
pe = &phb->ioda.pe_array[pe_num];
pe->pe_number = pe_num;
@@ -1425,6 +1431,7 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
struct pnv_phb *phb;
struct pci_dn *pdn;
int ret;
+ u16 i;
bus = pdev->bus;
hose = pci_bus_to_host(bus);
@@ -1448,19 +1455,30 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
}
/* Calculate available PE for required VFs */
- mutex_lock(&phb->ioda.pe_alloc_mutex);
- pdn->offset = bitmap_find_next_zero_area(
- phb->ioda.pe_alloc, phb->ioda.total_pe,
- 0, num_vfs, 0);
- if (pdn->offset >= phb->ioda.total_pe) {
+ if (pdn->m64_single_mode) {
+ for (i = 0; i < num_vfs; i++)
+ pdn->pe_num_map[i] = IODA_INVALID_PE;
+ for (i = 0; i < num_vfs; i++) {
+ pdn->pe_num_map[i] = pnv_ioda_alloc_pe(phb);
+ if (pdn->pe_num_map[i] == IODA_INVALID_PE) {
+ ret = -EBUSY;
+ goto m64_failed;
+ }
+ }
+ } else {
+ mutex_lock(&phb->ioda.pe_alloc_mutex);
+ pdn->pe_num_map[0] = bitmap_find_next_zero_area(
+ phb->ioda.pe_alloc, phb->ioda.total_pe,
+ 0, num_vfs, 0);
+ if (pdn->pe_num_map[0] >= phb->ioda.total_pe) {
+ mutex_unlock(&phb->ioda.pe_alloc_mutex);
+ dev_info(&pdev->dev, "Failed to enable VF%d\n", num_vfs);
+ return -EBUSY;
+ }
+ bitmap_set(phb->ioda.pe_alloc, pdn->pe_num_map[0], num_vfs);
mutex_unlock(&phb->ioda.pe_alloc_mutex);
- dev_info(&pdev->dev, "Failed to enable VF%d\n", num_vfs);
- pdn->offset = 0;
- return -EBUSY;
}
- bitmap_set(phb->ioda.pe_alloc, pdn->offset, num_vfs);
pdn->num_vfs = num_vfs;
- mutex_unlock(&phb->ioda.pe_alloc_mutex);
/* Assign M64 window accordingly */
ret = pnv_pci_vf_assign_m64(pdev, num_vfs);
@@ -1475,7 +1493,7 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
* Otherwise, the PE# for the VF will conflict with others.
*/
if (!pdn->m64_single_mode) {
- ret = pnv_pci_vf_resource_shift(pdev, pdn->offset);
+ ret = pnv_pci_vf_resource_shift(pdev, pdn->pe_num_map[0]);
if (ret)
goto m64_failed;
}
@@ -1487,8 +1505,11 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
return 0;
m64_failed:
- bitmap_clear(phb->ioda.pe_alloc, pdn->offset, num_vfs);
- pdn->offset = 0;
+ if (pdn->m64_single_mode) {
+ for (i = 0; i < num_vfs; i++)
+ pnv_ioda_free_pe(phb, pdn->pe_num_map[i]);
+ } else
+ bitmap_clear(phb->ioda.pe_alloc, pdn->pe_num_map[0], num_vfs);
return ret;
}
--
1.7.9.5
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v3 6/6] powerpc/powernv: allocate sparse PE# when using M64 BAR in Single PE mode
2015-08-13 14:11 ` [PATCH v3 6/6] powerpc/powernv: allocate sparse PE# when using M64 BAR in Single PE mode Wei Yang
@ 2015-08-14 1:03 ` Gavin Shan
2015-08-14 3:57 ` Wei Yang
2015-08-15 10:27 ` Alexey Kardashevskiy
0 siblings, 2 replies; 22+ messages in thread
From: Gavin Shan @ 2015-08-14 1:03 UTC (permalink / raw)
To: Wei Yang; +Cc: aik, gwshan, benh, linuxppc-dev
On Thu, Aug 13, 2015 at 10:11:11PM +0800, Wei Yang wrote:
>When M64 BAR is set to Single PE mode, the PE# assigned to VF could be
>sparse.
>
>This patch restructures the patch to allocate sparse PE# for VFs when M64
>BAR is set to Single PE mode.
>
>Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
>---
> arch/powerpc/include/asm/pci-bridge.h | 2 +-
> arch/powerpc/platforms/powernv/pci-ioda.c | 59 +++++++++++++++++++----------
> 2 files changed, 41 insertions(+), 20 deletions(-)
>
>diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
>index 9d33ada..b026ef8 100644
>--- a/arch/powerpc/include/asm/pci-bridge.h
>+++ b/arch/powerpc/include/asm/pci-bridge.h
>@@ -214,7 +214,7 @@ struct pci_dn {
> #ifdef CONFIG_PCI_IOV
> u16 vfs_expanded; /* number of VFs IOV BAR expanded */
> u16 num_vfs; /* number of VFs enabled*/
>- int offset; /* PE# for the first VF PE */
>+ int pe_num_map[MAX_M64_BAR];/* PE# for the first VF PE or array */
Same question as to "m64_map". pdn for non-PF doesn't need it.
> bool m64_single_mode; /* Use M64 BAR in Single Mode */
> #define IODA_INVALID_M64 (-1)
> int m64_map[PCI_SRIOV_NUM_BARS][MAX_M64_BAR];
>diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
>index 1e6ac86..7633538 100644
>--- a/arch/powerpc/platforms/powernv/pci-ioda.c
>+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
>@@ -1232,7 +1232,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
>
> /* Map the M64 here */
> if (pdn->m64_single_mode) {
>- pe_num = pdn->offset + j;
>+ pe_num = pdn->pe_num_map[j];
> rc = opal_pci_map_pe_mmio_window(phb->opal_id,
> pe_num, OPAL_M64_WINDOW_TYPE,
> pdn->m64_map[i][j], 0);
>@@ -1336,7 +1336,7 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev)
> struct pnv_phb *phb;
> struct pci_dn *pdn;
> struct pci_sriov *iov;
>- u16 num_vfs;
>+ u16 num_vfs, i;
>
> bus = pdev->bus;
> hose = pci_bus_to_host(bus);
>@@ -1350,14 +1350,17 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev)
>
> if (phb->type == PNV_PHB_IODA2) {
> if (!pdn->m64_single_mode)
>- pnv_pci_vf_resource_shift(pdev, -pdn->offset);
>+ pnv_pci_vf_resource_shift(pdev, -pdn->pe_num_map[0]);
>
> /* Release M64 windows */
> pnv_pci_vf_release_m64(pdev);
>
> /* Release PE numbers */
>- bitmap_clear(phb->ioda.pe_alloc, pdn->offset, num_vfs);
>- pdn->offset = 0;
>+ if (pdn->m64_single_mode) {
>+ for (i = 0; i < num_vfs; i++)
>+ pnv_ioda_free_pe(phb, pdn->pe_num_map[i]);
>+ } else
>+ bitmap_clear(phb->ioda.pe_alloc, pdn->pe_num_map[0], num_vfs);
> }
> }
>
>@@ -1383,7 +1386,10 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)
>
> /* Reserve PE for each VF */
> for (vf_index = 0; vf_index < num_vfs; vf_index++) {
>- pe_num = pdn->offset + vf_index;
>+ if (pdn->m64_single_mode)
>+ pe_num = pdn->pe_num_map[vf_index];
>+ else
>+ pe_num = pdn->pe_num_map[0] + vf_index;
>
> pe = &phb->ioda.pe_array[pe_num];
> pe->pe_number = pe_num;
>@@ -1425,6 +1431,7 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
> struct pnv_phb *phb;
> struct pci_dn *pdn;
> int ret;
>+ u16 i;
>
> bus = pdev->bus;
> hose = pci_bus_to_host(bus);
>@@ -1448,19 +1455,30 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
> }
>
> /* Calculate available PE for required VFs */
>- mutex_lock(&phb->ioda.pe_alloc_mutex);
>- pdn->offset = bitmap_find_next_zero_area(
>- phb->ioda.pe_alloc, phb->ioda.total_pe,
>- 0, num_vfs, 0);
>- if (pdn->offset >= phb->ioda.total_pe) {
>+ if (pdn->m64_single_mode) {
>+ for (i = 0; i < num_vfs; i++)
>+ pdn->pe_num_map[i] = IODA_INVALID_PE;
>+ for (i = 0; i < num_vfs; i++) {
>+ pdn->pe_num_map[i] = pnv_ioda_alloc_pe(phb);
>+ if (pdn->pe_num_map[i] == IODA_INVALID_PE) {
>+ ret = -EBUSY;
>+ goto m64_failed;
>+ }
>+ }
>+ } else {
>+ mutex_lock(&phb->ioda.pe_alloc_mutex);
>+ pdn->pe_num_map[0] = bitmap_find_next_zero_area(
>+ phb->ioda.pe_alloc, phb->ioda.total_pe,
>+ 0, num_vfs, 0);
>+ if (pdn->pe_num_map[0] >= phb->ioda.total_pe) {
>+ mutex_unlock(&phb->ioda.pe_alloc_mutex);
>+ dev_info(&pdev->dev, "Failed to enable VF%d\n", num_vfs);
>+ return -EBUSY;
>+ }
>+ bitmap_set(phb->ioda.pe_alloc, pdn->pe_num_map[0], num_vfs);
> mutex_unlock(&phb->ioda.pe_alloc_mutex);
>- dev_info(&pdev->dev, "Failed to enable VF%d\n", num_vfs);
>- pdn->offset = 0;
>- return -EBUSY;
> }
>- bitmap_set(phb->ioda.pe_alloc, pdn->offset, num_vfs);
> pdn->num_vfs = num_vfs;
>- mutex_unlock(&phb->ioda.pe_alloc_mutex);
>
> /* Assign M64 window accordingly */
> ret = pnv_pci_vf_assign_m64(pdev, num_vfs);
>@@ -1475,7 +1493,7 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
> * Otherwise, the PE# for the VF will conflict with others.
> */
> if (!pdn->m64_single_mode) {
>- ret = pnv_pci_vf_resource_shift(pdev, pdn->offset);
>+ ret = pnv_pci_vf_resource_shift(pdev, pdn->pe_num_map[0]);
> if (ret)
> goto m64_failed;
> }
>@@ -1487,8 +1505,11 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
> return 0;
>
> m64_failed:
>- bitmap_clear(phb->ioda.pe_alloc, pdn->offset, num_vfs);
>- pdn->offset = 0;
>+ if (pdn->m64_single_mode) {
>+ for (i = 0; i < num_vfs; i++)
>+ pnv_ioda_free_pe(phb, pdn->pe_num_map[i]);
if pdn->pe_num_map[i] isn't valid PE number, what will happen?
>+ } else
>+ bitmap_clear(phb->ioda.pe_alloc, pdn->pe_num_map[0], num_vfs);
>
> return ret;
> }
>--
>1.7.9.5
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v3 6/6] powerpc/powernv: allocate sparse PE# when using M64 BAR in Single PE mode
2015-08-14 1:03 ` Gavin Shan
@ 2015-08-14 3:57 ` Wei Yang
2015-08-15 10:27 ` Alexey Kardashevskiy
1 sibling, 0 replies; 22+ messages in thread
From: Wei Yang @ 2015-08-14 3:57 UTC (permalink / raw)
To: Gavin Shan; +Cc: Wei Yang, aik, benh, linuxppc-dev
On Fri, Aug 14, 2015 at 11:03:00AM +1000, Gavin Shan wrote:
>On Thu, Aug 13, 2015 at 10:11:11PM +0800, Wei Yang wrote:
>>When M64 BAR is set to Single PE mode, the PE# assigned to VF could be
>>sparse.
>>
>>This patch restructures the patch to allocate sparse PE# for VFs when M64
>>BAR is set to Single PE mode.
>>
>>Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
>>---
>> arch/powerpc/include/asm/pci-bridge.h | 2 +-
>> arch/powerpc/platforms/powernv/pci-ioda.c | 59 +++++++++++++++++++----------
>> 2 files changed, 41 insertions(+), 20 deletions(-)
>>
>>diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
>>index 9d33ada..b026ef8 100644
>>--- a/arch/powerpc/include/asm/pci-bridge.h
>>+++ b/arch/powerpc/include/asm/pci-bridge.h
>>@@ -214,7 +214,7 @@ struct pci_dn {
>> #ifdef CONFIG_PCI_IOV
>> u16 vfs_expanded; /* number of VFs IOV BAR expanded */
>> u16 num_vfs; /* number of VFs enabled*/
>>- int offset; /* PE# for the first VF PE */
>>+ int pe_num_map[MAX_M64_BAR];/* PE# for the first VF PE or array */
>
>Same question as to "m64_map". pdn for non-PF doesn't need it.
>
The same, I prefer the dynamic version.
>> bool m64_single_mode; /* Use M64 BAR in Single Mode */
>> #define IODA_INVALID_M64 (-1)
>> int m64_map[PCI_SRIOV_NUM_BARS][MAX_M64_BAR];
>>diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
>>index 1e6ac86..7633538 100644
>>--- a/arch/powerpc/platforms/powernv/pci-ioda.c
>>+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
>>@@ -1232,7 +1232,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
>>
>> /* Map the M64 here */
>> if (pdn->m64_single_mode) {
>>- pe_num = pdn->offset + j;
>>+ pe_num = pdn->pe_num_map[j];
>> rc = opal_pci_map_pe_mmio_window(phb->opal_id,
>> pe_num, OPAL_M64_WINDOW_TYPE,
>> pdn->m64_map[i][j], 0);
>>@@ -1336,7 +1336,7 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev)
>> struct pnv_phb *phb;
>> struct pci_dn *pdn;
>> struct pci_sriov *iov;
>>- u16 num_vfs;
>>+ u16 num_vfs, i;
>>
>> bus = pdev->bus;
>> hose = pci_bus_to_host(bus);
>>@@ -1350,14 +1350,17 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev)
>>
>> if (phb->type == PNV_PHB_IODA2) {
>> if (!pdn->m64_single_mode)
>>- pnv_pci_vf_resource_shift(pdev, -pdn->offset);
>>+ pnv_pci_vf_resource_shift(pdev, -pdn->pe_num_map[0]);
>>
>> /* Release M64 windows */
>> pnv_pci_vf_release_m64(pdev);
>>
>> /* Release PE numbers */
>>- bitmap_clear(phb->ioda.pe_alloc, pdn->offset, num_vfs);
>>- pdn->offset = 0;
>>+ if (pdn->m64_single_mode) {
>>+ for (i = 0; i < num_vfs; i++)
>>+ pnv_ioda_free_pe(phb, pdn->pe_num_map[i]);
>>+ } else
>>+ bitmap_clear(phb->ioda.pe_alloc, pdn->pe_num_map[0], num_vfs);
>> }
>> }
>>
>>@@ -1383,7 +1386,10 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)
>>
>> /* Reserve PE for each VF */
>> for (vf_index = 0; vf_index < num_vfs; vf_index++) {
>>- pe_num = pdn->offset + vf_index;
>>+ if (pdn->m64_single_mode)
>>+ pe_num = pdn->pe_num_map[vf_index];
>>+ else
>>+ pe_num = pdn->pe_num_map[0] + vf_index;
>>
>> pe = &phb->ioda.pe_array[pe_num];
>> pe->pe_number = pe_num;
>>@@ -1425,6 +1431,7 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
>> struct pnv_phb *phb;
>> struct pci_dn *pdn;
>> int ret;
>>+ u16 i;
>>
>> bus = pdev->bus;
>> hose = pci_bus_to_host(bus);
>>@@ -1448,19 +1455,30 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
>> }
>>
>> /* Calculate available PE for required VFs */
>>- mutex_lock(&phb->ioda.pe_alloc_mutex);
>>- pdn->offset = bitmap_find_next_zero_area(
>>- phb->ioda.pe_alloc, phb->ioda.total_pe,
>>- 0, num_vfs, 0);
>>- if (pdn->offset >= phb->ioda.total_pe) {
>>+ if (pdn->m64_single_mode) {
>>+ for (i = 0; i < num_vfs; i++)
>>+ pdn->pe_num_map[i] = IODA_INVALID_PE;
>>+ for (i = 0; i < num_vfs; i++) {
>>+ pdn->pe_num_map[i] = pnv_ioda_alloc_pe(phb);
>>+ if (pdn->pe_num_map[i] == IODA_INVALID_PE) {
>>+ ret = -EBUSY;
>>+ goto m64_failed;
>>+ }
>>+ }
>>+ } else {
>>+ mutex_lock(&phb->ioda.pe_alloc_mutex);
>>+ pdn->pe_num_map[0] = bitmap_find_next_zero_area(
>>+ phb->ioda.pe_alloc, phb->ioda.total_pe,
>>+ 0, num_vfs, 0);
>>+ if (pdn->pe_num_map[0] >= phb->ioda.total_pe) {
>>+ mutex_unlock(&phb->ioda.pe_alloc_mutex);
>>+ dev_info(&pdev->dev, "Failed to enable VF%d\n", num_vfs);
>>+ return -EBUSY;
>>+ }
>>+ bitmap_set(phb->ioda.pe_alloc, pdn->pe_num_map[0], num_vfs);
>> mutex_unlock(&phb->ioda.pe_alloc_mutex);
>>- dev_info(&pdev->dev, "Failed to enable VF%d\n", num_vfs);
>>- pdn->offset = 0;
>>- return -EBUSY;
>> }
>>- bitmap_set(phb->ioda.pe_alloc, pdn->offset, num_vfs);
>> pdn->num_vfs = num_vfs;
>>- mutex_unlock(&phb->ioda.pe_alloc_mutex);
>>
>> /* Assign M64 window accordingly */
>> ret = pnv_pci_vf_assign_m64(pdev, num_vfs);
>>@@ -1475,7 +1493,7 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
>> * Otherwise, the PE# for the VF will conflict with others.
>> */
>> if (!pdn->m64_single_mode) {
>>- ret = pnv_pci_vf_resource_shift(pdev, pdn->offset);
>>+ ret = pnv_pci_vf_resource_shift(pdev, pdn->pe_num_map[0]);
>> if (ret)
>> goto m64_failed;
>> }
>>@@ -1487,8 +1505,11 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
>> return 0;
>>
>> m64_failed:
>>- bitmap_clear(phb->ioda.pe_alloc, pdn->offset, num_vfs);
>>- pdn->offset = 0;
>>+ if (pdn->m64_single_mode) {
>>+ for (i = 0; i < num_vfs; i++)
>>+ pnv_ioda_free_pe(phb, pdn->pe_num_map[i]);
>
>if pdn->pe_num_map[i] isn't valid PE number, what will happen?
>
You are right, we need to check this.
>>+ } else
>>+ bitmap_clear(phb->ioda.pe_alloc, pdn->pe_num_map[0], num_vfs);
>>
>> return ret;
>> }
>>--
>>1.7.9.5
>>
--
Richard Yang
Help you, Help me
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v3 6/6] powerpc/powernv: allocate sparse PE# when using M64 BAR in Single PE mode
2015-08-14 1:03 ` Gavin Shan
2015-08-14 3:57 ` Wei Yang
@ 2015-08-15 10:27 ` Alexey Kardashevskiy
2015-08-15 23:28 ` Gavin Shan
1 sibling, 1 reply; 22+ messages in thread
From: Alexey Kardashevskiy @ 2015-08-15 10:27 UTC (permalink / raw)
To: Gavin Shan, Wei Yang; +Cc: benh, linuxppc-dev
On 08/14/2015 11:03 AM, Gavin Shan wrote:
> On Thu, Aug 13, 2015 at 10:11:11PM +0800, Wei Yang wrote:
>> When M64 BAR is set to Single PE mode, the PE# assigned to VF could be
>> sparse.
>>
>> This patch restructures the patch to allocate sparse PE# for VFs when M64
>> BAR is set to Single PE mode.
>>
>> Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
>> ---
>> arch/powerpc/include/asm/pci-bridge.h | 2 +-
>> arch/powerpc/platforms/powernv/pci-ioda.c | 59 +++++++++++++++++++----------
>> 2 files changed, 41 insertions(+), 20 deletions(-)
>>
>> diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
>> index 9d33ada..b026ef8 100644
>> --- a/arch/powerpc/include/asm/pci-bridge.h
>> +++ b/arch/powerpc/include/asm/pci-bridge.h
>> @@ -214,7 +214,7 @@ struct pci_dn {
>> #ifdef CONFIG_PCI_IOV
>> u16 vfs_expanded; /* number of VFs IOV BAR expanded */
>> u16 num_vfs; /* number of VFs enabled*/
>> - int offset; /* PE# for the first VF PE */
>> + int pe_num_map[MAX_M64_BAR];/* PE# for the first VF PE or array */
>
> Same question as to "m64_map". pdn for non-PF doesn't need it.
non-PF is VF, right?
--
Alexey
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v3 6/6] powerpc/powernv: allocate sparse PE# when using M64 BAR in Single PE mode
2015-08-15 10:27 ` Alexey Kardashevskiy
@ 2015-08-15 23:28 ` Gavin Shan
0 siblings, 0 replies; 22+ messages in thread
From: Gavin Shan @ 2015-08-15 23:28 UTC (permalink / raw)
To: Alexey Kardashevskiy; +Cc: Gavin Shan, Wei Yang, benh, linuxppc-dev
On Sat, Aug 15, 2015 at 08:27:54PM +1000, Alexey Kardashevskiy wrote:
>On 08/14/2015 11:03 AM, Gavin Shan wrote:
>>On Thu, Aug 13, 2015 at 10:11:11PM +0800, Wei Yang wrote:
>>>When M64 BAR is set to Single PE mode, the PE# assigned to VF could be
>>>sparse.
>>>
>>>This patch restructures the patch to allocate sparse PE# for VFs when M64
>>>BAR is set to Single PE mode.
>>>
>>>Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
>>>---
>>>arch/powerpc/include/asm/pci-bridge.h | 2 +-
>>>arch/powerpc/platforms/powernv/pci-ioda.c | 59 +++++++++++++++++++----------
>>>2 files changed, 41 insertions(+), 20 deletions(-)
>>>
>>>diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
>>>index 9d33ada..b026ef8 100644
>>>--- a/arch/powerpc/include/asm/pci-bridge.h
>>>+++ b/arch/powerpc/include/asm/pci-bridge.h
>>>@@ -214,7 +214,7 @@ struct pci_dn {
>>>#ifdef CONFIG_PCI_IOV
>>> u16 vfs_expanded; /* number of VFs IOV BAR expanded */
>>> u16 num_vfs; /* number of VFs enabled*/
>>>- int offset; /* PE# for the first VF PE */
>>>+ int pe_num_map[MAX_M64_BAR];/* PE# for the first VF PE or array */
>>
>>Same question as to "m64_map". pdn for non-PF doesn't need it.
>
>
>non-PF is VF, right?
>
3 types of devices: (A) PF (B) VF (C) All others. Here, I mean (C).
Thanks,
Gavin
^ permalink raw reply [flat|nested] 22+ messages in thread