diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-04-07 20:31:00 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-04-07 20:31:00 +0000 |
commit | facf9accf739920033c1d81479544b03b7ce955c (patch) | |
tree | 5474beb8d336bfd839c6e0c46d4cd7008601b584 /sys/dev/pci | |
parent | aa39742da07249eec29a11a0c5934bdc6f2ffed5 (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.c | 9 |
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; |