void *m_ext_get(struct vmm_mbuf *m, u32 size, enum vmm_mbuf_alloc_types how) { void *buf; u32 slab; struct mempool *mp = NULL; if (VMM_MBUF_ALLOC_DMA == how) { buf = vmm_dma_malloc(size); if (!buf) { return NULL; } m->m_flags |= M_EXT_DMA; MEXTADD(m, buf, size, ext_dma_free, NULL); } else { for (slab = 0; slab < EPOOL_SLAB_COUNT; slab++) { if (size <= epool_slab_buf_size(slab)) { mp = mbpctrl.epool_slabs[slab]; break; } } if (mp && (buf = mempool_malloc(mp))) { m->m_flags |= M_EXT_POOL; MEXTADD(m, buf, size, ext_pool_free, mp); } else if ((buf = vmm_malloc(size))) { m->m_flags |= M_EXT_HEAP; MEXTADD(m, buf, size, ext_heap_free, NULL); } else { return NULL; } } return m->m_extbuf; }
void *vmm_dma_zalloc(virtual_size_t size) { void *ret = vmm_dma_malloc(size); if (ret) { memset(ret, 0, size); } return ret; }
/* * m_ext_dma_ensure: Ensure that the data buffer is DMA proof, reallocating * and copying data to do so. */ void m_ext_dma_ensure(struct vmm_mbuf *m) { char *buf = NULL; if (vmm_is_dma(m->m_extbuf)) { return; } buf = vmm_dma_malloc(m->m_len); memcpy(buf, m->m_extbuf, m->m_len); if (m->m_extfree) { m->m_extfree(m, m->m_extbuf, m->m_extlen, m->m_extarg); } else { vmm_free(m->m_extbuf); } MEXTADD(m, buf, m->m_len, ext_dma_free, 0); }