Actually, I think I have a better idea based on a key observation:
We are trying to acquire pm_mutex here. And if we block due to this,
we are *100% sure* that we are not going to run as long as hibernation
sequence is running, since hibernation releases pm_mutex only at the
very end, when everything is done.
And this means, this task is going to be blocked for much more longer
than what the freezer intends to achieve. Which means, freezing and
thawing doesn't really make a difference to this task!
So, let's just ask the freezer to skip freezing us!! And everything
will be just fine!
Something like:
void lock_system_sleep(void)
{
/* simplified freezer_do_not_count() */
current->flags |= PF_FREEZER_SKIP;
mutex_lock(&pm_mutex);
}
void unlock_system_sleep(void)
{
mutex_unlock(&pm_mutex);
/* simplified freezer_count() */
current->flags&= ~PF_FREEZER_SKIP;
}
We probably don't want the restriction that freezer_do_not_count() and
freezer_count() work only for userspace tasks. So I have open coded
the relevant parts of those functions here.