Re: [PATCH] powerpc/powernv: use one M64 BAR in Single PE mode for one VF BAR

2015-07-30 Thread Gavin Shan
On Thu, Jul 30, 2015 at 01:43:59PM +0800, Wei Yang wrote:
On Thu, Jul 30, 2015 at 11:15:01AM +1000, Gavin Shan wrote:
On Wed, Jul 29, 2015 at 03:22:07PM +0800, Wei Yang wrote:
In current implementation, when VF BAR is bigger than 64MB, it uses 4 M64
BAR 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 weiy...@linux.vnet.ibm.com
---
 arch/powerpc/include/asm/pci-bridge.h |5 +-
 arch/powerpc/platforms/powernv/pci-ioda.c |  104 
 +
 2 files changed, 18 insertions(+), 91 deletions(-)


questions regarding this:

(1) When M64 BAR is running in single-PE-mode for VFs, the alignment for one
particular IOV BAR still have to be (IOV_BAR_size * max_vf_number), or
M64 segment size of last BAR (0x1000) is fine? If the later one is 
 fine,
more M64 space would be saved. On the other hand, if the IOV BAR size
(for all VFs) is less than 256MB, will the allocated resource conflict
with the M64 segments in last BAR?

Not need to be IOV BAR size aligned, be individual VF BAR size aligned is fine.

IOV BAR size = VF BAR size * expended_num_vfs


The (15th) last PHB's M64 BAR is divided into 256 segments and the size for
each of them is 256MB. Lets have an example: PF has one M64 BAR (128MB) and it
supports 8 VFs. The VF BAR size is 128MB and the IOV BAR size is (128MB * 8).
If we take the VF BAR size (128MB) as the alignment, the MMIO might be assigned
to have following layout. PF and VF will be put into different PE#. So I think
the correct alignment would be max{VF_bar_size, M64_segment_size}, or I missed
something?

   +---++
   |  PF's M64 BAR | VF BARs|
   +---++
   0   128MB (128MB *9)

(2) When M64 BAR is in single-PE-mode, the PE numbers allocated for VFs need
continuous or not.

No, not need.


Ok. If you like, you can improve it to have discrete PE numbers when the PHB's
M64 BARs for VFs runs in single-mode in separate patch.

(3) Each PF could have 6 IOV BARs and there're 15 available M64 BAR. It means
only two VFs can be enabled in the extreme case. Would it be a problem?


Yes, you are right.

Based on Alexey's mail, full isolation is more important than more VFs.


Ok. Lets ignore this issue for now. Maybe it has to be considered in future.
Here's another problem:

(4) In pnv_pci_sriov_enable(), we can bail early when num_vfs = 
phb_avaiable_M64_BARs.
no need to allocate PE number and PHB's M64 BARs, then hit failure and 
release
the allocated resources.

diff --git a/arch/powerpc/include/asm/pci-bridge.h 
b/arch/powerpc/include/asm/pci-bridge.h
index 712add5..1997e5d 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -214,10 +214,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;
+#define MAX_M64_WINDOW  16
 #define IODA_INVALID_M64(-1)
-int m64_wins[PCI_SRIOV_NUM_BARS][M64_PER_IOV];
+int m64_wins[PCI_SRIOV_NUM_BARS][MAX_M64_WINDOW];
 #endif /* CONFIG_PCI_IOV */
 #endif

The m64_wins would be renamed to m64_map. Also, it would have dynamic 
size:

