On Tue, 2018-05-08 at 17:57 +0000, Rodriguez, Edwin wrote: > The problem currently with the dpdk based implementation of spdk_malloc is > that it ignores the flag altogether so somebody could pass in 0 without it > ever being noticed. https://review.gerrithub.io/#/c/spdk/spdk/+/410479/ Hopefully this check will prevent people from using spdk_malloc in a way that isn't implementable for your env. > > From: "Walker, Benjamin" > Date: Tuesday, May 8, 2018 at 1:54 PM > To: Ed Rodriguez , "spdk(a)lists.01.org" .org>, "z.khatami88(a)gmail.com" , "Harris, James R" es.r.harris(a)intel.com> > Subject: Re: [SPDK] spdk_malloc vs. malloc > > On Tue, 2018-05-08 at 17:35 +0000, Rodriguez, Edwin wrote: > > Something like this would work for NetApp: > > > > enum spdk_malloc_flags { > > SPDK_MALLOC_DMA, > > SPDK_MALLOC_SHARE, > > SPDK_MALLOC_DMA_SHARE > > }; > > void *spdk_malloc(size_t size, size_t align, uint64_t *phys_addr, int > > socket_id, enum spdk_malloc_flags flags); > > > This is very close to the code that is already merged. The code today uses > #defines instead of an enum, and DMA is 1, SHARE is 2, and DMA+SHARE is 3, but > it's otherwise the same thing. Although in the current code it is technically > possible to pass no flags while in your definition it is not possible, it is > already the case that passing no flags is not valid and the call should fail. > > The flags are definitely intended to be prohibited from being 0, which I think > is the key requirement for you guys. We can make that clearer in the > documentation for sure. > > > > > Ed R > > > > > > From: SPDK on behalf of Ed Rodriguez > > > @netapp.com> > > Reply-To: Storage Performance Development Kit > > Date: Monday, May 7, 2018 at 1:39 PM > > To: "Walker, Benjamin" , "Harris, James R" > > > .harris(a)intel.com>, "spdk(a)lists.01.org" , "z.khatami88(a)gm > > ai > > l.com" > > Subject: Re: [SPDK] spdk_malloc vs. malloc > > > > spdk_malloc could work for cases 2-4 if the flags param were prohibited from > > being 0 - in our implementation we don't do anything special for shared > > memory > > so spdk_free can continue to call the equivalent of spdk_dma_free. > > > > Ed R > > > > On 5/7/18, 1:19 PM, "Walker, Benjamin" wrote: > > > > SPDK needs four different types of memory allocation operations today: > > > > 1) Standard virtual memory > > 2) Process-shared memory > > 3) DMA-safe memory ("pinned") > > 4) DMA-safe and process-shared memory > > > > For #1, SPDK is using POSIX to do that allocation and free. That one is > > a > > very > > separate discussion than the other 3, so I'll leave that alone. > > > > For numbers 2-4, SPDK could either have 3 separate functions or one > > function > > with flags to do the allocations. I don't think the allocation side > > choice > > makes > > much of a difference. On the free side, however, we need to decide if > > we're > > going to do one generic spdk_free(void *buf), an spdk_free with flags, > > or > > 3 > > separate free functions corresponding to 3 separate allocation > > functions. > > We're > > currently moving toward spdk_malloc with flags and spdk_free without, > > but > > that > > is up for debate. > > > > There are at least 3 known implementations of the SPDK env layer today, > > so > > I'll > > attempt to outline what each of those needs so we have some concrete > > examples. > > > > The primary implementation of the env layer, which ships with SPDK, is > > the > > one > > based on DPDK. DPDK internally always allocates all memory as both DMA- > > safe and > > shared, so the distinction there isn't necessary. Essentially, > > allocation > > types > > 2-4 are all degenerate and map to a single DPDK call. On the free side, > > DPDK > > does not need to know what type of allocation it was (again, because > > they're all > > degenerate). > > > > One known alternative implementation (Oracle) has three separate > > operations > > corresponding to memory allocation types 2, 3, and 4. However, my > > understanding > > is that they also have internal tracking structures such that they can > > figure > > out which type of allocation an address came from originally, so they > > are > > able > > to implement spdk_free(void *buf) by doing internal look-ups and don't > > need the > > user to pass them flags. > > > > Another known alternative implementation (NetApp) has two memory > > allocation > > operations internally. One corresponds to both types 1 and 2, and the > > other > > corresponds to types 3 and 4. Further, on the free side there are > > different free > > functions for types 1 and 2 compared to types 3 and 4. The current > > abstraction > > in SPDK has a single call for types 2-4 with no flags, so it's valid > > criticism > > that this API is difficult for NetApp to implement. We need to figure > > out > > a way > > to address this. > > > > The easiest solution today, in my opinion, is for the NetApp > > implementation to > > always allocate DMA-safe memory in response to calls to spdk_malloc, > > even > > if > > only the shared flag was specified (case #2). Note that SPDK doesn't > > call > > spdk_malloc for case #1 already, so that's a separate code path. Then > > always do > > the DMA-safe memory free in response to spdk_free. That will definitely > > make it > > work correctly today, and then the NetApp implementation doesn't need > > the > > flags > > on free either. > > > > I'd love to have as many people weigh in here as possible. The more > > diverse > > opinions we get, the better the ultimate design will be. We absolutely > > have to > > make sure this memory abstraction is solid and meets everyone's needs, > > while > > still being reasonably simple to use. > > > > Thanks, > > Ben > > > > > > On Fri, 2018-05-04 at 17:17 -0700, Harris, James R wrote: > > > You’re right Ed. We’ll need to hold off on adding usages of this new > > API > > > until we get this sorted out. > > > > > > What if we just add an spdk_dma_shared_malloc() and got rid of the > > flags > > > completely? And then just keep all of the existing malloc/free calls > > where > > > DMA/shared memory is not required. This should alleviate the impact > > to > > your > > > code base and I *think* would work for Oracle – but would need Zahra > > to > > > confirm. This adds an explicit assumption of course that we won’t > > have > > a need > > > for some other kind of malloc ‘flag’ in the future. > > > > > > Sorry John – I know you wanted to end this thread but I’ve decided to > > continue > > > it. ( > > > > > > -Jim > > > > > > > > > > > > On 5/4/18, 3:37 PM, "Rodriguez, Edwin" > > wrote: > > > > > > The problem I have with the new code is that it makes > > distinguishing > > > between dma and non-dma free difficult. In the kernel, dma memory > > comes > > from > > > a different pool than regular allocations, i.e. > > contigmalloc/contigfree > > in > > > FreeBsd. How does spdk_free distinguish between a block allocated > > with > > > SPDK_MALLOC_DMA and a regular block? > > > > > > Ed R > > > > > > On 5/4/18, 6:30 PM, "SPDK on behalf of Meneghini, John" > bounce > > s(a)list > > > s.01.org on behalf of John.Meneghini(a)netapp.com> wrote: > > > > > > Thanks, Ben, et al, for your reply. > > > > > > > you may want to avoid calling them at run-time because they > > can > > > fail, but SPDK generally already does > > > > that for performance reasons anyway. Can you outline what > > you > > mean? > > > > > > What is run-time? We are using the SPDK libraries inside of > > a > > kernel > > > kmod. So, all time is run-time. > > > > > > I think we can end this thread. I tried to win this argument > > once > > > before. I guess calloc() and malloc() are here to stay... so > > > it doesn't matter what we do with spdk_malloc(). > > > > > > :-) > > > > > > If anyone wants to ask me about my views on this topic, I'll > > be > > at the > > > SPDK Developer's Summit in two weeks. > > > > > > See you then. > > > > > > /John > > > > > > On 5/3/18, 7:24 PM, "Walker, Benjamin" > .co > > m> > > > wrote: > > > > > > On Thu, 2018-05-03 at 20:14 +0000, Meneghini, John wrote: > > > > The issue is: spdk_malloc and spdk_calloc are logical > > APIs > > to > > > abstract the > > > > POSIX malloc and calloc calls. We chose to NOT use > > those > > API > > > names originally > > > > and went with the spdk_dma_{} api names. My concern is > > that > > > taking those API > > > > names now will eliminate the possibility of any other > > use > > in the > > > future. > > > > > > > > I am not asking to "fully abstract POSIX". I am simply > > saying > > > that the > > > > malloc(), calloc() and free() POSIX APIs suffer from > > some > > > problems. This is > > > > why DPDK implemented rte_malloc() and rte_calloc(). > > As > > we move > > > forward to > > > > build production quality products out of SPDK we will > > want > > to > > > abstract malloc, > > > > calloc and free; especially in the libraries. I don't > > care > > > about what the > > > > applications do. I want a better memory management > > APIs > > in the > > > libraries. > > > > > > DPDK implemented rte_malloc and rte_calloc to allocate > > DMA- > > safe > > > and shared > > > memory. They still call POSIX malloc and calloc for all > > other > > > types of > > > allocations. This is the same thing that SPDK has done. > > > > > > I've never heard of malloc, calloc, and free having > > problems > > to > > > the extent that > > > you'd want to reimplement them in your application some > > other way. > > > Certainly, > > > you may want to avoid calling them at run-time because > > they > > can > > > fail, but SPDK > > > generally already does that for performance reasons > > anyway. > > Can > > > you outline what > > > you mean? > > > > > > > > > > > I'd be happy to simply map spdk_malloc/calloc() to > > > rte_malloc/calloc() and I > > > > don't see the point introducing an spdk_malloc() that > > only > > > extends > > > > spdk_dma_malloc(). I'd rather absorb an API change to > > > spdk_dma_malloc(). We > > > > change many APIs in SPDK from release to release. I > > don't > > see > > > why this API > > > > can't be changed - with agreement from the SPDK > > community. > > > > > > > > /* > > > > * Allocate memory on default heap. > > > > */ > > > > void * > > > > rte_malloc(const char *type, size_t size, unsigned > > align) > > > > { > > > > return rte_malloc_socket(type, size, align, > > > SOCKET_ID_ANY); > > > > } > > > > > > > > /* > > > > * Allocate zero'd memory on default heap. > > > > */ > > > > void * > > > > rte_calloc(const char *type, size_t num, size_t size, > > unsigned > > > align) > > > > { > > > > return rte_zmalloc(type, num * size, align); > > > > } > > > > > > > > /John > > > > > > > > On 5/3/18, 3:21 PM, "Walker, Benjamin" > @in > > tel.co > > > m> wrote: > > > > > > > > On Thu, 2018-05-03 at 18:23 +0000, Meneghini, John > > wrote: > > > > > > If the user passes flags == 0 to the new > > spdk_malloc() > > > call, this > > > > could be > > > > > implemented by malloc() or equivalent behind the > > scenes, > > > > > > > > > > So, does this mean you’re willing to change all > > calls to > > > malloc(size) > > > > with > > > > > spdk_malloc(size, 0, NULL, > > SPDK_ENV_SOCKET_ID_ANY, > > > SPDK_MALLOC_SHARE)? > > > > > > > > > > Is that the plan? > > > > > > > > > > > > > Hi John, > > > > > > > > SPDK explicitly depends on POSIX throughout the > > code > > base. > > > We do have an > > > > environment abstraction layer designed to make > > porting > > SPDK > > > to various > > > > environments (i.e. away from DPDK) easier, but this > > only > > > abstracts > > > > operations > > > > that are not available through standard POSIX > > calls. > > We're > > > concerned that > > > > fully > > > > abstracting POSIX would introduce a significant > > barrier to > > > entry for new > > > > contributors to the project, while only enabling > > one > > > additional use case > > > > that > > > > we're aware of. I understand that this one use case > > happens > > > to be yours, > > > > and so > > > > this is a challenge for you. > > > > > > > > In your code today, I assume you carry patches to > > replace > > > the POSIX calls > > > > with > > > > your available alternatives. We've attempted to > > make > > > carrying these > > > > patches > > > > reasonably easy by moving all of the POSIX includes > > into a > > > single header > > > > (include/stdinc.h). Since you're already carrying > > those > > > patches, can you > > > > simply > > > > choose a different name for your replacement for > > > malloc/calloc? > > > > > > > > Thanks, > > > > Ben > > > > > > > > > > > > > > > > > _______________________________________________ > > > SPDK mailing list > > > SPDK(a)lists.01.org > > > https://lists.01.org/mailman/listinfo/spdk > > > > > > > > > > > > > > > > > > _______________________________________________ > > SPDK mailing list > > SPDK(a)lists.01.org > > https://lists.01.org/mailman/listinfo/spdk > > > >