summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Mooney <pmooney@pfmooney.com>2017-03-13 23:10:42 +0000
committerPatrick Mooney <pmooney@oxide.computer>2020-09-01 17:28:57 +0000
commit1c8449e95a93a750df972545379490366b392934 (patch)
treed3f09abd33685ad2b0bdabc8fd841d214b6b27e0
parentd11e14a72ad0bfccf84405261d5d93e6eaafe6a7 (diff)
downloadillumos-joyent-1c8449e95a93a750df972545379490366b392934.tar.gz
13084 tl_open should handle id_space exhaustion
Reviewed by: Robert Mustacchi <rm@joyent.com> Reviewed by: Ryan Zezeski <ryan.zeseski@joyent.com> Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com> Reviewed by: Toomas Soome <tsoome@me.com> Reviewed by: Andrew Stormont <astormont@racktopsystems.com> Approved by: Robert Mustacchi <rm@fingolfin.org>
-rw-r--r--usr/src/uts/common/io/tl.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/usr/src/uts/common/io/tl.c b/usr/src/uts/common/io/tl.c
index c11af49b64..10466c22da 100644
--- a/usr/src/uts/common/io/tl.c
+++ b/usr/src/uts/common/io/tl.c
@@ -1484,8 +1484,9 @@ tl_closeok(tl_endpt_t *tep)
static int
tl_open(queue_t *rq, dev_t *devp, int oflag, int sflag, cred_t *credp)
{
- tl_endpt_t *tep;
- minor_t minor = getminor(*devp);
+ tl_endpt_t *tep;
+ minor_t minor = getminor(*devp);
+ id_t inst_minor;
/*
* Driver is called directly. Both CLONEOPEN and MODOPEN
@@ -1505,6 +1506,14 @@ tl_open(queue_t *rq, dev_t *devp, int oflag, int sflag, cred_t *credp)
minor |= TL_SOCKET;
}
+ /*
+ * Attempt to allocate a unique minor number for this instance.
+ * Avoid an uninterruptable sleep if none are available.
+ */
+ if ((inst_minor = id_alloc_nosleep(tl_minors)) == -1) {
+ return (ENOMEM);
+ }
+
tep = kmem_cache_alloc(tl_cache, KM_SLEEP);
tep->te_refcnt = 1;
tep->te_cpid = curproc->p_pid;
@@ -1516,9 +1525,7 @@ tl_open(queue_t *rq, dev_t *devp, int oflag, int sflag, cred_t *credp)
tep->te_flag = minor & TL_MINOR_MASK;
tep->te_transport = &tl_transports[minor];
-
- /* Allocate a unique minor number for this instance. */
- tep->te_minor = (minor_t)id_alloc(tl_minors);
+ tep->te_minor = (minor_t)inst_minor;
/* Reserve hash handle for bind(). */
(void) mod_hash_reserve(tep->te_addrhash, &tep->te_hash_hndl);