* freezing() returned false when the cgroup is being frozen
@ 2025-10-18 9:02 Qu Wenruo
2025-10-18 23:22 ` Tejun Heo
0 siblings, 1 reply; 4+ messages in thread
From: Qu Wenruo @ 2025-10-18 9:02 UTC (permalink / raw)
To: cgroups
Hi,
Recently I'm fixing a bug that a long running btrfs ioctl can prevent
suspension and cgroup freezing.
The root cause is btrfs lacks the proper checks to abort the ioctl, so
that the process can return to user space.
The fix is not that hard, normally some freezing() checks.
But I noticed that in the ioctl context, if the pm triggered freezing,
then freezing(current) properly returned true.
However if a cgroup freezing is triggered for the process running the
btrfs ioctl, freezing(current) will still return false.
The pm code has dedicated booleans, thus when pm is involved it
freezing_slow_path() just checks @pm_nosig_freezing and @pm_freezing
flags driectly.
On the hand for cgroup freezing case, it has to go cgroup_freezing() to
check if the cgroup is freezing.
Not familiar with cgroup, but it looks like the CGROUP_FREEZING bits are
only set during freezer_css_online(), but not sure if for the long
running ioctl case it's properly triggered.
Anyway the freezing() checks can be worked around by checking pending
signals inside btrfs, as cgroup freezing will send a wakeup signal to
the process.
Just curious if the freezing(current) is supposed to return false for
the cgroup freezing case.
Thanks,
Qu
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: freezing() returned false when the cgroup is being frozen
2025-10-18 9:02 freezing() returned false when the cgroup is being frozen Qu Wenruo
@ 2025-10-18 23:22 ` Tejun Heo
2025-10-18 23:32 ` Qu Wenruo
0 siblings, 1 reply; 4+ messages in thread
From: Tejun Heo @ 2025-10-18 23:22 UTC (permalink / raw)
To: Qu Wenruo; +Cc: cgroups
Hello,
On Sat, Oct 18, 2025 at 07:32:16PM +1030, Qu Wenruo wrote:
...
> Not familiar with cgroup, but it looks like the CGROUP_FREEZING bits are
> only set during freezer_css_online(), but not sure if for the long running
> ioctl case it's properly triggered.
>
> Anyway the freezing() checks can be worked around by checking pending
> signals inside btrfs, as cgroup freezing will send a wakeup signal to the
> process.
>
> Just curious if the freezing(current) is supposed to return false for the
> cgroup freezing case.
cgroup1 and cgroup2 have completely separate freezer implementation.
cgroup1's piggy back on the PM freezer which can freeze user and kthreads at
arbitrary freezing points. While that's fine for system-wide PM freezing, it
becomes a problem for cgroup freezing as users now can produce unkillable
frozen processes at will, which can create interesting problems (e.g. IIRC
the unkillable state can become transitive through ptrace).
Instead, cgroup2 freezer is a part of the task job control mechanism (the
same thing that SIGTSTP/SIGSTOP uses) and a frozen task behaves as if it has
sticky SIGSTOP signal pending. You can kill it, ptrace it and so on. As
such, it doesn't interact with the PM freezing mechanism at all. I suppose
you aren't talking about kthreads, right? It's just user threads doing
long-running ioctl's in btrfs code? If so, this should be no different from
getting any other signals. ie. If the code can handle signals and
task_work(), cgroup2 freezer should work fine too.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: freezing() returned false when the cgroup is being frozen
2025-10-18 23:22 ` Tejun Heo
@ 2025-10-18 23:32 ` Qu Wenruo
2025-10-19 5:26 ` Tejun Heo
0 siblings, 1 reply; 4+ messages in thread
From: Qu Wenruo @ 2025-10-18 23:32 UTC (permalink / raw)
To: Tejun Heo; +Cc: cgroups
在 2025/10/19 09:52, Tejun Heo 写道:
> Hello,
>
> On Sat, Oct 18, 2025 at 07:32:16PM +1030, Qu Wenruo wrote:
> ...
>> Not familiar with cgroup, but it looks like the CGROUP_FREEZING bits are
>> only set during freezer_css_online(), but not sure if for the long running
>> ioctl case it's properly triggered.
>>
>> Anyway the freezing() checks can be worked around by checking pending
>> signals inside btrfs, as cgroup freezing will send a wakeup signal to the
>> process.
>>
>> Just curious if the freezing(current) is supposed to return false for the
>> cgroup freezing case.
>
> cgroup1 and cgroup2 have completely separate freezer implementation.
> cgroup1's piggy back on the PM freezer which can freeze user and kthreads at
> arbitrary freezing points. While that's fine for system-wide PM freezing, it
> becomes a problem for cgroup freezing as users now can produce unkillable
> frozen processes at will, which can create interesting problems (e.g. IIRC
> the unkillable state can become transitive through ptrace).
>
> Instead, cgroup2 freezer is a part of the task job control mechanism (the
> same thing that SIGTSTP/SIGSTOP uses) and a frozen task behaves as if it has
> sticky SIGSTOP signal pending. You can kill it, ptrace it and so on. As
> such, it doesn't interact with the PM freezing mechanism at all. I suppose
> you aren't talking about kthreads, right?
Yep, I'm only talking about user space process trapped in long ioctls.
> It's just user threads doing
> long-running ioctl's in btrfs code? If so, this should be no different from
> getting any other signals. ie. If the code can handle signals and
> task_work(), cgroup2 freezer should work fine too.
The freezing behavior is fine, my main concern is that freezing()
function doesn't return true when cgroup (v2?) is freezing the process.
As you explained, since legacy cgroup is not that widely used anymore, I
believe systemd is using cgroup v2, thus it's fully signal based, so
freezing() is no longer the proper way to detect such freezing, but
signal_pending().
Maybe some comment on freezing() about this?
Thanks,
Qu
>
> Thanks.
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: freezing() returned false when the cgroup is being frozen
2025-10-18 23:32 ` Qu Wenruo
@ 2025-10-19 5:26 ` Tejun Heo
0 siblings, 0 replies; 4+ messages in thread
From: Tejun Heo @ 2025-10-19 5:26 UTC (permalink / raw)
To: Qu Wenruo; +Cc: cgroups
...
> As you explained, since legacy cgroup is not that widely used anymore, I
> believe systemd is using cgroup v2, thus it's fully signal based, so
> freezing() is no longer the proper way to detect such freezing, but
> signal_pending().
>
> Maybe some comment on freezing() about this?
Yeah, that sounds like a good idea. Will do.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-10-19 5:26 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-18 9:02 freezing() returned false when the cgroup is being frozen Qu Wenruo
2025-10-18 23:22 ` Tejun Heo
2025-10-18 23:32 ` Qu Wenruo
2025-10-19 5:26 ` Tejun Heo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox