diff options
| author | Robert Mustacchi <rm@joyent.com> | 2018-04-17 20:58:05 +0000 |
|---|---|---|
| committer | Robert Mustacchi <rm@joyent.com> | 2018-04-17 23:53:32 +0000 |
| commit | c503160a02cf369bd6e7adfeb4a9dd95ea8cd3da (patch) | |
| tree | f407000402d52571b1a7e179f88d58d1d037e94f | |
| parent | 535faf307534ecc7ee41fbf74a1c625cc7aef441 (diff) | |
| download | illumos-joyent-c503160a02cf369bd6e7adfeb4a9dd95ea8cd3da.tar.gz | |
OS-6899 gsqueue cpu online logic can infinite loop
Reviewed by: Ryan Zezeski <rpz@joyent.com>
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Approved by: Patrick Mooney <patrick.mooney@joyent.com>
| -rw-r--r-- | usr/src/uts/common/io/gsqueue/gsqueue.c | 42 |
1 files changed, 20 insertions, 22 deletions
diff --git a/usr/src/uts/common/io/gsqueue/gsqueue.c b/usr/src/uts/common/io/gsqueue/gsqueue.c index da54d704f9..03bb799499 100644 --- a/usr/src/uts/common/io/gsqueue/gsqueue.c +++ b/usr/src/uts/common/io/gsqueue/gsqueue.c @@ -10,7 +10,7 @@ */ /* - * Copyright 2017 Joyent, Inc. + * Copyright 2018 Joyent, Inc. */ /* @@ -72,7 +72,7 @@ * described in `gs_ncpus`. The ordering of `gs_cpus` is unimportant. When * there is no longer a need for a given binding (see the following section for * more explanation on when this is the case) then we move the entry to the - * `gs_defunct` list which is just a singly linked list of gsqueue_cpu_t. + * `gs_defunct` list which is just a list_t of gsqueue_cpu_t. * * In addition, each gsqueue_set_t can have a series of callbacks registered * with it. These are described in the following section. Graphically, a given @@ -166,7 +166,7 @@ typedef struct gsqueue_cb { } gsqueue_cb_t; typedef struct gsqueue_cpu { - struct gsqueue_cpu *gqc_next; + list_node_t gqc_lnode; squeue_t *gqc_head; processorid_t gqc_cpuid; } gsqueue_cpu_t; @@ -177,7 +177,7 @@ struct gsqueue_set { kmutex_t gs_lock; int gs_ncpus; gsqueue_cpu_t **gs_cpus; - gsqueue_cpu_t *gs_defunct; + list_t gs_defunct; gsqueue_cb_t *gs_cbs; }; @@ -194,7 +194,7 @@ gsqueue_cpu_create(pri_t wpri, processorid_t cpuid) scp = kmem_cache_alloc(gsqueue_cpu_cache, KM_SLEEP); - scp->gqc_next = NULL; + list_link_init(&scp->gqc_lnode); scp->gqc_cpuid = cpuid; scp->gqc_head = squeue_create(wpri, B_FALSE); scp->gqc_head->sq_state = SQS_DEFAULT; @@ -268,8 +268,7 @@ gsqueue_set_destroy(gsqueue_set_t *gssp) for (i = 0; i < gssp->gs_ncpus; i++) { scp = gssp->gs_cpus[i]; squeue_unbind(scp->gqc_head); - scp->gqc_next = gssp->gs_defunct; - gssp->gs_defunct = scp; + list_insert_tail(&gssp->gs_defunct, scp); gssp->gs_cpus[i] = NULL; } gssp->gs_ncpus = 0; @@ -277,11 +276,7 @@ gsqueue_set_destroy(gsqueue_set_t *gssp) mutex_exit(&gssp->gs_lock); mutex_exit(&cpu_lock); - while (gssp->gs_defunct != NULL) { - gsqueue_cpu_t *scp; - - scp = gssp->gs_defunct; - gssp->gs_defunct = scp->gqc_next; + while ((scp = list_remove_head(&gssp->gs_defunct)) != NULL) { gsqueue_cpu_destroy(scp); } @@ -293,9 +288,9 @@ gsqueue_set_destroy(gsqueue_set_t *gssp) kmem_cache_free(gsqueue_cb_cache, cbp); } - ASSERT(gssp->gs_ncpus == 0); - ASSERT(gssp->gs_defunct == NULL); - ASSERT(gssp->gs_cbs == NULL); + ASSERT3U(gssp->gs_ncpus, ==, 0); + ASSERT3P(list_head(&gssp->gs_defunct), ==, NULL); + ASSERT3P(gssp->gs_cbs, ==, NULL); kmem_cache_free(gsqueue_set_cache, gssp); } @@ -404,11 +399,12 @@ gsqueue_handle_online(processorid_t id) gsqueue_cpu_t *scp; mutex_enter(&gssp->gs_lock); - scp = gssp->gs_defunct; - while (scp != NULL) { - if (scp->gqc_cpuid == id) + for (scp = list_head(&gssp->gs_defunct); scp != NULL; + scp = list_next(&gssp->gs_defunct, scp)) { + if (scp->gqc_cpuid == id) { + list_remove(&gssp->gs_defunct, scp); break; - scp = scp->gqc_next; + } } if (scp == NULL) { @@ -416,6 +412,7 @@ gsqueue_handle_online(processorid_t id) } else { squeue_bind(scp->gqc_head, id); } + ASSERT(gssp->gs_ncpus < NCPU); gssp->gs_cpus[gssp->gs_ncpus] = scp; gssp->gs_ncpus++; @@ -447,8 +444,7 @@ gsqueue_handle_offline(processorid_t id) if (scp != NULL) { squeue_unbind(scp->gqc_head); - scp->gqc_next = gssp->gs_defunct; - gssp->gs_defunct = scp; + list_insert_tail(&gssp->gs_defunct, scp); gssp->gs_cpus[i] = gssp->gs_cpus[gssp->gs_ncpus-1]; gssp->gs_ncpus--; gsqueue_notify(gssp, scp->gqc_head, B_FALSE); @@ -498,8 +494,9 @@ gsqueue_set_cache_construct(void *buf, void *arg, int kmflags) return (-1); mutex_init(&gssp->gs_lock, NULL, MUTEX_DRIVER, NULL); + list_create(&gssp->gs_defunct, sizeof (gsqueue_cpu_t), + offsetof(gsqueue_cpu_t, gqc_lnode)); gssp->gs_ncpus = 0; - gssp->gs_defunct = NULL; gssp->gs_cbs = NULL; return (0); @@ -513,6 +510,7 @@ gsqueue_set_cache_destruct(void *buf, void *arg) kmem_free(gssp->gs_cpus, sizeof (gsqueue_cpu_t *) * NCPU); gssp->gs_cpus = NULL; + list_destroy(&gssp->gs_defunct); mutex_destroy(&gssp->gs_lock); } |
