From owner-freebsd-hackers Mon Jan 22 12:42:28 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from mass.dis.org (mass.dis.org [216.240.45.41]) by hub.freebsd.org (Postfix) with ESMTP id 0D0C337B69C for ; Mon, 22 Jan 2001 12:42:08 -0800 (PST) Received: from mass.dis.org (localhost [127.0.0.1]) by mass.dis.org (8.11.1/8.11.1) with ESMTP id f0MKvL001244; Mon, 22 Jan 2001 12:57:21 -0800 (PST) (envelope-from msmith@mass.dis.org) Message-Id: <200101222057.f0MKvL001244@mass.dis.org> X-Mailer: exmh version 2.1.1 10/15/1999 To: Robert Lipe Cc: Alfred Perlstein , freebsd-hackers@FreeBSD.ORG Subject: Re: contigmalloc, M_WAITOK, & leaks. In-reply-to: Your message of "Mon, 22 Jan 2001 12:41:34 PST." <200101222041.f0MKfY001170@mass.dis.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Date: Mon, 22 Jan 2001 12:57:21 -0800 From: Mike Smith Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG > > Is there an s/g memory interface in FreeBSD? This was my first choice, > > but since I couldn't find a set of functions to build a list of buffers > > that satisfied a set of constraints, I fell back to contigmalloc to get > > things off the ground. I'd be delighted to use an interface to get me > > an s/g list with a given set of constraints that pointed to a list of > > buffers with a given set of constraints. > > Yes; this is where the busdma stuff comes in. Use bus_dma_tag_create to > create a DMA tag which defines the costraints applicable to your DMA-able > memory. Then you can either use bus_dmamem_alloc/bus_dmamem_free to > allocate conforming memory, or just take memory in the kernel's address > space. In either case, you use bus_dmamap_load to build the scatter/ > gather list (and possibly perform other setup work), bus_dmamap_unload > to tear down any of the setup work, and bus_dmamem_sync to perform > possibly-required bounce buffering, bus scatter/gather control, etc. Urk. I should avoid replying to messages in the first 20 minutes or so after I wake up; my dreams get confused with reality. With dma-conformant allocated memory: struct buf_cluster { void *vaddr; vm_offset_t paddr; bus_dmamap_t map; } bus_dma_tag_create(parent_tag, ... &tag); bus_dmamem_alloc(tag, &cluster.vaddr, BUS_DMA_NOWAIT, &cluster.map); bus_dmamap_load(tag, cluster.map, cluster.vaddr, cluster_size, cluster_helper_func, &cluster, 0) ... void cluster_helper_func(void *arg, bus_dma_segment_t *segs, int nseg, int error) { struct buf_cluster *cluster = (struct buf_cluster *)arg; cluster->paddr = segs[0].ds_addr; } The above case works if you've specified the tag as giving you a single, unfragmented allocation. If you took a more generous route and allowed it to be fragmented because your structures would never cross a page boundary then you would want to make the helper function more elaborate; the scatter gather list is in the usual base/length format in the segs array, and nsegs of course gives you its length. I hope this helps, there are lots of examples of the use of this interface scattered throughout the tree. -- ... every activity meets with opposition, everyone who acts has his rivals and unfortunately opponents also. But not because people want to be opponents, rather because the tasks and relationships force people to take different points of view. [Dr. Fritz Todt] V I C T O R Y N O T V E N G E A N C E To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message