#include <time.h>
#include "errno.h"
-#ifndef ETIME
-#define ETIME ETIMEDOUT
-#endif
#include "common/gen_clflush.h"
#include "dev/gen_debug.h"
#include "common/gen_gem.h"
}
static struct iris_bo *
-hash_find_bo(struct hash_table *ht, unsigned int key)
+find_and_ref_external_bo(struct hash_table *ht, unsigned int key)
{
struct hash_entry *entry = _mesa_hash_table_search(ht, &key);
- return entry ? (struct iris_bo *) entry->data : NULL;
+ struct iris_bo *bo = entry ? entry->data : NULL;
+
+ if (bo) {
+ assert(bo->external);
+ assert(!bo->reusable);
+
+ /* Being non-reusable, the BO cannot be in the cache lists, but it
+ * may be in the zombie list if it had reached zero references, but
+ * we hadn't yet closed it...and then reimported the same BO. If it
+ * is, then remove it since it's now been resurrected.
+ */
+ if (bo->head.prev || bo->head.next)
+ list_del(&bo->head);
+
+ iris_bo_reference(bo);
+ }
+
+ return bo;
}
/**
* provides a sufficiently fast match.
*/
mtx_lock(&bufmgr->lock);
- bo = hash_find_bo(bufmgr->name_table, handle);
- if (bo) {
- iris_bo_reference(bo);
+ bo = find_and_ref_external_bo(bufmgr->name_table, handle);
+ if (bo)
goto out;
- }
struct drm_gem_open open_arg = { .name = handle };
int ret = gen_ioctl(bufmgr->fd, DRM_IOCTL_GEM_OPEN, &open_arg);
* object from the kernel before by looking through the list
* again for a matching gem_handle
*/
- bo = hash_find_bo(bufmgr->handle_table, open_arg.handle);
- if (bo) {
- iris_bo_reference(bo);
+ bo = find_and_ref_external_bo(bufmgr->handle_table, open_arg.handle);
+ if (bo)
goto out;
- }
bo = bo_calloc();
if (!bo)
{
struct iris_bufmgr *bufmgr = bo->bufmgr;
+ if (bo->external) {
+ struct hash_entry *entry;
+
+ if (bo->global_name) {
+ entry = _mesa_hash_table_search(bufmgr->name_table, &bo->global_name);
+ _mesa_hash_table_remove(bufmgr->name_table, entry);
+ }
+
+ entry = _mesa_hash_table_search(bufmgr->handle_table, &bo->gem_handle);
+ _mesa_hash_table_remove(bufmgr->handle_table, entry);
+ }
+
/* Close this object */
struct drm_gem_close close = { .handle = bo->gem_handle };
int ret = gen_ioctl(bufmgr->fd, DRM_IOCTL_GEM_CLOSE, &close);
munmap(bo->map_gtt, bo->size);
}
- if (bo->external) {
- struct hash_entry *entry;
-
- if (bo->global_name) {
- entry = _mesa_hash_table_search(bufmgr->name_table, &bo->global_name);
- _mesa_hash_table_remove(bufmgr->name_table, entry);
- }
-
- entry = _mesa_hash_table_search(bufmgr->handle_table, &bo->gem_handle);
- _mesa_hash_table_remove(bufmgr->handle_table, entry);
- }
-
if (bo->idle) {
bo_close(bo);
} else {
* for named buffers, we must not create two bo's pointing at the same
* kernel object
*/
- bo = hash_find_bo(bufmgr->handle_table, handle);
- if (bo) {
- iris_bo_reference(bo);
+ bo = find_and_ref_external_bo(bufmgr->handle_table, handle);
+ if (bo)
goto out;
- }
bo = bo_calloc();
if (!bo)
* \param fd File descriptor of the opened DRM device.
*/
struct iris_bufmgr *
-iris_bufmgr_init(struct gen_device_info *devinfo, int fd)
+iris_bufmgr_init(struct gen_device_info *devinfo, int fd, bool bo_reuse)
{
uint64_t gtt_size = iris_gtt_size(fd);
if (gtt_size <= IRIS_MEMZONE_OTHER_START)
list_inithead(&bufmgr->zombie_list);
bufmgr->has_llc = devinfo->has_llc;
+ bufmgr->bo_reuse = bo_reuse;
STATIC_ASSERT(IRIS_MEMZONE_SHADER_START == 0ull);
const uint64_t _4GB = 1ull << 32;
IRIS_MEMZONE_OTHER_START,
(gtt_size - _4GB) - IRIS_MEMZONE_OTHER_START);
- // XXX: driconf
- bufmgr->bo_reuse = env_var_as_boolean("bo_reuse", true);
-
init_cache_buckets(bufmgr);
bufmgr->name_table =