- When the IOV BAR is extended to 256 segments, its size is sizeof(int) * 
PCI_SRIOV_NUM_BARS;
- When the IOV BAR is extended to max_vf_num, its size is sizeof(int) * 
max_vf_num;

 struct list_head child_list;
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 5738d31..b3e7909 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1168,7 +1168,7 @@ 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++) {
+for (j = 0; j  MAX_M64_WINDOW; j++) {
 if (pdn-m64_wins[i][j] == IODA_INVALID_M64)
 continue;
 opal_pci_phb_mmio_enable(phb-opal_id,
@@ -1193,8 +1193,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, 
u16 num_vfs)
 inttotal_vfs;
 resource_size_tsize, start;
 intpe_num;
-intvf_groups;
-intvf_per_group;
+intm64s;

m64s could have better name. For example, vfs_per_m64_bar...


m64s is used to represent number of M64 BARs necessary to enable num_vfs.

Re: [PATCH] powerpc/powernv: use one M64 BAR in Single PE mode for one VF BAR

2015-07-30 Thread Wei Yang
On Fri, Jul 31, 2015 at 10:13:26AM +1000, Gavin Shan wrote:
On Thu, Jul 30, 2015 at 01:43:59PM +0800, Wei Yang wrote:
On Thu, Jul 30, 2015 at 11:15:01AM +1000, Gavin Shan wrote:
On Wed, Jul 29, 2015 at 03:22:07PM +0800, Wei Yang wrote:
In current implementation, when VF BAR is bigger than 64MB, it uses 4 M64
BAR 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 weiy...@linux.vnet.ibm.com
---
 arch/powerpc/include/asm/pci-bridge.h |5 +-
 arch/powerpc/platforms/powernv/pci-ioda.c |  104 
 +
 2 files changed, 18 insertions(+), 91 deletions(-)


questions regarding this:

(1) When M64 BAR is running in single-PE-mode for VFs, the alignment for one
particular IOV BAR still have to be (IOV_BAR_size * max_vf_number), or
M64 segment size of last BAR (0x1000) is fine? If the later one is 
 fine,
more M64 space would be saved. On the other hand, if the IOV BAR size
(for all VFs) is less than 256MB, will the allocated resource conflict
with the M64 segments in last BAR?

Not need to be IOV BAR size aligned, be individual VF BAR size aligned is 
fine.

IOV BAR size = VF BAR size * expended_num_vfs


The (15th) last PHB's M64 BAR is divided into 256 segments and the size for
each of them is 256MB. Lets have an example: PF has one M64 BAR (128MB) and it
supports 8 VFs. The VF BAR size is 128MB and the IOV BAR size is (128MB * 8).
If we take the VF BAR size (128MB) as the alignment, the MMIO might be assigned
to have following layout. PF and VF will be put into different PE#. So I think
the correct alignment would be max{VF_bar_size, M64_segment_size}, or I missed
something?

   +---++
   |  PF's M64 BAR | VF BARs|
   +---++
   0   128MB (128MB *9)


Ok, got your point. So the layout should be

   ++---+
   | VF BARs|  PF's M64 BAR |
   ++---+
   0MB (128MB * 8)

(2) When M64 BAR is in single-PE-mode, the PE numbers allocated for VFs need
continuous or not.

No, not need.


Ok. If you like, you can improve it to have discrete PE numbers when the PHB's
M64 BARs for VFs runs in single-mode in separate patch.


Yep, good suggestion.

(3) Each PF could have 6 IOV BARs and there're 15 available M64 BAR. It means
only two VFs can be enabled in the extreme case. Would it be a problem?


Yes, you are right.

Based on Alexey's mail, full isolation is more important than more VFs.


Ok. Lets ignore this issue for now. Maybe it has to be considered in future.
Here's another problem:

(4) In pnv_pci_sriov_enable(), we can bail early when num_vfs = 
phb_avaiable_M64_BARs.
no need to allocate PE number and PHB's M64 BARs, then hit failure and 
 release
the allocated resources.


Yep, good suggestion.

diff --git a/arch/powerpc/include/asm/pci-bridge.h 
b/arch/powerpc/include/asm/pci-bridge.h
index 712add5..1997e5d 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -214,10 +214,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;
+#define MAX_M64_WINDOW  16
 #define IODA_INVALID_M64(-1)
-   int m64_wins[PCI_SRIOV_NUM_BARS][M64_PER_IOV];
+   int m64_wins[PCI_SRIOV_NUM_BARS][MAX_M64_WINDOW];
 #endif /* CONFIG_PCI_IOV */
 #endif

The m64_wins would be renamed to m64_map. Also, it would have dynamic 
size:

- When the IOV BAR is extended to 256 segments, its size is sizeof(int) * 
PCI_SRIOV_NUM_BARS;
- When the IOV BAR is extended to max_vf_num, its size is sizeof(int) * 
max_vf_num;

struct list_head child_list;
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 5738d31..b3e7909 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1168,7 +1168,7 @@ 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++) {
+   for (j = 0; j  MAX_M64_WINDOW; j++) {
if (pdn-m64_wins[i][j] == IODA_INVALID_M64)
continue;
opal_pci_phb_mmio_enable(phb-opal_id,
@@ -1193,8 +1193,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev 
*pdev, u16 num_vfs)
inttotal_vfs;

Re: [PATCH] powerpc/powernv: use one M64 BAR in Single PE mode for one VF BAR

2015-07-29 Thread Gavin Shan
On Wed, Jul 29, 2015 at 03:22:07PM +0800, Wei Yang wrote:
In current implementation, when VF BAR is bigger than 64MB, it uses 4 M64
BAR 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 weiy...@linux.vnet.ibm.com
---
 arch/powerpc/include/asm/pci-bridge.h |5 +-
 arch/powerpc/platforms/powernv/pci-ioda.c |  104 +
 2 files changed, 18 insertions(+), 91 deletions(-)


questions regarding this:

(1) When M64 BAR is running in single-PE-mode for VFs, the alignment for one
particular IOV BAR still have to be (IOV_BAR_size * max_vf_number), or
M64 segment size of last BAR (0x1000) is fine? If the later one is fine,
more M64 space would be saved. On the other hand, if the IOV BAR size
(for all VFs) is less than 256MB, will the allocated resource conflict
with the M64 segments in last BAR?
(2) When M64 BAR is in single-PE-mode, the PE numbers allocated for VFs need
continuous or not.
(3) Each PF could have 6 IOV BARs and there're 15 available M64 BAR. It means
only two VFs can be enabled in the extreme case. Would it be a problem?

diff --git a/arch/powerpc/include/asm/pci-bridge.h 
b/arch/powerpc/include/asm/pci-bridge.h
index 712add5..1997e5d 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -214,10 +214,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;
+#define MAX_M64_WINDOW  16
 #define IODA_INVALID_M64(-1)
-  int m64_wins[PCI_SRIOV_NUM_BARS][M64_PER_IOV];
+  int m64_wins[PCI_SRIOV_NUM_BARS][MAX_M64_WINDOW];
 #endif /* CONFIG_PCI_IOV */
 #endif

The m64_wins would be renamed to m64_map. Also, it would have dynamic size:

- When the IOV BAR is extended to 256 segments, its size is sizeof(int) * 
PCI_SRIOV_NUM_BARS;
- When the IOV BAR is extended to max_vf_num, its size is sizeof(int) * 
max_vf_num;

   struct list_head child_list;
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 5738d31..b3e7909 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1168,7 +1168,7 @@ 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++) {
+  for (j = 0; j  MAX_M64_WINDOW; j++) {
   if (pdn-m64_wins[i][j] == IODA_INVALID_M64)
   continue;
   opal_pci_phb_mmio_enable(phb-opal_id,
@@ -1193,8 +1193,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, 
u16 num_vfs)
   inttotal_vfs;
   resource_size_tsize, start;
   intpe_num;
-  intvf_groups;
-  intvf_per_group;
+  intm64s;

m64s could have better name. For example, vfs_per_m64_bar...


   bus = pdev-bus;
   hose = pci_bus_to_host(bus);
@@ -1204,17 +1203,13 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, 
u16 num_vfs)

   /* 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++)
+  for (j = 0; j  MAX_M64_WINDOW; j++)
   pdn-m64_wins[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;
-  }
+  if (pdn-vfs_expanded != phb-ioda.total_pe)
+  m64s = num_vfs;
+  else
+  m64s = 1;

The condition (pdn-vfs_expanded != phb-ioda.total_pe) isn't precise enough as
explained below.


   for (i = 0; i  PCI_SRIOV_NUM_BARS; i++) {
   res = pdev-resource[i + PCI_IOV_RESOURCES];
@@ -1224,7 +1219,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, 
u16 num_vfs)
   if (!pnv_pci_is_mem_pref_64(res-flags))
   continue;

-  for (j = 0; j  vf_groups; j++) {
+  for (j = 0; j  m64s; j++) {
   do {
   win = 
 find_next_zero_bit(phb-ioda.m64_bar_alloc,
   phb-ioda.m64_bar_idx + 1, 

[PATCH] powerpc/powernv: use one M64 BAR in Single PE mode for one VF BAR

2015-07-29 Thread Wei Yang
In current implementation, when VF BAR is bigger than 64MB, it uses 4 M64
BAR 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 weiy...@linux.vnet.ibm.com
---
 arch/powerpc/include/asm/pci-bridge.h |5 +-
 arch/powerpc/platforms/powernv/pci-ioda.c |  104 +
 2 files changed, 18 insertions(+), 91 deletions(-)

diff --git a/arch/powerpc/include/asm/pci-bridge.h 
b/arch/powerpc/include/asm/pci-bridge.h
index 712add5..1997e5d 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -214,10 +214,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;
+#define MAX_M64_WINDOW  16
 #define IODA_INVALID_M64(-1)
-   int m64_wins[PCI_SRIOV_NUM_BARS][M64_PER_IOV];
+   int m64_wins[PCI_SRIOV_NUM_BARS][MAX_M64_WINDOW];
 #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 5738d31..b3e7909 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1168,7 +1168,7 @@ 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++) {
+   for (j = 0; j  MAX_M64_WINDOW; j++) {
if (pdn-m64_wins[i][j] == IODA_INVALID_M64)
continue;
opal_pci_phb_mmio_enable(phb-opal_id,
@@ -1193,8 +1193,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, 
u16 num_vfs)
inttotal_vfs;
resource_size_tsize, start;
intpe_num;
-   intvf_groups;
-   intvf_per_group;
+   intm64s;
 
bus = pdev-bus;
hose = pci_bus_to_host(bus);
@@ -1204,17 +1203,13 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, 
u16 num_vfs)
 
/* 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++)
+   for (j = 0; j  MAX_M64_WINDOW; j++)
pdn-m64_wins[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;
-   }
+   if (pdn-vfs_expanded != phb-ioda.total_pe)
+   m64s = num_vfs;
+   else
+   m64s = 1;
 
for (i = 0; i  PCI_SRIOV_NUM_BARS; i++) {
res = pdev-resource[i + PCI_IOV_RESOURCES];
@@ -1224,7 +1219,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, 
u16 num_vfs)
if (!pnv_pci_is_mem_pref_64(res-flags))
continue;
 
-   for (j = 0; j  vf_groups; j++) {
+   for (j = 0; j  m64s; j++) {
do {
win = 
find_next_zero_bit(phb-ioda.m64_bar_alloc,
phb-ioda.m64_bar_idx + 1, 0);
@@ -1235,10 +1230,9 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, 
u16 num_vfs)
 
pdn-m64_wins[i][j] = win;
 
-   if (pdn-m64_per_iov == M64_PER_IOV) {
+   if (pdn-vfs_expanded != phb-ioda.total_pe) {
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);
@@ -1246,7 +1240,7 @@ 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-vfs_expanded != phb-ioda.total_pe) {
pe_num = pdn-offset + j;
rc = opal_pci_map_pe_mmio_window(phb-opal_id,
pe_num, 

Re: [PATCH] powerpc/powernv: use one M64 BAR in Single PE mode for one VF BAR

2015-07-29 Thread Wei Yang
On Thu, Jul 30, 2015 at 11:15:01AM +1000, Gavin Shan wrote:
On Wed, Jul 29, 2015 at 03:22:07PM +0800, Wei Yang wrote:
In current implementation, when VF BAR is bigger than 64MB, it uses 4 M64
BAR 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 weiy...@linux.vnet.ibm.com
---
 arch/powerpc/include/asm/pci-bridge.h |5 +-
 arch/powerpc/platforms/powernv/pci-ioda.c |  104 
 +
 2 files changed, 18 insertions(+), 91 deletions(-)


questions regarding this:

(1) When M64 BAR is running in single-PE-mode for VFs, the alignment for one
particular IOV BAR still have to be (IOV_BAR_size * max_vf_number), or
M64 segment size of last BAR (0x1000) is fine? If the later one is 
 fine,
more M64 space would be saved. On the other hand, if the IOV BAR size
(for all VFs) is less than 256MB, will the allocated resource conflict
with the M64 segments in last BAR?

Not need to be IOV BAR size aligned, be individual VF BAR size aligned is fine.

IOV BAR size = VF BAR size * expended_num_vfs

(2) When M64 BAR is in single-PE-mode, the PE numbers allocated for VFs need
continuous or not.

No, not need.

(3) Each PF could have 6 IOV BARs and there're 15 available M64 BAR. It means
only two VFs can be enabled in the extreme case. Would it be a problem?


Yes, you are right.

Based on Alexey's mail, full isolation is more important than more VFs.

diff --git a/arch/powerpc/include/asm/pci-bridge.h 
b/arch/powerpc/include/asm/pci-bridge.h
index 712add5..1997e5d 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -214,10 +214,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;
+#define MAX_M64_WINDOW  16
 #define IODA_INVALID_M64(-1)
- int m64_wins[PCI_SRIOV_NUM_BARS][M64_PER_IOV];
+ int m64_wins[PCI_SRIOV_NUM_BARS][MAX_M64_WINDOW];
 #endif /* CONFIG_PCI_IOV */
 #endif

The m64_wins would be renamed to m64_map. Also, it would have dynamic size:

- When the IOV BAR is extended to 256 segments, its size is sizeof(int) * 
PCI_SRIOV_NUM_BARS;
- When the IOV BAR is extended to max_vf_num, its size is sizeof(int) * 
max_vf_num;

  struct list_head child_list;
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 5738d31..b3e7909 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1168,7 +1168,7 @@ 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++) {
+ for (j = 0; j  MAX_M64_WINDOW; j++) {
  if (pdn-m64_wins[i][j] == IODA_INVALID_M64)
  continue;
  opal_pci_phb_mmio_enable(phb-opal_id,
@@ -1193,8 +1193,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, 
u16 num_vfs)
  inttotal_vfs;
  resource_size_tsize, start;
  intpe_num;
- intvf_groups;
- intvf_per_group;
+ intm64s;

m64s could have better name. For example, vfs_per_m64_bar...


m64s is used to represent number of M64 BARs necessary to enable num_vfs.
vfs_per_m64_bar may be misleading.

How about m64_bars ?


  bus = pdev-bus;
  hose = pci_bus_to_host(bus);
@@ -1204,17 +1203,13 @@ static int pnv_pci_vf_assign_m64(struct pci_dev 
*pdev, u16 num_vfs)

  /* 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++)
+ for (j = 0; j  MAX_M64_WINDOW; j++)
  pdn-m64_wins[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;
- }
+ if (pdn-vfs_expanded != phb-ioda.total_pe)
+ m64s = num_vfs;
+ else
+ m64s = 1;

The condition (pdn-vfs_expanded != phb-ioda.total_pe) isn't precise enough as
explained below.


  for (i = 0; i  PCI_SRIOV_NUM_BARS; i++) {
  res = pdev-resource[i + PCI_IOV_RESOURCES];
@@ -1224,7 +1219,7 @@ static int