extent_free fixes

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

extent_free fixes

Mark Kettenis
The diff below should fix one of the issues uncovered by the
acpipci(4) changes that I just backed out.

On some systems, ACPI specifies overlapping regions of address space
that gets forwarded to the PCI bus.  Since we use extent_free(9) to
make those regions of address space available, that code needs to be
able to handle overlaps.

Since the acpipci(4) has been backed out, I attach the diff (with
debug print code) below.  Alexander, it would be great if you can test
this on that SuperMicro box.


Index: sys/kern/subr_extent.c
===================================================================
RCS file: /cvs/src/sys/kern/subr_extent.c,v
retrieving revision 1.61
diff -u -p -r1.61 subr_extent.c
--- sys/kern/subr_extent.c 28 Aug 2019 22:22:43 -0000 1.61
+++ sys/kern/subr_extent.c 7 Sep 2019 13:55:01 -0000
@@ -962,6 +962,7 @@ int
 extent_free(struct extent *ex, u_long start, u_long size, int flags)
 {
  struct extent_region *rp, *nrp = NULL;
+ struct extent_region *tmp;
  u_long end = start + (size - 1);
  int exflags;
  int error = 0;
@@ -1019,8 +1020,12 @@ extent_free(struct extent *ex, u_long st
  *
  * Cases 2, 3, and 4 require that the EXF_NOCOALESCE flag
  * is not set.
+ *
+ * If the EX_CONFLICTOK flag is set, partially overlapping
+ * regions are allowed.  This is handled in cases 1a, 2a and
+ * 3a below.
  */
- LIST_FOREACH(rp, &ex->ex_regions, er_link) {
+ LIST_FOREACH_SAFE(rp, &ex->ex_regions, er_link, tmp) {
  /*
  * Save ourselves some comparisons; does the current
  * region end before chunk to be freed begins?  If so,
@@ -1080,12 +1085,28 @@ extent_free(struct extent *ex, u_long st
  nrp = NULL;
  goto done;
  }
+
+ if ((flags & EX_CONFLICTOK) == 0)
+ continue;
+
+ /* Case 1a. */
+ if ((start <= rp->er_start && end >= rp->er_end)) {
+ LIST_REMOVE(rp, er_link);
+ extent_free_region_descriptor(ex, rp);
+ continue;
+ }
+
+ /* Case 2a. */
+ if ((start <= rp->er_start) && (end >= rp->er_start))
+ rp->er_start = (end + 1);
+
+ /* Case 3a. */
+ if ((start <= rp->er_end) && (end >= rp->er_end))
+ rp->er_end = (start - 1);
  }
 
- if (flags & EX_CONFLICTOK) {
- error = EINVAL;
+ if (flags & EX_CONFLICTOK)
  goto done;
- }
 
  /* Region not found, or request otherwise invalid. */
 #if defined(DIAGNOSTIC) || defined(DDB)
Index: regress/sys/kern/extent/extest.awk
===================================================================
RCS file: /cvs/src/regress/sys/kern/extent/extest.awk,v
retrieving revision 1.2
diff -u -p -r1.2 extest.awk
--- regress/sys/kern/extent/extest.awk 10 Apr 2009 20:57:04 -0000 1.2
+++ regress/sys/kern/extent/extest.awk 7 Sep 2019 13:55:01 -0000
@@ -67,7 +67,12 @@ $1 == "alloc_subregion" {
 }
 
 $1 == "free" {
- printf("error = extent_free(ex, %s, %s, 0);\n", $2, $3)
+ if ($4 == "") {
+ flags = "0";
+ } else {
+ flags = $4;
+ }
+ printf("error = extent_free(ex, %s, %s, %s);\n", $2, $3, flags)
  printf("if (error)\n\tprintf(\"error: %%s\\n\", strerror(error));\n")
 }
 
Index: regress/sys/kern/extent/extest.exp
===================================================================
RCS file: /cvs/src/regress/sys/kern/extent/extest.exp,v
retrieving revision 1.4
diff -u -p -r1.4 extest.exp
--- regress/sys/kern/extent/extest.exp 13 Oct 2009 20:53:40 -0000 1.4
+++ regress/sys/kern/extent/extest.exp 7 Sep 2019 13:55:01 -0000
@@ -92,3 +92,13 @@ extent `test16' (0x0 - 0xffffffff), flag
 output for test17
 extent `test17' (0x0 - 0xffffffffffffffff), flags = 0x0
      0x0 - 0xffffffffffffffff
+output for test18
+extent `test18' (0x0 - 0xffff), flags = 0x0
+     0x0 - 0xcff
+     0xf000 - 0xffff
+output for test19
+extent `test19' (0x0 - 0xffff), flags = 0x0
+     0x0 - 0xcff
+output for test20
+extent `test20' (0x0 - 0xffff), flags = 0x0
+     0xf000 - 0xffff
Index: regress/sys/kern/extent/tests
===================================================================
RCS file: /cvs/src/regress/sys/kern/extent/tests,v
retrieving revision 1.5
diff -u -p -r1.5 tests
--- regress/sys/kern/extent/tests 13 Oct 2009 20:53:40 -0000 1.5
+++ regress/sys/kern/extent/tests 7 Sep 2019 13:55:01 -0000
@@ -136,3 +136,19 @@ print
 extent test17 0x00000000 -1L EX_FILLED
 alloc_region 0 0x4000 EX_CONFLICTOK
 print
+
+# Check freeing overkapping regions from a filled extent
+extent test18 0x0000 0xffff EX_FILLED
+free 0x164e 0x2
+free 0x0d00 0xe300 EX_CONFLICTOK
+print
+
+extent test19 0x0000 0xffff EX_FILLED
+free 0x164e 0x2
+free 0x0d00 0xf300 EX_CONFLICTOK
+print
+
+extent test20 0x0000 0xffff EX_FILLED
+free 0x164e 0x2
+free 0x0000 0xf000 EX_CONFLICTOK
+print






Index: dev/acpi/acpi.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.374
diff -u -p -r1.374 acpi.c
--- dev/acpi/acpi.c 7 Sep 2019 13:46:20 -0000 1.374
+++ dev/acpi/acpi.c 7 Sep 2019 14:04:45 -0000
@@ -71,6 +71,7 @@ int acpi_debug = 16;
 
 int acpi_poll_enabled;
 int acpi_hasprocfvs;
+int acpi_haspci;
 
 #define ACPIEN_RETRIES 15
 
Index: dev/acpi/acpivar.h
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpivar.h,v
retrieving revision 1.105
diff -u -p -r1.105 acpivar.h
--- dev/acpi/acpivar.h 7 Sep 2019 13:46:20 -0000 1.105
+++ dev/acpi/acpivar.h 7 Sep 2019 14:04:45 -0000
@@ -43,6 +43,7 @@ extern int acpi_debug;
 #endif
 
 extern int acpi_hasprocfvs;
+extern int acpi_haspci;
 
 struct klist;
 struct acpiec_softc;
Index: arch/amd64/amd64/mainbus.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/mainbus.c,v
retrieving revision 1.49
diff -u -p -r1.49 mainbus.c
--- arch/amd64/amd64/mainbus.c 7 Sep 2019 13:46:19 -0000 1.49
+++ arch/amd64/amd64/mainbus.c 7 Sep 2019 14:04:45 -0000
@@ -231,6 +231,9 @@ mainbus_attach(struct device *parent, st
 #endif
 
 #if NPCI > 0
+#if NACPI > 0
+ if (!acpi_haspci)
+#endif
  {
  pci_init_extents();
 
@@ -244,6 +247,7 @@ mainbus_attach(struct device *parent, st
  mba.mba_pba.pba_busex = pcibus_ex;
  mba.mba_pba.pba_domain = pci_ndomains++;
  mba.mba_pba.pba_bus = 0;
+ mba.mba_pba.pba_flags = PCI_FLAGS_MSI_ENABLED;
  config_found(self, &mba.mba_pba, mainbus_print);
 #if NACPI > 0
  acpi_pciroots_attach(self, &mba.mba_pba, mainbus_print);
Index: arch/amd64/conf/GENERIC
===================================================================
RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v
retrieving revision 1.478
diff -u -p -r1.478 GENERIC
--- arch/amd64/conf/GENERIC 7 Sep 2019 13:46:19 -0000 1.478
+++ arch/amd64/conf/GENERIC 7 Sep 2019 14:04:45 -0000
@@ -48,6 +48,7 @@ acpicmos* at acpi?
 acpidock* at acpi?
 acpiec* at acpi?
 acpipci* at acpi?
+pci* at acpipci?
 acpiprt* at acpi?
 acpisbs* at acpi?
 acpitz* at acpi?
Index: arch/amd64/conf/RAMDISK
===================================================================
RCS file: /cvs/src/sys/arch/amd64/conf/RAMDISK,v
retrieving revision 1.74
diff -u -p -r1.74 RAMDISK
--- arch/amd64/conf/RAMDISK 7 Sep 2019 13:46:19 -0000 1.74
+++ arch/amd64/conf/RAMDISK 7 Sep 2019 14:04:46 -0000
@@ -29,6 +29,8 @@ acpi0 at bios?
 #acpicpu* at acpi?
 acpicmos* at acpi?
 acpiec* at acpi?
+acpipci* at acpi?
+pci* at acpipci?
 acpiprt* at acpi?
 acpimadt0 at acpi?
 #acpitz* at acpi?
Index: arch/amd64/conf/RAMDISK_CD
===================================================================
RCS file: /cvs/src/sys/arch/amd64/conf/RAMDISK_CD,v
retrieving revision 1.184
diff -u -p -r1.184 RAMDISK_CD
--- arch/amd64/conf/RAMDISK_CD 7 Sep 2019 13:46:19 -0000 1.184
+++ arch/amd64/conf/RAMDISK_CD 7 Sep 2019 14:04:46 -0000
@@ -37,6 +37,8 @@ acpi0 at bios?
 #acpicpu* at acpi?
 acpicmos* at acpi?
 acpiec* at acpi?
+acpipci* at acpi?
+pci* at acpipci?
 acpiprt* at acpi?
 acpimadt0 at acpi?
 #acpitz* at acpi?
Index: arch/amd64/conf/files.amd64
===================================================================
RCS file: /cvs/src/sys/arch/amd64/conf/files.amd64,v
retrieving revision 1.104
diff -u -p -r1.104 files.amd64
--- arch/amd64/conf/files.amd64 7 Sep 2019 13:46:19 -0000 1.104
+++ arch/amd64/conf/files.amd64 7 Sep 2019 14:04:46 -0000
@@ -237,7 +237,7 @@ attach acpi at bios
 file arch/amd64/amd64/acpi_machdep.c acpi
 file arch/amd64/amd64/acpi_wakecode.S acpi & !small_kernel
 
-device acpipci
+device acpipci: pcibus
 attach acpipci at acpi
 file arch/amd64/pci/acpipci.c acpipci
 
Index: arch/amd64/pci/acpipci.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/pci/acpipci.c,v
retrieving revision 1.3
diff -u -p -r1.3 acpipci.c
--- arch/amd64/pci/acpipci.c 7 Sep 2019 13:46:19 -0000 1.3
+++ arch/amd64/pci/acpipci.c 7 Sep 2019 14:04:46 -0000
@@ -53,6 +53,19 @@ struct acpipci_softc {
  struct device sc_dev;
  struct acpi_softc *sc_acpi;
  struct aml_node *sc_node;
+
+ bus_space_tag_t sc_iot;
+ bus_space_tag_t sc_memt;
+ bus_dma_tag_t sc_dmat;
+
+ struct extent *sc_busex;
+ struct extent *sc_memex;
+ struct extent *sc_ioex;
+ char sc_busex_name[32];
+ char sc_ioex_name[32];
+ char sc_memex_name[32];
+ int sc_bus;
+ uint32_t sc_seg;
 };
 
 int acpipci_match(struct device *, void *, void *);
@@ -72,6 +85,11 @@ const char *acpipci_hids[] = {
  NULL
 };
 
+void acpipci_attach_deferred(struct device *);
+int acpipci_print(void *, const char *);
+int acpipci_parse_resources(int, union acpi_resource *, void *);
+void acpipci_osc(struct acpipci_softc *);
+
 int
 acpipci_match(struct device *parent, void *match, void *aux)
 {
@@ -86,15 +104,167 @@ acpipci_attach(struct device *parent, st
 {
  struct acpi_attach_args *aaa = aux;
  struct acpipci_softc *sc = (struct acpipci_softc *)self;
- struct aml_value args[4];
  struct aml_value res;
- static uint8_t uuid[16] = ACPI_PCI_UUID;
- uint32_t buf[3];
+ uint64_t bbn = 0;
+ uint64_t seg = 0;
 
  sc->sc_acpi = (struct acpi_softc *)parent;
  sc->sc_node = aaa->aaa_node;
  printf(" %s", sc->sc_node->name);
 
+ if (aml_evalname(sc->sc_acpi, sc->sc_node, "_CRS", 0, NULL, &res)) {
+ printf(": can't find resources\n");
+ return;
+ }
+
+ aml_evalinteger(sc->sc_acpi, sc->sc_node, "_BBN", 0, NULL, &bbn);
+ sc->sc_bus = bbn;
+
+ aml_evalinteger(sc->sc_acpi, sc->sc_node, "_SEG", 0, NULL, &seg);
+ sc->sc_seg = seg;
+
+ /* Create extents for our address spaces. */
+ snprintf(sc->sc_busex_name, sizeof(sc->sc_busex_name),
+    "%s pcibus", sc->sc_dev.dv_xname);
+ snprintf(sc->sc_ioex_name, sizeof(sc->sc_ioex_name),
+    "%s pciio", sc->sc_dev.dv_xname);
+ snprintf(sc->sc_memex_name, sizeof(sc->sc_memex_name),
+    "%s pcimem", sc->sc_dev.dv_xname);
+ sc->sc_busex = extent_create(sc->sc_busex_name, 0, 255,
+    M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED);
+ sc->sc_ioex = extent_create(sc->sc_ioex_name, 0, 0xffffffff,
+    M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED);
+ sc->sc_memex = extent_create(sc->sc_memex_name, 0, (u_long)-1,
+    M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED);
+
+ aml_parse_resource(&res, acpipci_parse_resources, sc);
+
+ acpipci_osc(sc);
+
+ printf("\n");
+
+ extent_print(sc->sc_busex);
+ extent_print(sc->sc_ioex);
+ extent_print(sc->sc_memex);
+
+ acpi_haspci = 1;
+
+ sc->sc_iot = aaa->aaa_iot;
+ sc->sc_memt = aaa->aaa_memt;
+ sc->sc_dmat = aaa->aaa_dmat;
+
+ config_defer(self, acpipci_attach_deferred);
+}
+
+void
+acpipci_attach_deferred(struct device *self)
+{
+ struct acpipci_softc *sc = (struct acpipci_softc *)self;
+ struct pcibus_attach_args pba;
+
+ memset(&pba, 0, sizeof(pba));
+ pba.pba_busname = "pci";
+ pba.pba_iot = sc->sc_iot;
+ pba.pba_memt = sc->sc_memt;
+ pba.pba_dmat = sc->sc_dmat;
+ pba.pba_busex = sc->sc_busex;
+ pba.pba_ioex = sc->sc_ioex;
+ pba.pba_memex = sc->sc_memex;
+ pba.pba_pmemex = sc->sc_memex;
+ pba.pba_domain = pci_ndomains++;
+ pba.pba_bus = sc->sc_bus;
+
+ /* Enable MSI in ACPI 2.0 and above, unless we're told not to. */
+ if (sc->sc_acpi->sc_fadt->hdr.revision >= 2 &&
+    (sc->sc_acpi->sc_fadt->iapc_boot_arch & FADT_NO_MSI) == 0)
+ pba.pba_flags |= PCI_FLAGS_MSI_ENABLED;
+
+ config_found(self, &pba, acpipci_print);
+}
+
+int
+acpipci_print(void *aux, const char *pnp)
+{
+ struct pcibus_attach_args *pba = aux;
+
+ if (pnp)
+ printf("%s at %s", pba->pba_busname, pnp);
+ printf(" bus %d", pba->pba_bus);
+ return (UNCONF);
+}
+
+int
+acpipci_parse_resources(int crsidx, union acpi_resource *crs, void *arg)
+{
+ struct acpipci_softc *sc = arg;
+ int type = AML_CRSTYPE(crs);
+ int restype, tflags = 0;
+ u_long min, len = 0, tra = 0;
+
+ switch (type) {
+ case LR_WORD:
+ restype = crs->lr_word.type;
+ tflags = crs->lr_word.tflags;
+ min = crs->lr_word._min;
+ len = crs->lr_word._len;
+ tra = crs->lr_word._tra;
+ break;
+ case LR_DWORD:
+ restype = crs->lr_dword.type;
+ tflags = crs->lr_dword.tflags;
+ min = crs->lr_dword._min;
+ len = crs->lr_dword._len;
+ tra = crs->lr_dword._tra;
+ break;
+ case LR_QWORD:
+ restype = crs->lr_qword.type;
+ tflags = crs->lr_qword.tflags;
+ min = crs->lr_qword._min;
+ len = crs->lr_qword._len;
+ tra = crs->lr_qword._tra;
+ break;
+ case LR_MEM32FIXED:
+ /*
+ * Coreboot on the PC Engines apu2 incorrectly uses a
+ * Memory32Fixed resource descriptor to describe mmio
+ * address space forwarded to the PCI bus.
+ */
+ restype = LR_TYPE_MEMORY;
+ min = crs->lr_m32fixed._bas;
+ len = crs->lr_m32fixed._len;
+ break;
+ }
+
+ if (len == 0)
+ return 0;
+
+ switch (restype) {
+ case LR_TYPE_MEMORY:
+ if (tflags & LR_MEMORY_TTP)
+ return 0;
+ extent_free(sc->sc_memex, min, len, EX_WAITOK | EX_CONFLICTOK);
+ break;
+ case LR_TYPE_IO:
+ if (tflags & LR_IO_TTP)
+ return 0;
+ extent_free(sc->sc_ioex, min, len, EX_WAITOK | EX_CONFLICTOK);
+ break;
+ case LR_TYPE_BUS:
+ extent_free(sc->sc_busex, min, len, EX_WAITOK);
+ break;
+ }
+
+ return 0;
+}
+
+void
+acpipci_osc(struct acpipci_softc *sc)
+{
+ struct aml_value args[4];
+ struct aml_value res;
+ static uint8_t uuid[16] = ACPI_PCI_UUID;
+ uint32_t buf[3];
+
  memset(args, 0, sizeof(args));
  args[0].type = AML_OBJTYPE_BUFFER;
  args[0].v_buffer = uuid;
@@ -112,10 +282,8 @@ acpipci_attach(struct device *parent, st
  buf[1] = ACPI_PCI_PCIE_CONFIG | ACPI_PCI_MSI;
  buf[2] = ACPI_PCI_PCIE_HOTPLUG;
 
- if (aml_evalname(sc->sc_acpi, sc->sc_node, "_OSC", 4, args, &res)) {
- printf(": _OSC failed\n");
+ if (aml_evalname(sc->sc_acpi, sc->sc_node, "_OSC", 4, args, &res))
  return;
- }
 
  if (res.type == AML_OBJTYPE_BUFFER) {
  size_t len = res.length;
@@ -128,6 +296,4 @@ acpipci_attach(struct device *parent, st
  len -= 4;
  }
  }
-
- printf("\n");
 }
Index: arch/amd64/pci/pci_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/pci/pci_machdep.c,v
retrieving revision 1.73
diff -u -p -r1.73 pci_machdep.c
--- arch/amd64/pci/pci_machdep.c 7 Sep 2019 13:46:19 -0000 1.73
+++ arch/amd64/pci/pci_machdep.c 7 Sep 2019 14:04:46 -0000
@@ -189,24 +189,11 @@ pci_attach_hook(struct device *parent, s
 
  switch (PCI_VENDOR(id)) {
  case PCI_VENDOR_INTEL:
- /*
- * In the wonderful world of virtualization you can
- * have the latest 64-bit AMD multicore CPU behind a
- * prehistoric Intel host bridge.  Give them what they
- * deserve.
- */
- switch (PCI_PRODUCT(id)) {
- case PCI_PRODUCT_INTEL_82441FX: /* QEMU */
- case PCI_PRODUCT_INTEL_82443BX: /* VMWare */
- break;
- default:
- pba->pba_flags |= PCI_FLAGS_MSI_ENABLED;
- break;
- }
- break;
  case PCI_VENDOR_NVIDIA:
  case PCI_VENDOR_AMD:
- pba->pba_flags |= PCI_FLAGS_MSI_ENABLED;
+ break;
+ default:
+ pba->pba_flags &= ~PCI_FLAGS_MSI_ENABLED;
  break;
  }
 

Reply | Threaded
Open this post in threaded view
|

Re: extent_free fixes

Alexander Bluhm
On Sat, Sep 07, 2019 at 04:07:22PM +0200, Mark Kettenis wrote:

> The diff below should fix one of the issues uncovered by the
> acpipci(4) changes that I just backed out.
>
> On some systems, ACPI specifies overlapping regions of address space
> that gets forwarded to the PCI bus.  Since we use extent_free(9) to
> make those regions of address space available, that code needs to be
> able to handle overlaps.
>
> Since the acpipci(4) has been backed out, I attach the diff (with
> debug print code) below.  Alexander, it would be great if you can test
> this on that SuperMicro box.
No strange errors in dmesg anymore.  Regress passes.
Dmesg and pcidump without and with this diff attached.

bluhm

> Index: sys/kern/subr_extent.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/subr_extent.c,v
> retrieving revision 1.61
> diff -u -p -r1.61 subr_extent.c
> --- sys/kern/subr_extent.c 28 Aug 2019 22:22:43 -0000 1.61
> +++ sys/kern/subr_extent.c 7 Sep 2019 13:55:01 -0000
> @@ -962,6 +962,7 @@ int
>  extent_free(struct extent *ex, u_long start, u_long size, int flags)
>  {
>   struct extent_region *rp, *nrp = NULL;
> + struct extent_region *tmp;
>   u_long end = start + (size - 1);
>   int exflags;
>   int error = 0;
> @@ -1019,8 +1020,12 @@ extent_free(struct extent *ex, u_long st
>   *
>   * Cases 2, 3, and 4 require that the EXF_NOCOALESCE flag
>   * is not set.
> + *
> + * If the EX_CONFLICTOK flag is set, partially overlapping
> + * regions are allowed.  This is handled in cases 1a, 2a and
> + * 3a below.
>   */
> - LIST_FOREACH(rp, &ex->ex_regions, er_link) {
> + LIST_FOREACH_SAFE(rp, &ex->ex_regions, er_link, tmp) {
>   /*
>   * Save ourselves some comparisons; does the current
>   * region end before chunk to be freed begins?  If so,
> @@ -1080,12 +1085,28 @@ extent_free(struct extent *ex, u_long st
>   nrp = NULL;
>   goto done;
>   }
> +
> + if ((flags & EX_CONFLICTOK) == 0)
> + continue;
> +
> + /* Case 1a. */
> + if ((start <= rp->er_start && end >= rp->er_end)) {
> + LIST_REMOVE(rp, er_link);
> + extent_free_region_descriptor(ex, rp);
> + continue;
> + }
> +
> + /* Case 2a. */
> + if ((start <= rp->er_start) && (end >= rp->er_start))
> + rp->er_start = (end + 1);
> +
> + /* Case 3a. */
> + if ((start <= rp->er_end) && (end >= rp->er_end))
> + rp->er_end = (start - 1);
>   }
>
> - if (flags & EX_CONFLICTOK) {
> - error = EINVAL;
> + if (flags & EX_CONFLICTOK)
>   goto done;
> - }
>
>   /* Region not found, or request otherwise invalid. */
>  #if defined(DIAGNOSTIC) || defined(DDB)
> Index: regress/sys/kern/extent/extest.awk
> ===================================================================
> RCS file: /cvs/src/regress/sys/kern/extent/extest.awk,v
> retrieving revision 1.2
> diff -u -p -r1.2 extest.awk
> --- regress/sys/kern/extent/extest.awk 10 Apr 2009 20:57:04 -0000 1.2
> +++ regress/sys/kern/extent/extest.awk 7 Sep 2019 13:55:01 -0000
> @@ -67,7 +67,12 @@ $1 == "alloc_subregion" {
>  }
>
>  $1 == "free" {
> - printf("error = extent_free(ex, %s, %s, 0);\n", $2, $3)
> + if ($4 == "") {
> + flags = "0";
> + } else {
> + flags = $4;
> + }
> + printf("error = extent_free(ex, %s, %s, %s);\n", $2, $3, flags)
>   printf("if (error)\n\tprintf(\"error: %%s\\n\", strerror(error));\n")
>  }
>
> Index: regress/sys/kern/extent/extest.exp
> ===================================================================
> RCS file: /cvs/src/regress/sys/kern/extent/extest.exp,v
> retrieving revision 1.4
> diff -u -p -r1.4 extest.exp
> --- regress/sys/kern/extent/extest.exp 13 Oct 2009 20:53:40 -0000 1.4
> +++ regress/sys/kern/extent/extest.exp 7 Sep 2019 13:55:01 -0000
> @@ -92,3 +92,13 @@ extent `test16' (0x0 - 0xffffffff), flag
>  output for test17
>  extent `test17' (0x0 - 0xffffffffffffffff), flags = 0x0
>       0x0 - 0xffffffffffffffff
> +output for test18
> +extent `test18' (0x0 - 0xffff), flags = 0x0
> +     0x0 - 0xcff
> +     0xf000 - 0xffff
> +output for test19
> +extent `test19' (0x0 - 0xffff), flags = 0x0
> +     0x0 - 0xcff
> +output for test20
> +extent `test20' (0x0 - 0xffff), flags = 0x0
> +     0xf000 - 0xffff
> Index: regress/sys/kern/extent/tests
> ===================================================================
> RCS file: /cvs/src/regress/sys/kern/extent/tests,v
> retrieving revision 1.5
> diff -u -p -r1.5 tests
> --- regress/sys/kern/extent/tests 13 Oct 2009 20:53:40 -0000 1.5
> +++ regress/sys/kern/extent/tests 7 Sep 2019 13:55:01 -0000
> @@ -136,3 +136,19 @@ print
>  extent test17 0x00000000 -1L EX_FILLED
>  alloc_region 0 0x4000 EX_CONFLICTOK
>  print
> +
> +# Check freeing overkapping regions from a filled extent
> +extent test18 0x0000 0xffff EX_FILLED
> +free 0x164e 0x2
> +free 0x0d00 0xe300 EX_CONFLICTOK
> +print
> +
> +extent test19 0x0000 0xffff EX_FILLED
> +free 0x164e 0x2
> +free 0x0d00 0xf300 EX_CONFLICTOK
> +print
> +
> +extent test20 0x0000 0xffff EX_FILLED
> +free 0x164e 0x2
> +free 0x0000 0xf000 EX_CONFLICTOK
> +print
>
>
>
>
>
>
> Index: dev/acpi/acpi.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
> retrieving revision 1.374
> diff -u -p -r1.374 acpi.c
> --- dev/acpi/acpi.c 7 Sep 2019 13:46:20 -0000 1.374
> +++ dev/acpi/acpi.c 7 Sep 2019 14:04:45 -0000
> @@ -71,6 +71,7 @@ int acpi_debug = 16;
>
>  int acpi_poll_enabled;
>  int acpi_hasprocfvs;
> +int acpi_haspci;
>
>  #define ACPIEN_RETRIES 15
>
> Index: dev/acpi/acpivar.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/acpi/acpivar.h,v
> retrieving revision 1.105
> diff -u -p -r1.105 acpivar.h
> --- dev/acpi/acpivar.h 7 Sep 2019 13:46:20 -0000 1.105
> +++ dev/acpi/acpivar.h 7 Sep 2019 14:04:45 -0000
> @@ -43,6 +43,7 @@ extern int acpi_debug;
>  #endif
>
>  extern int acpi_hasprocfvs;
> +extern int acpi_haspci;
>
>  struct klist;
>  struct acpiec_softc;
> Index: arch/amd64/amd64/mainbus.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/amd64/mainbus.c,v
> retrieving revision 1.49
> diff -u -p -r1.49 mainbus.c
> --- arch/amd64/amd64/mainbus.c 7 Sep 2019 13:46:19 -0000 1.49
> +++ arch/amd64/amd64/mainbus.c 7 Sep 2019 14:04:45 -0000
> @@ -231,6 +231,9 @@ mainbus_attach(struct device *parent, st
>  #endif
>
>  #if NPCI > 0
> +#if NACPI > 0
> + if (!acpi_haspci)
> +#endif
>   {
>   pci_init_extents();
>
> @@ -244,6 +247,7 @@ mainbus_attach(struct device *parent, st
>   mba.mba_pba.pba_busex = pcibus_ex;
>   mba.mba_pba.pba_domain = pci_ndomains++;
>   mba.mba_pba.pba_bus = 0;
> + mba.mba_pba.pba_flags = PCI_FLAGS_MSI_ENABLED;
>   config_found(self, &mba.mba_pba, mainbus_print);
>  #if NACPI > 0
>   acpi_pciroots_attach(self, &mba.mba_pba, mainbus_print);
> Index: arch/amd64/conf/GENERIC
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v
> retrieving revision 1.478
> diff -u -p -r1.478 GENERIC
> --- arch/amd64/conf/GENERIC 7 Sep 2019 13:46:19 -0000 1.478
> +++ arch/amd64/conf/GENERIC 7 Sep 2019 14:04:45 -0000
> @@ -48,6 +48,7 @@ acpicmos* at acpi?
>  acpidock* at acpi?
>  acpiec* at acpi?
>  acpipci* at acpi?
> +pci* at acpipci?
>  acpiprt* at acpi?
>  acpisbs* at acpi?
>  acpitz* at acpi?
> Index: arch/amd64/conf/RAMDISK
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/conf/RAMDISK,v
> retrieving revision 1.74
> diff -u -p -r1.74 RAMDISK
> --- arch/amd64/conf/RAMDISK 7 Sep 2019 13:46:19 -0000 1.74
> +++ arch/amd64/conf/RAMDISK 7 Sep 2019 14:04:46 -0000
> @@ -29,6 +29,8 @@ acpi0 at bios?
>  #acpicpu* at acpi?
>  acpicmos* at acpi?
>  acpiec* at acpi?
> +acpipci* at acpi?
> +pci* at acpipci?
>  acpiprt* at acpi?
>  acpimadt0 at acpi?
>  #acpitz* at acpi?
> Index: arch/amd64/conf/RAMDISK_CD
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/conf/RAMDISK_CD,v
> retrieving revision 1.184
> diff -u -p -r1.184 RAMDISK_CD
> --- arch/amd64/conf/RAMDISK_CD 7 Sep 2019 13:46:19 -0000 1.184
> +++ arch/amd64/conf/RAMDISK_CD 7 Sep 2019 14:04:46 -0000
> @@ -37,6 +37,8 @@ acpi0 at bios?
>  #acpicpu* at acpi?
>  acpicmos* at acpi?
>  acpiec* at acpi?
> +acpipci* at acpi?
> +pci* at acpipci?
>  acpiprt* at acpi?
>  acpimadt0 at acpi?
>  #acpitz* at acpi?
> Index: arch/amd64/conf/files.amd64
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/conf/files.amd64,v
> retrieving revision 1.104
> diff -u -p -r1.104 files.amd64
> --- arch/amd64/conf/files.amd64 7 Sep 2019 13:46:19 -0000 1.104
> +++ arch/amd64/conf/files.amd64 7 Sep 2019 14:04:46 -0000
> @@ -237,7 +237,7 @@ attach acpi at bios
>  file arch/amd64/amd64/acpi_machdep.c acpi
>  file arch/amd64/amd64/acpi_wakecode.S acpi & !small_kernel
>
> -device acpipci
> +device acpipci: pcibus
>  attach acpipci at acpi
>  file arch/amd64/pci/acpipci.c acpipci
>
> Index: arch/amd64/pci/acpipci.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/pci/acpipci.c,v
> retrieving revision 1.3
> diff -u -p -r1.3 acpipci.c
> --- arch/amd64/pci/acpipci.c 7 Sep 2019 13:46:19 -0000 1.3
> +++ arch/amd64/pci/acpipci.c 7 Sep 2019 14:04:46 -0000
> @@ -53,6 +53,19 @@ struct acpipci_softc {
>   struct device sc_dev;
>   struct acpi_softc *sc_acpi;
>   struct aml_node *sc_node;
> +
> + bus_space_tag_t sc_iot;
> + bus_space_tag_t sc_memt;
> + bus_dma_tag_t sc_dmat;
> +
> + struct extent *sc_busex;
> + struct extent *sc_memex;
> + struct extent *sc_ioex;
> + char sc_busex_name[32];
> + char sc_ioex_name[32];
> + char sc_memex_name[32];
> + int sc_bus;
> + uint32_t sc_seg;
>  };
>
>  int acpipci_match(struct device *, void *, void *);
> @@ -72,6 +85,11 @@ const char *acpipci_hids[] = {
>   NULL
>  };
>
> +void acpipci_attach_deferred(struct device *);
> +int acpipci_print(void *, const char *);
> +int acpipci_parse_resources(int, union acpi_resource *, void *);
> +void acpipci_osc(struct acpipci_softc *);
> +
>  int
>  acpipci_match(struct device *parent, void *match, void *aux)
>  {
> @@ -86,15 +104,167 @@ acpipci_attach(struct device *parent, st
>  {
>   struct acpi_attach_args *aaa = aux;
>   struct acpipci_softc *sc = (struct acpipci_softc *)self;
> - struct aml_value args[4];
>   struct aml_value res;
> - static uint8_t uuid[16] = ACPI_PCI_UUID;
> - uint32_t buf[3];
> + uint64_t bbn = 0;
> + uint64_t seg = 0;
>
>   sc->sc_acpi = (struct acpi_softc *)parent;
>   sc->sc_node = aaa->aaa_node;
>   printf(" %s", sc->sc_node->name);
>
> + if (aml_evalname(sc->sc_acpi, sc->sc_node, "_CRS", 0, NULL, &res)) {
> + printf(": can't find resources\n");
> + return;
> + }
> +
> + aml_evalinteger(sc->sc_acpi, sc->sc_node, "_BBN", 0, NULL, &bbn);
> + sc->sc_bus = bbn;
> +
> + aml_evalinteger(sc->sc_acpi, sc->sc_node, "_SEG", 0, NULL, &seg);
> + sc->sc_seg = seg;
> +
> + /* Create extents for our address spaces. */
> + snprintf(sc->sc_busex_name, sizeof(sc->sc_busex_name),
> +    "%s pcibus", sc->sc_dev.dv_xname);
> + snprintf(sc->sc_ioex_name, sizeof(sc->sc_ioex_name),
> +    "%s pciio", sc->sc_dev.dv_xname);
> + snprintf(sc->sc_memex_name, sizeof(sc->sc_memex_name),
> +    "%s pcimem", sc->sc_dev.dv_xname);
> + sc->sc_busex = extent_create(sc->sc_busex_name, 0, 255,
> +    M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED);
> + sc->sc_ioex = extent_create(sc->sc_ioex_name, 0, 0xffffffff,
> +    M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED);
> + sc->sc_memex = extent_create(sc->sc_memex_name, 0, (u_long)-1,
> +    M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED);
> +
> + aml_parse_resource(&res, acpipci_parse_resources, sc);
> +
> + acpipci_osc(sc);
> +
> + printf("\n");
> +
> + extent_print(sc->sc_busex);
> + extent_print(sc->sc_ioex);
> + extent_print(sc->sc_memex);
> +
> + acpi_haspci = 1;
> +
> + sc->sc_iot = aaa->aaa_iot;
> + sc->sc_memt = aaa->aaa_memt;
> + sc->sc_dmat = aaa->aaa_dmat;
> +
> + config_defer(self, acpipci_attach_deferred);
> +}
> +
> +void
> +acpipci_attach_deferred(struct device *self)
> +{
> + struct acpipci_softc *sc = (struct acpipci_softc *)self;
> + struct pcibus_attach_args pba;
> +
> + memset(&pba, 0, sizeof(pba));
> + pba.pba_busname = "pci";
> + pba.pba_iot = sc->sc_iot;
> + pba.pba_memt = sc->sc_memt;
> + pba.pba_dmat = sc->sc_dmat;
> + pba.pba_busex = sc->sc_busex;
> + pba.pba_ioex = sc->sc_ioex;
> + pba.pba_memex = sc->sc_memex;
> + pba.pba_pmemex = sc->sc_memex;
> + pba.pba_domain = pci_ndomains++;
> + pba.pba_bus = sc->sc_bus;
> +
> + /* Enable MSI in ACPI 2.0 and above, unless we're told not to. */
> + if (sc->sc_acpi->sc_fadt->hdr.revision >= 2 &&
> +    (sc->sc_acpi->sc_fadt->iapc_boot_arch & FADT_NO_MSI) == 0)
> + pba.pba_flags |= PCI_FLAGS_MSI_ENABLED;
> +
> + config_found(self, &pba, acpipci_print);
> +}
> +
> +int
> +acpipci_print(void *aux, const char *pnp)
> +{
> + struct pcibus_attach_args *pba = aux;
> +
> + if (pnp)
> + printf("%s at %s", pba->pba_busname, pnp);
> + printf(" bus %d", pba->pba_bus);
> + return (UNCONF);
> +}
> +
> +int
> +acpipci_parse_resources(int crsidx, union acpi_resource *crs, void *arg)
> +{
> + struct acpipci_softc *sc = arg;
> + int type = AML_CRSTYPE(crs);
> + int restype, tflags = 0;
> + u_long min, len = 0, tra = 0;
> +
> + switch (type) {
> + case LR_WORD:
> + restype = crs->lr_word.type;
> + tflags = crs->lr_word.tflags;
> + min = crs->lr_word._min;
> + len = crs->lr_word._len;
> + tra = crs->lr_word._tra;
> + break;
> + case LR_DWORD:
> + restype = crs->lr_dword.type;
> + tflags = crs->lr_dword.tflags;
> + min = crs->lr_dword._min;
> + len = crs->lr_dword._len;
> + tra = crs->lr_dword._tra;
> + break;
> + case LR_QWORD:
> + restype = crs->lr_qword.type;
> + tflags = crs->lr_qword.tflags;
> + min = crs->lr_qword._min;
> + len = crs->lr_qword._len;
> + tra = crs->lr_qword._tra;
> + break;
> + case LR_MEM32FIXED:
> + /*
> + * Coreboot on the PC Engines apu2 incorrectly uses a
> + * Memory32Fixed resource descriptor to describe mmio
> + * address space forwarded to the PCI bus.
> + */
> + restype = LR_TYPE_MEMORY;
> + min = crs->lr_m32fixed._bas;
> + len = crs->lr_m32fixed._len;
> + break;
> + }
> +
> + if (len == 0)
> + return 0;
> +
> + switch (restype) {
> + case LR_TYPE_MEMORY:
> + if (tflags & LR_MEMORY_TTP)
> + return 0;
> + extent_free(sc->sc_memex, min, len, EX_WAITOK | EX_CONFLICTOK);
> + break;
> + case LR_TYPE_IO:
> + if (tflags & LR_IO_TTP)
> + return 0;
> + extent_free(sc->sc_ioex, min, len, EX_WAITOK | EX_CONFLICTOK);
> + break;
> + case LR_TYPE_BUS:
> + extent_free(sc->sc_busex, min, len, EX_WAITOK);
> + break;
> + }
> +
> + return 0;
> +}
> +
> +void
> +acpipci_osc(struct acpipci_softc *sc)
> +{
> + struct aml_value args[4];
> + struct aml_value res;
> + static uint8_t uuid[16] = ACPI_PCI_UUID;
> + uint32_t buf[3];
> +
>   memset(args, 0, sizeof(args));
>   args[0].type = AML_OBJTYPE_BUFFER;
>   args[0].v_buffer = uuid;
> @@ -112,10 +282,8 @@ acpipci_attach(struct device *parent, st
>   buf[1] = ACPI_PCI_PCIE_CONFIG | ACPI_PCI_MSI;
>   buf[2] = ACPI_PCI_PCIE_HOTPLUG;
>
> - if (aml_evalname(sc->sc_acpi, sc->sc_node, "_OSC", 4, args, &res)) {
> - printf(": _OSC failed\n");
> + if (aml_evalname(sc->sc_acpi, sc->sc_node, "_OSC", 4, args, &res))
>   return;
> - }
>
>   if (res.type == AML_OBJTYPE_BUFFER) {
>   size_t len = res.length;
> @@ -128,6 +296,4 @@ acpipci_attach(struct device *parent, st
>   len -= 4;
>   }
>   }
> -
> - printf("\n");
>  }
> Index: arch/amd64/pci/pci_machdep.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/pci/pci_machdep.c,v
> retrieving revision 1.73
> diff -u -p -r1.73 pci_machdep.c
> --- arch/amd64/pci/pci_machdep.c 7 Sep 2019 13:46:19 -0000 1.73
> +++ arch/amd64/pci/pci_machdep.c 7 Sep 2019 14:04:46 -0000
> @@ -189,24 +189,11 @@ pci_attach_hook(struct device *parent, s
>
>   switch (PCI_VENDOR(id)) {
>   case PCI_VENDOR_INTEL:
> - /*
> - * In the wonderful world of virtualization you can
> - * have the latest 64-bit AMD multicore CPU behind a
> - * prehistoric Intel host bridge.  Give them what they
> - * deserve.
> - */
> - switch (PCI_PRODUCT(id)) {
> - case PCI_PRODUCT_INTEL_82441FX: /* QEMU */
> - case PCI_PRODUCT_INTEL_82443BX: /* VMWare */
> - break;
> - default:
> - pba->pba_flags |= PCI_FLAGS_MSI_ENABLED;
> - break;
> - }
> - break;
>   case PCI_VENDOR_NVIDIA:
>   case PCI_VENDOR_AMD:
> - pba->pba_flags |= PCI_FLAGS_MSI_ENABLED;
> + break;
> + default:
> + pba->pba_flags &= ~PCI_FLAGS_MSI_ENABLED;
>   break;
>   }
>

dmesg-backout (10K) Download Attachment
dmesg-extfree (11K) Download Attachment
pcidump-backout (50K) Download Attachment
pcidump-extfree (50K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: extent_free fixes

Mark Kettenis
> Date: Mon, 9 Sep 2019 13:29:32 +0200
> From: Alexander Bluhm <[hidden email]>
>
> On Sat, Sep 07, 2019 at 04:07:22PM +0200, Mark Kettenis wrote:
> > The diff below should fix one of the issues uncovered by the
> > acpipci(4) changes that I just backed out.
> >
> > On some systems, ACPI specifies overlapping regions of address space
> > that gets forwarded to the PCI bus.  Since we use extent_free(9) to
> > make those regions of address space available, that code needs to be
> > able to handle overlaps.
> >
> > Since the acpipci(4) has been backed out, I attach the diff (with
> > debug print code) below.  Alexander, it would be great if you can test
> > this on that SuperMicro box.
>
> No strange errors in dmesg anymore.  Regress passes.
> Dmesg and pcidump without and with this diff attached.

Thanks.  Good!  That means I'd like to see some ok's now ;).



Index: sys/kern/subr_extent.c
===================================================================
RCS file: /cvs/src/sys/kern/subr_extent.c,v
retrieving revision 1.61
diff -u -p -r1.61 subr_extent.c
--- sys/kern/subr_extent.c 28 Aug 2019 22:22:43 -0000 1.61
+++ sys/kern/subr_extent.c 7 Sep 2019 13:55:01 -0000
@@ -962,6 +962,7 @@ int
 extent_free(struct extent *ex, u_long start, u_long size, int flags)
 {
  struct extent_region *rp, *nrp = NULL;
+ struct extent_region *tmp;
  u_long end = start + (size - 1);
  int exflags;
  int error = 0;
@@ -1019,8 +1020,12 @@ extent_free(struct extent *ex, u_long st
  *
  * Cases 2, 3, and 4 require that the EXF_NOCOALESCE flag
  * is not set.
+ *
+ * If the EX_CONFLICTOK flag is set, partially overlapping
+ * regions are allowed.  This is handled in cases 1a, 2a and
+ * 3a below.
  */
- LIST_FOREACH(rp, &ex->ex_regions, er_link) {
+ LIST_FOREACH_SAFE(rp, &ex->ex_regions, er_link, tmp) {
  /*
  * Save ourselves some comparisons; does the current
  * region end before chunk to be freed begins?  If so,
@@ -1080,12 +1085,28 @@ extent_free(struct extent *ex, u_long st
  nrp = NULL;
  goto done;
  }
+
+ if ((flags & EX_CONFLICTOK) == 0)
+ continue;
+
+ /* Case 1a. */
+ if ((start <= rp->er_start && end >= rp->er_end)) {
+ LIST_REMOVE(rp, er_link);
+ extent_free_region_descriptor(ex, rp);
+ continue;
+ }
+
+ /* Case 2a. */
+ if ((start <= rp->er_start) && (end >= rp->er_start))
+ rp->er_start = (end + 1);
+
+ /* Case 3a. */
+ if ((start <= rp->er_end) && (end >= rp->er_end))
+ rp->er_end = (start - 1);
  }
 
- if (flags & EX_CONFLICTOK) {
- error = EINVAL;
+ if (flags & EX_CONFLICTOK)
  goto done;
- }
 
  /* Region not found, or request otherwise invalid. */
 #if defined(DIAGNOSTIC) || defined(DDB)
Index: regress/sys/kern/extent/extest.awk
===================================================================
RCS file: /cvs/src/regress/sys/kern/extent/extest.awk,v
retrieving revision 1.2
diff -u -p -r1.2 extest.awk
--- regress/sys/kern/extent/extest.awk 10 Apr 2009 20:57:04 -0000 1.2
+++ regress/sys/kern/extent/extest.awk 7 Sep 2019 13:55:01 -0000
@@ -67,7 +67,12 @@ $1 == "alloc_subregion" {
 }
 
 $1 == "free" {
- printf("error = extent_free(ex, %s, %s, 0);\n", $2, $3)
+ if ($4 == "") {
+ flags = "0";
+ } else {
+ flags = $4;
+ }
+ printf("error = extent_free(ex, %s, %s, %s);\n", $2, $3, flags)
  printf("if (error)\n\tprintf(\"error: %%s\\n\", strerror(error));\n")
 }
 
Index: regress/sys/kern/extent/extest.exp
===================================================================
RCS file: /cvs/src/regress/sys/kern/extent/extest.exp,v
retrieving revision 1.4
diff -u -p -r1.4 extest.exp
--- regress/sys/kern/extent/extest.exp 13 Oct 2009 20:53:40 -0000 1.4
+++ regress/sys/kern/extent/extest.exp 7 Sep 2019 13:55:01 -0000
@@ -92,3 +92,13 @@ extent `test16' (0x0 - 0xffffffff), flag
 output for test17
 extent `test17' (0x0 - 0xffffffffffffffff), flags = 0x0
      0x0 - 0xffffffffffffffff
+output for test18
+extent `test18' (0x0 - 0xffff), flags = 0x0
+     0x0 - 0xcff
+     0xf000 - 0xffff
+output for test19
+extent `test19' (0x0 - 0xffff), flags = 0x0
+     0x0 - 0xcff
+output for test20
+extent `test20' (0x0 - 0xffff), flags = 0x0
+     0xf000 - 0xffff
Index: regress/sys/kern/extent/tests
===================================================================
RCS file: /cvs/src/regress/sys/kern/extent/tests,v
retrieving revision 1.5
diff -u -p -r1.5 tests
--- regress/sys/kern/extent/tests 13 Oct 2009 20:53:40 -0000 1.5
+++ regress/sys/kern/extent/tests 7 Sep 2019 13:55:01 -0000
@@ -136,3 +136,19 @@ print
 extent test17 0x00000000 -1L EX_FILLED
 alloc_region 0 0x4000 EX_CONFLICTOK
 print
+
+# Check freeing overkapping regions from a filled extent
+extent test18 0x0000 0xffff EX_FILLED
+free 0x164e 0x2
+free 0x0d00 0xe300 EX_CONFLICTOK
+print
+
+extent test19 0x0000 0xffff EX_FILLED
+free 0x164e 0x2
+free 0x0d00 0xf300 EX_CONFLICTOK
+print
+
+extent test20 0x0000 0xffff EX_FILLED
+free 0x164e 0x2
+free 0x0000 0xf000 EX_CONFLICTOK
+print