summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2016-04-07 20:31:00 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2016-04-07 20:31:00 +0000
commitfacf9accf739920033c1d81479544b03b7ce955c (patch)
tree5474beb8d336bfd839c6e0c46d4cd7008601b584 /sys/dev/pci
parentaa39742da07249eec29a11a0c5934bdc6f2ffed5 (diff)
Return -ENOSPC if idr_alloc() fails to allocate an unused id instead of
spinning forever.
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/drm/drm_linux.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/sys/dev/pci/drm/drm_linux.c b/sys/dev/pci/drm/drm_linux.c
index 0ab0130941d..1591351475e 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.10 2016/04/05 20:44:03 kettenis Exp $ */
+/* $OpenBSD: drm_linux.c,v 1.11 2016/04/07 20:30:59 kettenis Exp $ */
/*
* Copyright (c) 2013 Jonathan Gray <jsg@openbsd.org>
* Copyright (c) 2015, 2016 Mark Kettenis <kettenis@openbsd.org>
@@ -276,6 +276,7 @@ idr_alloc(struct idr *idr, void *ptr, int start, int end,
{
int flags = (gfp_mask & GFP_NOWAIT) ? PR_NOWAIT : PR_WAITOK;
struct idr_entry *id;
+ int begin;
KERNEL_ASSERT_LOCKED();
@@ -291,10 +292,14 @@ idr_alloc(struct idr *idr, void *ptr, int start, int end,
if (end <= 0)
end = INT_MAX;
- id->id = start + arc4random_uniform(end - start);
+ id->id = begin = start + arc4random_uniform(end - start);
while (SPLAY_INSERT(idr_tree, &idr->tree, id)) {
if (++id->id == end)
id->id = start;
+ if (id->id == begin) {
+ pool_put(&idr_pool, id);
+ return -ENOSPC;
+ }
}
id->ptr = ptr;
return id->id;