[haiku-commits] haiku: hrev53610 - src/libs/compat/freebsd_network

  • From: waddlesplash <waddlesplash@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 2 Dec 2019 20:43:23 -0500 (EST)

hrev53610 adds 1 changeset to branch 'master'
old head: 70cdd7d4f5fc62e8b3e220646f84235ec3d444d5
new head: 7100b1e1f545c900db7e27ba61242002a91279cf
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=7100b1e1f545+%5E70cdd7d4f5fc

----------------------------------------------------------------------------

7100b1e1f545: freebsd_network: Move segment array allocation in bus_dma to 
dmamap_create().
  
  It seems that some drivers (e.g. broadcom43xx) create a parent DMA tag
  with nsegments set to BUS_SPACE_UNRESTRICTED, i.e. MAX_INT, which of
  course fails allocation, expecting to never allocate memory for this
  tag, only for child tags. So in order to handle this, we have to
  delay allocating the segment array until we are certain that the nsegments
  value is the "real deal".
  
  Doing it in dmamap_load would be fine, but as there is more than one
  entry point to that, we would have to allocate this in multiple places.
  dmamap_create() must be called and there is only one way through it,
  so put the allocation there.
  
  Fixes #15500 (i.e. both the KDL and the underlying problem that
  led to it; it only crashed because the wrong pointer was passed
  to kernel_free, whoops.)

                                   [ waddlesplash <waddlesplash@xxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev53610
Commit:      7100b1e1f545c900db7e27ba61242002a91279cf
URL:         https://git.haiku-os.org/haiku/commit/?id=7100b1e1f545
Author:      waddlesplash <waddlesplash@xxxxxxxxx>
Date:        Tue Dec  3 01:37:52 2019 UTC

Ticket:      https://dev.haiku-os.org/ticket/15500

----------------------------------------------------------------------------

1 file changed, 11 insertions(+), 8 deletions(-)
src/libs/compat/freebsd_network/bus_dma.cpp | 19 +++++++++++--------

----------------------------------------------------------------------------

diff --git a/src/libs/compat/freebsd_network/bus_dma.cpp 
b/src/libs/compat/freebsd_network/bus_dma.cpp
index 6b588fadf5..e2bce61aca 100644
--- a/src/libs/compat/freebsd_network/bus_dma.cpp
+++ b/src/libs/compat/freebsd_network/bus_dma.cpp
@@ -84,14 +84,6 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t 
alignment, bus_size_t bounda
        newtag->maxsegsz = maxsegsz;
        newtag->ref_count = 1;
 
-       newtag->segments = (bus_dma_segment_t*)kernel_malloc(
-               sizeof(bus_dma_segment_t) * newtag->nsegments, M_DEVBUF,
-               M_NOWAIT);
-       if (newtag->segments == NULL) {
-               kernel_free(dmat, M_DEVBUF);
-               return ENOMEM;
-       }
-
        if (newtag->parent != NULL) {
                atomic_add(&parent->ref_count, 1);
 
@@ -147,6 +139,17 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, 
bus_dmamap_t* mapp)
 {
        // We never bounce, so we do not need maps.
        *mapp = NULL;
+
+       // However, since bus_dmamap_create() must be called before buffers
+       // are loaded, we allocate the "segments" field (if not yet done.)
+       if (dmat->segments == NULL) {
+               dmat->segments = (bus_dma_segment_t*)kernel_malloc(
+                       sizeof(bus_dma_segment_t) * dmat->nsegments, M_DEVBUF,
+                       M_ZERO | M_NOWAIT);
+               if (dmat->segments == NULL)
+                       return ENOMEM;
+       }
+
        return 0;
 }
 


Other related posts:

  • » [haiku-commits] haiku: hrev53610 - src/libs/compat/freebsd_network - waddlesplash