On Thu, Mar 14, 2019 at 01:45:20PM +0200, Gal Pressman wrote: > +/* > + * Since we don't track munmaps, we can't know when a user stopped using his > + * mmapped buffers. > + * This should be called on dealloc_ucontext in order to drain the mmap entries > + * and free the (unmapped) DMA buffers. > + */ > +static void mmap_entries_remove_free(struct efa_dev *dev, > + struct efa_ucontext *ucontext) > +{ > + struct efa_mmap_entry *entry, *tmp; > + > + mutex_lock(&ucontext->lock); > + list_for_each_entry_safe(entry, tmp, &ucontext->pending_mmaps, list) { > + list_del(&entry->list); > + efa_dbg(&dev->ibdev.dev, > + "mmap: obj[0x%p] key[%#llx] addr[%#llx] len[%#llx] removed\n", > + entry->obj, entry->key, entry->address, entry->length); > + if (get_mmap_flag(entry->key) == EFA_MMAP_DMA_PAGE) > + /* DMA mapping is already gone, now free the pages */ > + free_pages_exact(phys_to_virt(entry->address), > + entry->length); > + kfree(entry); > + } > + mutex_unlock(&ucontext->lock); > +} > + > +static struct efa_mmap_entry *mmap_entry_get(struct efa_dev *dev, > + struct efa_ucontext *ucontext, > + u64 key, > + u64 len) > +{ > + struct efa_mmap_entry *entry, *tmp; > + > + mutex_lock(&ucontext->lock); > + list_for_each_entry_safe(entry, tmp, &ucontext->pending_mmaps, list) { > + if (entry->key == key && entry->length == len) { > + efa_dbg(&dev->ibdev.dev, > + "mmap: obj[%p] key[0x%llx] addr[0x%llX] len[0x%llX] removed\n", > + entry->obj, key, entry->address, > + entry->length); > + mutex_unlock(&ucontext->lock); > + return entry; > + } > + } > + mutex_unlock(&ucontext->lock); > + > + return NULL; > +} > + > +static void mmap_entry_insert(struct efa_dev *dev, > + struct efa_ucontext *ucontext, > + struct efa_mmap_entry *entry, > + u8 mmap_flag) > +{ > + mutex_lock(&ucontext->lock); > + entry->key = ucontext->mmap_key; > + set_mmap_flag(&entry->key, mmap_flag); > + ucontext->mmap_key += PAGE_SIZE; > + list_add_tail(&entry->list, &ucontext->pending_mmaps); > + efa_dbg(&dev->ibdev.dev, > + "mmap: obj[%p] addr[0x%llx], len[0x%llx], key[0x%llx] inserted\n", > + entry->obj, entry->address, entry->length, entry->key); > + mutex_unlock(&ucontext->lock); > +} This whole thing is just a cyclic allocating xarray.. Jason