From owner-freebsd-sparc Fri Jan 17 6:34:43 2003 Delivered-To: freebsd-sparc@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id DF8F237B401; Fri, 17 Jan 2003 06:34:40 -0800 (PST) Received: from mailhub.fokus.gmd.de (mailhub.fokus.gmd.de [193.174.154.14]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7347043EB2; Fri, 17 Jan 2003 06:34:39 -0800 (PST) (envelope-from brandt@fokus.gmd.de) Received: from beagle (beagle [193.175.132.100]) by mailhub.fokus.gmd.de (8.11.6/8.11.6) with ESMTP id h0HEYbM13061; Fri, 17 Jan 2003 15:34:37 +0100 (MET) Date: Fri, 17 Jan 2003 15:34:37 +0100 (CET) From: Harti Brandt To: tmm@freebsd.org Cc: sparc@freebsd.org Subject: Problem with iommu_dvmamap_create Message-ID: <20030117151958.U715@beagle.fokus.gmd.de> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-sparc@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org Hi, it seems, there is a problem in this function. I have a case, where my driver creates a dma_tag with a maxsize of 64k-1, a maximum segment size of 64k-1 and a large maximum number of segments (say 30...40). As soon, as I create a DMA map with this tag, the io gets botched (up to the point, that the boot prom reports a nvram checksum error). When I comment out the code in iommu.c as follows I can at least create and destroy the maps without any bad effect (I did not try to load them yet): int iommu_dvmamap_create(bus_dma_tag_t pt, bus_dma_tag_t dt, struct iommu_state *is, int flags, bus_dmamap_t *mapp) { bus_size_t totsz, presz, currsz; int error, i, maxpre; if ((error = sparc64_dmamap_create(pt->dt_parent, dt, flags, mapp)) != 0) return (error); KASSERT(SLIST_EMPTY(&(*mapp)->dm_reslist), ("iommu_dvmamap_create: hierarchy botched")); iommu_map_insq(*mapp); /* * Preallocate DVMA space; if this fails now, it is retried at load * time. Through bus_dmamap_load_mbuf() and bus_dmamap_load_uio(), it * is possible to have multiple discontiguous segments in a single map, * which is handled by allocating additional resources, instead of * increasing the size, to avoid fragmentation. * Clamp preallocation to BUS_SPACE_MAXSIZE. In some situations we can * handle more; that case is handled by reallocating at map load time. */ totsz = ulmin(IOMMU_SIZE_ROUNDUP(dt->dt_maxsize), IOMMU_MAX_PRE); error = iommu_dvma_valloc(dt, is, *mapp, totsz); if (error != 0) return (0); #if 0 /* * Try to be smart about preallocating some additional segments if * needed. */ maxpre = imin(dt->dt_nsegments, IOMMU_MAX_PRE_SEG); presz = dt->dt_maxsize / maxpre; for (i = 0; i < maxpre && totsz < IOMMU_MAX_PRE; i++) { currsz = round_io_page(ulmin(presz, IOMMU_MAX_PRE - totsz)); error = iommu_dvma_valloc(dt, is, *mapp, currsz); if (error != 0) break; totsz += currsz; } #endif return (0); } The problem seems to be the dt_maxsize / maxpre. In my case this evaluates to 0 and the call to valloc will use a currsz of 0. This seems to have bad effects on the resource manager. Also the loop will allocate one segment more than it needs (it does not count the first allocation). This is, however, not critical. I suggest also changing the comment above - it mentions BUS_SPACE_MAXSIZE, but BUS_SPACE_MAXSIZE does not figure in the code (should be IOMMU_MAX_PRE probably, which happens to be BUS_SPACE_MAXSIZE). Regards, harti -- harti brandt, http://www.fokus.gmd.de/research/cc/cats/employees/hartmut.brandt/private brandt@fokus.gmd.de, brandt@fokus.fhg.de To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-sparc" in the body of the message