Martin Husemann <martin%duskware.de@localhost> writes: > Consider the following pseudo-code running in softint context: > > void > softint_func(some_state *st, ....) > { > LOCK(st); > size_t n, max_n = st->num_items; > some_state_item **tmp_list = > kmem_intr_alloc(max_n * sizeof(*tmp_list)); kmem_intr_alloc takes a flag, and it seems that you need to pass KM_NOSLEEP, as blocking for memory in softint context is highly unlikely to be the right thing. The an page is silent on whether lack of both flags is an error, and if not what the semantics are. (It seems to me it should be an error.) With KM_NOSLEEP, it is possible that the allocation will fail. Thus there needs to be a strategy to deal with that. > n = 0; > for (i : st->items) { > if (!(i matches some predicate)) > continue; > i->retain(); > tmp_list[n++] = i; > } > UNLOCK(st); > /* do something with all elements in tmp_list */ > kmem_intr_free(tmp_list, max_n * sizeof(*tmp_list)); > } > > I don't want to alloca here (the list could be quite huge) and max_n could > vary a lot, so having a "manual" pool of a few common (preallocated) > list sizes hanging off the state does not go well either. I think that you need to pick one of pre-allocate the largest size and use it temporarily be able to deal with not having memory. This leads to hard-to-debug situations if that code is wrong, becuase usually malloc will succeed. figure out that this softint can block indefinitely, only harming later calls of the same family, and not leading to kernel deadlock/etc. This leads to hard-to-debug situations if lack of memory does lead to hangs, because usually malloc will succeed. > In a perfect world we would avoid the interrupt allocation all together, but > I have not found a way to rearrange things here to make this feasible. > > Is kmem_intr_alloc(9) the best way forward? With all that said, note that I'm not the allocation export.
Attachment:
signature.asc
Description: PGP signature