MCPcopy Create free account
hub / github.com/F-Stack/f-stack / task_alloc

Function task_alloc

freebsd/contrib/openzfs/module/os/linux/spl/spl-taskq.c:108–168  ·  view source on GitHub ↗

* NOTE: Must be called with tq->tq_lock held, returns a list_t which * is not attached to the free, work, or pending taskq lists. */

Source from the content-addressed store, hash-verified

106 * is not attached to the free, work, or pending taskq lists.
107 */
108static taskq_ent_t *
109task_alloc(taskq_t *tq, uint_t flags, unsigned long *irqflags)
110{
111 taskq_ent_t *t;
112 int count = 0;
113
114 ASSERT(tq);
115retry:
116 /* Acquire taskq_ent_t's from free list if available */
117 if (!list_empty(&tq->tq_free_list) && !(flags & TQ_NEW)) {
118 t = list_entry(tq->tq_free_list.next, taskq_ent_t, tqent_list);
119
120 ASSERT(!(t->tqent_flags & TQENT_FLAG_PREALLOC));
121 ASSERT(!(t->tqent_flags & TQENT_FLAG_CANCEL));
122 ASSERT(!timer_pending(&t->tqent_timer));
123
124 list_del_init(&t->tqent_list);
125 return (t);
126 }
127
128 /* Free list is empty and memory allocations are prohibited */
129 if (flags & TQ_NOALLOC)
130 return (NULL);
131
132 /* Hit maximum taskq_ent_t pool size */
133 if (tq->tq_nalloc >= tq->tq_maxalloc) {
134 if (flags & TQ_NOSLEEP)
135 return (NULL);
136
137 /*
138 * Sleep periodically polling the free list for an available
139 * taskq_ent_t. Dispatching with TQ_SLEEP should always succeed
140 * but we cannot block forever waiting for an taskq_ent_t to
141 * show up in the free list, otherwise a deadlock can happen.
142 *
143 * Therefore, we need to allocate a new task even if the number
144 * of allocated tasks is above tq->tq_maxalloc, but we still
145 * end up delaying the task allocation by one second, thereby
146 * throttling the task dispatch rate.
147 */
148 spin_unlock_irqrestore(&tq->tq_lock, *irqflags);
149 schedule_timeout(HZ / 100);
150 spin_lock_irqsave_nested(&tq->tq_lock, *irqflags,
151 tq->tq_lock_class);
152 if (count < 100) {
153 count++;
154 goto retry;
155 }
156 }
157
158 spin_unlock_irqrestore(&tq->tq_lock, *irqflags);
159 t = kmem_alloc(sizeof (taskq_ent_t), task_km_flags(flags));
160 spin_lock_irqsave_nested(&tq->tq_lock, *irqflags, tq->tq_lock_class);
161
162 if (t) {
163 taskq_init_ent(t);
164 tq->tq_nalloc++;
165 }

Callers 3

taskq_dispatchFunction · 0.70
taskq_dispatch_delayFunction · 0.70
taskq_createFunction · 0.70

Calls 4

list_emptyFunction · 0.85
list_del_initFunction · 0.85
task_km_flagsFunction · 0.85
taskq_init_entFunction · 0.70

Tested by

no test coverage detected