| 1032 | } |
| 1033 | |
| 1034 | taskq_t * |
| 1035 | taskq_create(const char *name, int threads_arg, pri_t pri, |
| 1036 | int minalloc, int maxalloc, uint_t flags) |
| 1037 | { |
| 1038 | taskq_t *tq; |
| 1039 | taskq_thread_t *tqt; |
| 1040 | int count = 0, rc = 0, i; |
| 1041 | unsigned long irqflags; |
| 1042 | int nthreads = threads_arg; |
| 1043 | |
| 1044 | ASSERT(name != NULL); |
| 1045 | ASSERT(minalloc >= 0); |
| 1046 | ASSERT(maxalloc <= INT_MAX); |
| 1047 | ASSERT(!(flags & (TASKQ_CPR_SAFE))); /* Unsupported */ |
| 1048 | |
| 1049 | /* Scale the number of threads using nthreads as a percentage */ |
| 1050 | if (flags & TASKQ_THREADS_CPU_PCT) { |
| 1051 | ASSERT(nthreads <= 100); |
| 1052 | ASSERT(nthreads >= 0); |
| 1053 | nthreads = MIN(threads_arg, 100); |
| 1054 | nthreads = MAX(nthreads, 0); |
| 1055 | nthreads = MAX((num_online_cpus() * nthreads) /100, 1); |
| 1056 | } |
| 1057 | |
| 1058 | tq = kmem_alloc(sizeof (*tq), KM_PUSHPAGE); |
| 1059 | if (tq == NULL) |
| 1060 | return (NULL); |
| 1061 | |
| 1062 | tq->tq_hp_support = B_FALSE; |
| 1063 | #ifdef HAVE_CPU_HOTPLUG |
| 1064 | if (flags & TASKQ_THREADS_CPU_PCT) { |
| 1065 | tq->tq_hp_support = B_TRUE; |
| 1066 | if (cpuhp_state_add_instance_nocalls(spl_taskq_cpuhp_state, |
| 1067 | &tq->tq_hp_cb_node) != 0) { |
| 1068 | kmem_free(tq, sizeof (*tq)); |
| 1069 | return (NULL); |
| 1070 | } |
| 1071 | } |
| 1072 | #endif |
| 1073 | |
| 1074 | spin_lock_init(&tq->tq_lock); |
| 1075 | INIT_LIST_HEAD(&tq->tq_thread_list); |
| 1076 | INIT_LIST_HEAD(&tq->tq_active_list); |
| 1077 | tq->tq_name = kmem_strdup(name); |
| 1078 | tq->tq_nactive = 0; |
| 1079 | tq->tq_nthreads = 0; |
| 1080 | tq->tq_nspawn = 0; |
| 1081 | tq->tq_maxthreads = nthreads; |
| 1082 | tq->tq_cpu_pct = threads_arg; |
| 1083 | tq->tq_pri = pri; |
| 1084 | tq->tq_minalloc = minalloc; |
| 1085 | tq->tq_maxalloc = maxalloc; |
| 1086 | tq->tq_nalloc = 0; |
| 1087 | tq->tq_flags = (flags | TASKQ_ACTIVE); |
| 1088 | tq->tq_next_id = TASKQID_INITIAL; |
| 1089 | tq->tq_lowest_id = TASKQID_INITIAL; |
| 1090 | INIT_LIST_HEAD(&tq->tq_free_list); |
| 1091 | INIT_LIST_HEAD(&tq->tq_pend_list); |
no test coverage detected