On Wed, 17 Sep 2025, Lucas De Marchi wrote: > There may be cases in which the BAR0 also needs to move to accommodate > the bigger BAR2. However if it's not released, the BAR2 resize fails. > During the vram probe it can't be released as it's already in use by > xe_mmio for early register access. > > Add a new function in xe_vram and let xe_pci call it directly before > even early device probe. This allows the BAR2 to resize in cases BAR0 > also needs to move: > > [] xe 0000:03:00.0: vgaarb: deactivate vga console > [] xe 0000:03:00.0: [drm] Attempting to resize bar from 8192MiB -> > 16384MiB > [] xe 0000:03:00.0: BAR 0 [mem 0x83000000-0x83ffffff 64bit]: releasing > [] xe 0000:03:00.0: BAR 2 [mem 0x4000000000-0x41ffffffff 64bit pref]: > releasing > [] pcieport 0000:02:01.0: bridge window [mem 0x4000000000-0x41ffffffff > 64bit pref]: releasing > [] pcieport 0000:01:00.0: bridge window [mem 0x4000000000-0x41ffffffff > 64bit pref]: releasing > [] pcieport 0000:01:00.0: bridge window [mem 0x4000000000-0x43ffffffff > 64bit pref]: assigned > [] pcieport 0000:02:01.0: bridge window [mem 0x4000000000-0x43ffffffff > 64bit pref]: assigned > [] xe 0000:03:00.0: BAR 2 [mem 0x4000000000-0x43ffffffff 64bit pref]: > assigned > [] xe 0000:03:00.0: BAR 0 [mem 0x83000000-0x83ffffff 64bit]: assigned > [] pcieport 0000:00:01.0: PCI bridge to [bus 01-04] > [] pcieport 0000:00:01.0: bridge window [mem 0x83000000-0x840fffff] > [] pcieport 0000:00:01.0: bridge window [mem > 0x4000000000-0x44007fffff 64bit pref] > [] pcieport 0000:01:00.0: PCI bridge to [bus 02-04] > [] pcieport 0000:01:00.0: bridge window [mem 0x83000000-0x840fffff] > [] pcieport 0000:01:00.0: bridge window [mem > 0x4000000000-0x43ffffffff 64bit pref] > [] pcieport 0000:02:01.0: PCI bridge to [bus 03] > [] pcieport 0000:02:01.0: bridge window [mem 0x83000000-0x83ffffff] > [] pcieport 0000:02:01.0: bridge window [mem > 0x4000000000-0x43ffffffff 64bit pref] > [] xe 0000:03:00.0: [drm] BAR2 resized to 16384M > [] xe 0000:03:00.0: [drm:xe_pci_probe [xe]] BATTLEMAGE e221:0000 > dgfx:1 gfx:Xe2_HPG (20.02) ... > > As shown above, it happens even before we try to read any register for > platform identification. > > All the rebar logic is more pci-specific than xe-specific and can be > done very early in the probe sequence. In future it would be good to > move it out of xe_vram.c, but this refactor is left for later. > > Cc: Ilpo Järvinen <ilpo.jarvi...@linux.intel.com> > Cc: <sta...@vger.kernel.org> # 6.12+ > Link: > https://lore.kernel.org/intel-xe/fafda2a3-fc63-ce97-d22b-803f771a4...@linux.intel.com > Signed-off-by: Lucas De Marchi <lucas.demar...@intel.com> > --- > drivers/gpu/drm/xe/xe_pci.c | 2 ++ > drivers/gpu/drm/xe/xe_vram.c | 22 ++++++++++++++-------- > drivers/gpu/drm/xe/xe_vram.h | 1 + > 3 files changed, 17 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c > index 701ba9baa9d7e..1f4120b535137 100644 > --- a/drivers/gpu/drm/xe/xe_pci.c > +++ b/drivers/gpu/drm/xe/xe_pci.c > @@ -866,6 +866,8 @@ static int xe_pci_probe(struct pci_dev *pdev, const > struct pci_device_id *ent) > if (err) > return err; > > + xe_vram_resize_bar(xe); > + > err = xe_device_probe_early(xe); > /* > * In Boot Survivability mode, no drm card is exposed and driver > diff --git a/drivers/gpu/drm/xe/xe_vram.c b/drivers/gpu/drm/xe/xe_vram.c > index b44ebf50fedbb..4fb5a8426531a 100644 > --- a/drivers/gpu/drm/xe/xe_vram.c > +++ b/drivers/gpu/drm/xe/xe_vram.c > @@ -26,15 +26,23 @@ > > #define BAR_SIZE_SHIFT 20 > > -static void > -_resize_bar(struct xe_device *xe, int resno, resource_size_t size) > +static void release_bars(struct pci_dev *pdev) > +{ > + int resno; > + > + for (resno = PCI_STD_RESOURCES; resno < PCI_STD_RESOURCE_END; resno++) { > + if (pci_resource_len(pdev, resno))
Please test res->parent instead to find out if the resource is assigned or not. While pci_resource_len() works currently, I've plans to change that. Thanks to drivers making the assumption that unassigned resources are reset that change is very scary and breaks all over the place. :-( It's important to not reset the resources as once reset resource is effectively gone until remove/rescan cycle as BARs are not read from the device ever again after the initial probing. So if a BAR won't fit once, shrinking another BAR will not allow the previously non-fitting one to reappear even if it would then fit. (The resource reset has already been removed in the case of bridge window resources by my very recent changes so that the window resource is just DISABLED instead.) > + pci_release_resource(pdev, resno); Also, CONFIG_PCI_IOV=y will result in more BARs. I suggest you just use pci_dev_for_each_resource() which can be used in 3 args version to get resno need for pci_release_resource() call. But you'll then need to decide what to do with the Expansion ROM resource, filter it out I guess. Maybe use IORESOURCE_MEM_64 to release only relevant resource as those resources should share the same bridge window with the BAR we're resizing here. (Unrelated to this patch, but in case you end up noticing the same problem when enabling IOV config. Testing with my card, it seems PCI core's SR-IOV code is broken when it comes to initializing IOV resources, resulting in bogus conflicts: pnp 00:04: disabling [mem 0xfc000000-0xfc00ffff] because it overlaps 0000:03:00.0 BAR 9 [mem 0x00000000-0x3dffffffff 64bit pref] ...yet another patch needed it seems.) -- i. > + } > +} > + > +static void resize_bar(struct xe_device *xe, int resno, resource_size_t size) > { > struct pci_dev *pdev = to_pci_dev(xe->drm.dev); > int bar_size = pci_rebar_bytes_to_size(size); > int ret; > > - if (pci_resource_len(pdev, resno)) > - pci_release_resource(pdev, resno); > + release_bars(pdev); > > ret = pci_resize_resource(pdev, resno, bar_size); > if (ret) { > @@ -50,7 +58,7 @@ _resize_bar(struct xe_device *xe, int resno, > resource_size_t size) > * if force_vram_bar_size is set, attempt to set to the requested size > * else set to maximum possible size > */ > -static void resize_vram_bar(struct xe_device *xe) > +void xe_vram_resize_bar(struct xe_device *xe) > { > int force_vram_bar_size = xe_modparam.force_vram_bar_size; > struct pci_dev *pdev = to_pci_dev(xe->drm.dev); > @@ -119,7 +127,7 @@ static void resize_vram_bar(struct xe_device *xe) > pci_read_config_dword(pdev, PCI_COMMAND, &pci_cmd); > pci_write_config_dword(pdev, PCI_COMMAND, pci_cmd & > ~PCI_COMMAND_MEMORY); > > - _resize_bar(xe, LMEM_BAR, rebar_size); > + resize_bar(xe, LMEM_BAR, rebar_size); > > pci_assign_unassigned_bus_resources(pdev->bus); > pci_write_config_dword(pdev, PCI_COMMAND, pci_cmd); > @@ -148,8 +156,6 @@ static int determine_lmem_bar_size(struct xe_device *xe, > struct xe_vram_region * > return -ENXIO; > } > > - resize_vram_bar(xe); > - > lmem_bar->io_start = pci_resource_start(pdev, LMEM_BAR); > lmem_bar->io_size = pci_resource_len(pdev, LMEM_BAR); > if (!lmem_bar->io_size) > diff --git a/drivers/gpu/drm/xe/xe_vram.h b/drivers/gpu/drm/xe/xe_vram.h > index 72860f714fc66..13505cfb184dc 100644 > --- a/drivers/gpu/drm/xe/xe_vram.h > +++ b/drivers/gpu/drm/xe/xe_vram.h > @@ -11,6 +11,7 @@ > struct xe_device; > struct xe_vram_region; > > +void xe_vram_resize_bar(struct xe_device *xe); > int xe_vram_probe(struct xe_device *xe); > > struct xe_vram_region *xe_vram_region_alloc(struct xe_device *xe, u8 id, u32 > placement); > >