Make sure all tasklets are drained before unloading the LinuxKPI.

Else use-after-free may happen.

This change also partially cherry picks support for the
taskqgroup_drain_all() function.

Sponsored by:	Mellanox Technologies // NVIDIA Networking

(cherry picked from commit 209d4919c5)
This commit is contained in:
Hans Petter Selasky 2021-05-21 08:52:59 +02:00
parent 623d96f4af
commit 407b687dfe
3 changed files with 16 additions and 0 deletions

View file

@ -128,6 +128,8 @@ tasklet_subsystem_uninit(void *arg __unused)
struct tasklet_worker *tw;
int i;
taskqgroup_drain_all(qgroup_softirq);
CPU_FOREACH(i) {
if (CPU_ABSENT(i))
continue;

View file

@ -817,3 +817,16 @@ void
taskqgroup_destroy(struct taskqgroup *qgroup)
{
}
void
taskqgroup_drain_all(struct taskqgroup *tqg)
{
struct gtaskqueue *q;
for (int i = 0; i < mp_ncpus; i++) {
q = tqg->tqg_queue[i].tgc_taskq;
if (q == NULL)
continue;
gtaskqueue_drain_all(q);
}
}

View file

@ -80,6 +80,7 @@ void taskqgroup_detach(struct taskqgroup *qgroup, struct grouptask *gtask);
struct taskqgroup *taskqgroup_create(const char *name, int cnt, int stride);
void taskqgroup_destroy(struct taskqgroup *qgroup);
void taskqgroup_bind(struct taskqgroup *qgroup);
void taskqgroup_drain_all(struct taskqgroup *qgroup);
#define GTASK_INIT(gtask, flags, priority, func, context) do { \
(gtask)->ta_flags = flags; \