From: jsg Date: Mon, 30 Sep 2024 12:21:17 +0000 (+0000) Subject: handle non xa_limit_32b ranges in xarray X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=22008fe3a13384a2d0eb7434eb1b03dcbce0d721;p=openbsd handle non xa_limit_32b ranges in xarray --- diff --git a/sys/dev/pci/drm/drm_linux.c b/sys/dev/pci/drm/drm_linux.c index b7b26e3e65d..c97c28f714f 100644 --- a/sys/dev/pci/drm/drm_linux.c +++ b/sys/dev/pci/drm/drm_linux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: drm_linux.c,v 1.118 2024/09/30 12:09:04 jsg Exp $ */ +/* $OpenBSD: drm_linux.c,v 1.119 2024/09/30 12:21:17 jsg Exp $ */ /* * Copyright (c) 2013 Jonathan Gray * Copyright (c) 2015, 2016 Mark Kettenis @@ -1003,11 +1003,15 @@ xa_destroy(struct xarray *xa) /* Don't wrap ids. */ int -__xa_alloc(struct xarray *xa, u32 *id, void *entry, int limit, gfp_t gfp) +__xa_alloc(struct xarray *xa, u32 *id, void *entry, struct xarray_range xr, + gfp_t gfp) { struct xarray_entry *xid; - int start = (xa->xa_flags & XA_FLAGS_ALLOC1) ? 1 : 0; - int begin; + uint32_t start = xr.start; + uint32_t end = xr.end; + + if (start == 0 && (xa->xa_flags & XA_FLAGS_ALLOC1)) + start = 1; if (gfp & GFP_NOWAIT) { xid = pool_get(&xa_pool, PR_NOWAIT); @@ -1020,17 +1024,14 @@ __xa_alloc(struct xarray *xa, u32 *id, void *entry, int limit, gfp_t gfp) if (xid == NULL) return -ENOMEM; - if (limit <= 0) - limit = INT_MAX; - - xid->id = begin = start; + xid->id = start; while (SPLAY_INSERT(xarray_tree, &xa->xa_tree, xid)) { - if (xid->id == limit) + if (xid->id == end) xid->id = start; else xid->id++; - if (xid->id == begin) { + if (xid->id == start) { pool_put(&xa_pool, xid); return -EBUSY; } @@ -1046,10 +1047,10 @@ __xa_alloc(struct xarray *xa, u32 *id, void *entry, int limit, gfp_t gfp) * The only caller of this (i915_drm_client.c) doesn't use next id. */ int -__xa_alloc_cyclic(struct xarray *xa, u32 *id, void *entry, int limit, u32 *next, - gfp_t gfp) +__xa_alloc_cyclic(struct xarray *xa, u32 *id, void *entry, + struct xarray_range xr, u32 *next, gfp_t gfp) { - int r = __xa_alloc(xa, id, entry, limit, gfp); + int r = __xa_alloc(xa, id, entry, xr, gfp); *next = *id + 1; return r; } diff --git a/sys/dev/pci/drm/include/linux/xarray.h b/sys/dev/pci/drm/include/linux/xarray.h index c41a5fda6f2..fd643058fc3 100644 --- a/sys/dev/pci/drm/include/linux/xarray.h +++ b/sys/dev/pci/drm/include/linux/xarray.h @@ -7,9 +7,9 @@ #include -#define XA_FLAGS_ALLOC 1 -#define XA_FLAGS_ALLOC1 2 -#define XA_FLAGS_LOCK_IRQ 4 +#define XA_FLAGS_ALLOC (1 << 0) +#define XA_FLAGS_ALLOC1 (1 << 1) +#define XA_FLAGS_LOCK_IRQ (1 << 2) /* * lower bits of pointer are tagged: @@ -29,10 +29,19 @@ struct xarray { SPLAY_HEAD(xarray_tree, xarray_entry) xa_tree; }; +struct xarray_range { + uint32_t start; + uint32_t end; +}; + +#define XA_LIMIT(_start, _end) (struct xarray_range){ _start, _end } +#define xa_limit_32b XA_LIMIT(0, UINT_MAX) + void xa_init_flags(struct xarray *, gfp_t); void xa_destroy(struct xarray *); -int __xa_alloc(struct xarray *, u32 *, void *, int, gfp_t); -int __xa_alloc_cyclic(struct xarray *, u32 *, void *, int, u32 *, gfp_t); +int __xa_alloc(struct xarray *, u32 *, void *, struct xarray_range, gfp_t); +int __xa_alloc_cyclic(struct xarray *, u32 *, void *, struct xarray_range, + u32 *, gfp_t); void *__xa_load(struct xarray *, unsigned long); void *__xa_store(struct xarray *, unsigned long, void *, gfp_t); void *__xa_erase(struct xarray *, unsigned long); @@ -41,8 +50,6 @@ void *xa_get_next(struct xarray *, unsigned long *); #define xa_for_each(xa, index, entry) \ for (index = 0; ((entry) = xa_get_next(xa, &(index))) != NULL; index++) -#define xa_limit_32b 0 - #define xa_lock(_xa) do { \ mtx_enter(&(_xa)->xa_lock); \ } while (0) @@ -112,11 +119,12 @@ xa_is_err(const void *e) } static inline int -xa_alloc(struct xarray *xa, u32 *id, void *entry, int limit, gfp_t gfp) +xa_alloc(struct xarray *xa, u32 *id, void *entry, struct xarray_range xr, + gfp_t gfp) { int r; mtx_enter(&xa->xa_lock); - r = __xa_alloc(xa, id, entry, limit, gfp); + r = __xa_alloc(xa, id, entry, xr, gfp); mtx_leave(&xa->xa_lock); return r; }