Artix Linux Forum

Artix Linux => System => Topic started by: nokangaroo on 25 July 2022, 13:33:52

Title: Testing seatd (not to necrobump the previous thread)
Post by: nokangaroo on 25 July 2022, 13:33:52
For me, the reasons for getting rid of elogind were dmesg errors like these (only with kernels later than 5.4, and regardless of kernel config, kernel commandline or BIOS settings):
Code: [Select]
[112632.955495] Asynchronous wait on fence 0000:00:02.0:elogind[1165]:4f482 timed out (hint:intel_atomic_commit_ready [i915])
[112636.925429] i915 0000:00:02.0: [drm] GPU HANG: ecode 9:1:878aaff9, in elogind [1165]
...
[ 3680.505752] i915 0000:00:02.0: [drm] Resetting rcs0 for preemption time out
[ 3680.505778] i915 0000:00:02.0: [drm] elogind[1171] context reset due to GPU hang
[ 3680.510459] i915 0000:00:02.0: [drm] GPU HANG: ecode 9:1:86dfaff9, in elogind [1171]
Turns out it didn't stop the freezes, but here's my experience with seatd FWIW.

seatd, dbus and polkit just need libelogind to run (elogind is only a buildtime dependency; the headers could be packaged with libelogind, or separately (an "elogind-headers" package would be nice, see below). I tested libelogind-249-pre, though the binary package also works. I've already been using custom-built dbus (no audit) and polkit (with duktape, which fortunately is the default now). For suspend, shutdown and reboot I added the following to /etc/sudoers:
Code: [Select]
%users ALL = NOPASSWD: /usr/local/lib/suspend,/usr/bin/openrc-shutdown -H 0,/usr/bin/openrc-shutdown -r 0
suspend is a little C program (doesn't currently work with linux-next, suspends only once, then hangs; works with mainline and 5.4):
Code: [Select]
#include <stdio.h>
#include <stdlib.h>
int main(void) {
    FILE *state;
    state = fopen("/sys/power/state", "r+");
    if (state == NULL) {
    exit(EXIT_FAILURE);
    }
    fprintf(state, "%s", "mem");
    fclose(state);
    exit(EXIT_SUCCESS);
}
I put it in /usr/local/lib because I don't want it on my path. This program could of course be expanded to handle shutdown and reboot as well (not currently needed). Who needs loginctl? For XDG_RUNTIME_DIR, I tested adding
Code: [Select]
export XDG_RUNTIME_DIR=`mktemp -d /tmp/xdg-${UID}-XXXXXXXXXX`
echo "XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR}" > ~/.pam_environment
to .bash_profile, which works perfectly well. There is also a pam_rundir package, which I also tested (it creates the usual /run/user/$UID).
The elogind-git package needed a hack to build (here's a working PKGBUILD):
Code: [Select]
pkgbase=elogind
pkgname=('elogind' 'libelogind' 'elogind-headers')
pkgver=249.pre.r0.g06e702c9d
pkgrel=6
pkgdesc="The systemd project's logind, extracted to a standalone package"
arch=('x86_64')
url="https://github.com/elogind/elogind"
license=('GPL' 'LGPL2.1')
makedepends=('intltool' 'gperf' 'gtk-doc' 'polkit' 'dbus'
            'libseccomp' 'meson' 'kexec-tools' 'openrc' 'libcap' 'python-jinja' 'elogind-headers')
options=('!libtool')
source=("git+https://github.com/elogind/elogind")
sha256sums=('SKIP')
groups=(modified)

pkgver() {
  cd "${srcdir}/elogind"
  git describe --long | sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g;s/\:/./g'
}

build() {
    # -Dman=false avoids a build error
    local meson_options=(
        -Drootlibdir=/usr/lib
        -Drootlibexecdir=/usr/lib/elogind
        -Ddbuspolicydir=/usr/share/dbus-1/system.d
        -Ddocdir=/usr/share/doc/elogind
        -Ddefault-hierarchy=hybrid
        -Dcgroup-controller=openrc
        -Daudit=false
        -Dman=false
        -Ddefault-kill-user-processes=false
    )
    meson "${pkgbase}" build "${meson_options[@]}"
    #***EVIL*** hack to avoid build error:
    sed -i -e "/^meson.add_install_script('sh', '-c', 'touch/d" "${srcdir}"/elogind/src/core/meson.build
    #end ***EVIL*** hack
    meson compile -C build
}

check(){
    meson test -C build --print-errorlogs
}

package_elogind() {
    pkgdesc="The systemd project's logind, extracted to a standalone package"
    provides=("elogind=${pkgver}" 'logind')
    depends=('acl' 'dbus' 'libseccomp' 'libelogind' 'kexec-tools' 'udev')
    optdepends=('polkit: polkit support')
    backup=('etc/elogind/logind.conf')
    #***EVIL*** hack
    mkdir -p "${pkgdir}"/usr/lib/elogind/system-{shutdown,sleep}
    touch "${pkgdir}"/usr/lib/elogind/system-{shutdown,sleep}/.keep_dir
    #end ***EVIL*** hack
    DESTDIR="${pkgdir}" meson install -C build

    ln -sfv libelogind.pc "${pkgdir}"/usr/lib/pkgconfig/libsystemd.pc

    install -dm755 "${srcdir}"/_libelogind
    mv -v "${pkgdir}"/usr/lib/libelogind*.so* "${srcdir}"/_libelogind

    install -d "${pkgdir}"/{etc,usr/lib}/elogind/{logind,sleep}.conf.d

}

package_libelogind() {
    pkgdesc="elogind client libraries"
    provides=('libelogind.so' "libelogind=${pkgver}" 'liblogind')
    depends=('libcap' 'libudev')

    cd "${pkgbase}"
    install -dm755 "${pkgdir}"/usr/lib
    mv "${srcdir}"/_libelogind/libelogind*.so* "${pkgdir}"/usr/lib
    #cp -R "${pkgdir}"../elogind/usr/include "${pkgdir}"/usr/

    ln -sfv libelogind.so "${pkgdir}"/usr/lib/libsystemd.so
    ln -sfv libsystemd.so "${pkgdir}"/usr/lib/libsystemd.so.0
}

package_elogind-headers() {
mkdir -p ${pkgdir}/usr/include/elogind
    cp -R --no-preserve='ownership' ${srcdir}/elogind/src/systemd ${pkgdir}/usr/include/elogind
    cd ${pkgdir}/usr/include/elogind
    for file in systemd/*.h; do ln -s $file ./${file/systemd//}; done
}
I tested {,lib}elogind-249-pre built with this PKGBUILD, see below.
Does seatd actually do anything on a system with a single logged-in user? "ps axo seat" came up empty except for a column of dashes. (Even when I logged in again on a different tty, which incidentally took very long, and I didn't get graphics - it turned out to be a libelogind-249-pre issue, works with {,lib}elogind-246-10, including the one built against elogind-headers. Maybe polkit and dbus also need to be rebuilt, but since seatd doesn't do anything for me, I'm done testing).
Title: Re: Testing seatd (not to necrobump the previous thread)
Post by: Dudemanguy on 25 July 2022, 16:15:34
Does seatd actually do anything on a system with a single logged-in user?

Yeah it makes it possible to run graphics as a non-root user. You wouldn't have been able to start xorg in the first place.
Title: Re: Testing seatd (not to necrobump the previous thread)
Post by: cat herders of linux on 25 July 2022, 16:31:40
Yeah it makes it possible to run graphics as a non-root user. You wouldn't have been able to start xorg in the first place.
tried using seatd on my mate dinit system and could not run graphics as a non root user.  i only got a working desktop running as root.
Title: Re: Testing seatd (not to necrobump the previous thread)
Post by: nokangaroo on 25 July 2022, 17:05:14
I just uninstalled elogind and kexec-tools and rebooted, and I'm in the graphics (rootless xorg). What I can't do is login to another tty and get graphics, same as with seatd. Still not convinced that seatd does anything. Rebooting now with elogind, will try rebuilding dbus and polkit with elogind-git.
Title: Re: Testing seatd (not to necrobump the previous thread)
Post by: Dudemanguy on 25 July 2022, 17:15:18
tried using seatd on my mate dinit system and could not run graphics as a non root user.  i only got a working desktop running as root.

You need to actually run the daemon and add the your user to the correct group.

I just uninstalled elogind and kexec-tools and rebooted, and I'm in the graphics (rootless xorg).

In theory, this shouldn't have worked at all. You should have had a permissions error when trying to access /dev/dri/card0 (or whatever your gpu card number is) if you really removed elogind completely from your system.
Title: Re: Testing seatd (not to necrobump the previous thread)
Post by: cat herders of linux on 25 July 2022, 17:22:38
You need to actually run the daemon and add the your user to the correct group.

In theory, this shouldn't have worked at all. You should have had a permissions error when trying to access /dev/dri/card0 (or whatever your gpu card number is) if you really removed elogind completely from your system.
https://forum.artixlinux.org/index.php/topic,3050.msg27949.html#msg27949

followed op..  please advise.
Title: Re: Testing seatd (not to necrobump the previous thread)
Post by: nokangaroo on 25 July 2022, 17:43:03
I didn't remove libelogind, and I used automatic login (I don't use a login manager, just a function in .bash_profile
Code: [Select]
gui() {
    if [[ -z "${WINDOWPATH}" ]]; then
        local WIN=$(pidof Xorg | wc -w)
        rm -f /tmp/.gui${WIN}-${UID}*
        local LOG="$(mktemp -q /tmp/.gui${WIN}-${UID}-`date +%a%d%b%Y-%T`.log.XXXXXXXXXX)"
        local ERR="$(mktemp -q /tmp/.gui${WIN}-${UID}-`date +%a%d%b%Y-%T`-error.log.XXXXXXXXXX)"
        startx :${WIN} 1>${LOG} 2>${ERR}
    else
        echo 'To be run from the console - Aborting.'
    fi
}
Then typing "gui" at the console will log you in (on as many ttys as you want, works with elogind). And I started seatd-openrc when testing seatd. Did you mean I have to add myself to the "seat" group? seatd was started with "-g video" by default (which I'm a member of), if I recall correctly.
Title: Re: Testing seatd (not to necrobump the previous thread)
Post by: Dudemanguy on 25 July 2022, 20:05:50
The init scripts are currently a bit dated. They should run with the "seat" group. Currently some run with "video" and others with "seatd". That said, if you were in the video group and seatd was running as the video group, then this should have worked.
Title: Re: Testing seatd (not to necrobump the previous thread)
Post by: pluto on 25 July 2022, 20:08:48
A little bit more information would be nice.

So far i can see here, you using the openrc version. Wich DE?

Quote
For suspend, shutdown and reboot I added the following to /etc/sudoers:

This sadly dont readd the Shutdown and Restart Buttons back to KDE. Tried is already too.

Quote
seatd, dbus and polkit just need libelogind to run (elogind is only a buildtime dependency; the headers could be packaged with libelogind, or separately (an "elogind-headers" package would be nice, see below). I tested libelogind-249-pre, though the binary package also works. I've already been using custom-built dbus (no audit) and polkit (with duktape, which fortunately is the default now)

Everything from AUR? why?

Quote
Who needs loginctl? For XDG_RUNTIME_DIR, I tested adding

Code: [Select]
export XDG_RUNTIME_DIR=`mktemp -d /tmp/xdg-${UID}-XXXXXXXXXX`
echo "XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR}" > ~/.pam_environment
to .bash_profile, which works perfectly well.

Why is this needed?

Edit:

Quote
The init scripts are currently a bit dated. They should run with the "seat" group. Currently some run with "video" and others with "seatd".

Im since two days testing seatd in a VM. The seatd group even didnt exist. So i only added me to the two groups audio and input like in the post https://forum.artixlinux.org/index.php/topic,3050.0.html mentioned. And everything works.

Should i add me to seat?
Title: Re: Testing seatd (not to necrobump the previous thread)
Post by: cat herders of linux on 25 July 2022, 22:29:27
The init scripts are currently a bit dated. They should run with the "seat" group. Currently some run with "video" and others with "seatd". That said, if you were in the video group and seatd was running as the video group, then this should have worked.
i am capable of following written instructions.  i added myself to all the groups listed as well as the ones recommended in the arch link you posted about groups.  I wouldn't waste your time if i could get it to work.  I see that it works for many and that is awesome.  There are a few though, me and nokangaroo at least for who it appears to not be working.  If it worked, i would def use it.  I thank you for your hard work on this project.  I look forward to the day it is part of the iso builds from community live usbs.
Title: Re: Testing seatd (not to necrobump the previous thread)
Post by: nokangaroo on 26 July 2022, 12:21:27
pluto:
My DE is MATE with openbox as window manager (which can handle my keyboard shortcuts, so I'm not using mate-settings-daemon or mate-panel, I use tint2 instead. I use mate-session-manager, which is actually smaller than lxde-session and works better). As for the AUR packages an all the other modifications, I am plagued by this i915 interface freeze (with kernels later than 5.4), and I was trying to find out if it had anything to do with userspace applications, see the above dmesg code (apparently it's a pure kernel issue, but I like my modified DE and will keep it).
If you can't get shutdown and restart buttons, try defining keyboard shortcuts (that's what I did; for openbox that means adding code to rc.xml, for KDE I can't tell you, but there will be documentation). You may need to press the power button after shutting down.
The XDG_RUNTIME_DIR is used by dbus, dconf and gvfs (and xorg puts a cookie there). Adding lines to .bash_profile is just one possible way to get it, the canonical way would be installing pam_rundir (only if you use seatd, elogind creates XDG_RUNTIME_DIR automatically)

The posted PKGBUILD is still not quite correct, it creates a corrupt libelogind.pc (which is trivial to fix but elogind-249-pre seems to be hopelessly broken, and I don't recommend using it).
Title: Re: Testing seatd (not to necrobump the previous thread)
Post by: pluto on 26 July 2022, 15:02:13
pluto:
My DE is MATE with openbox as window manager (which can handle my keyboard shortcuts, so I'm not using mate-settings-daemon or mate-panel, I use tint2 instead. I use mate-session-manager, which is actually smaller than lxde-session and works better). As for the AUR packages an all the other modifications, I am plagued by this i915 interface freeze (with kernels later than 5.4), and I was trying to find out if it had anything to do with userspace applications, see the above dmesg code (apparently it's a pure kernel issue, but I like my modified DE and will keep it).
If you can't get shutdown and restart buttons, try defining keyboard shortcuts (that's what I did; for openbox that means adding code to rc.xml, for KDE I can't tell you, but there will be documentation). You may need to press the power button after shutting down.
The XDG_RUNTIME_DIR is used by dbus, dconf and gvfs (and xorg puts a cookie there). Adding lines to .bash_profile is just one possible way to get it, the canonical way would be installing pam_rundir (only if you use seatd, elogind creates XDG_RUNTIME_DIR automatically)

The posted PKGBUILD is still not quite correct, it creates a corrupt libelogind.pc (which is trivial to fix but elogind-249-pre seems to be hopelessly broken, and I don't recommend using it).

Ah ok. Did you tried this? https://wiki.archlinux.org/title/Intel_graphics#Kernel_crashing_w/kernels_4.0+_on_Broadwell/Core-M_chips

sure i could make keyboard shortcuts wich start "sudo poweroff" for example. Or simple Desktopicons wich does this. But that only a workaround :-)

Now i simply shutdown/restart with konsole and sudo poweroff/sudo reboot. But would be nice if i could use KDE native for that. And it should be possible how i already found out. But i only found solution for dinit, initd and 66. But sadly not with openrc.

And im to stupid to implement the found solutions to openrc :-)
Title: Re: Testing seatd (not to necrobump the previous thread)
Post by: artoo on 26 July 2022, 18:58:08
I look forward to the day it is part of the iso builds from community live usbs.


Not gonna happen, unless seatd becomes a full logind replacement.
Title: Re: Testing seatd (not to necrobump the previous thread)
Post by: pluto on 26 July 2022, 20:33:49

Not gonna happen, unless seatd becomes a full logind replacement.

this is possibly a stupid question because i am not familiar with it, but what is missing until now?

im investing much time the last few days with researching because i switched to seatd and collecting a bunch information. I tried few wide spread DEs already (KDE, GNOME, Cinnamon), at all it seems to work without problems (after fresh install, openrc). The only Problem all have common is that all lose the ability to reboot/shutdown over the Desktop.

Edit: and with all i had to manually add a variable to make nano as standard editor for user, root and sudo. Dont know if this wouldnt be needed with elogind.
Title: Re: Testing seatd (not to necrobump the previous thread)
Post by: capezotte on 26 July 2022, 20:48:24
this is possibly a stupid question because i am not familiar with it, but what is missing until now?

im investing much time the last few days with researching because i switched to seatd and collecting a bunch information. I tried few wide spread DEs already (KDE, GNOME, Cinnamon), at all it seems to work without problems (after fresh install, openrc). The only Problem all have common is that all lose the ability to reboot/shutdown over the Desktop.

Power management is one of these features. GNOME, KDE, etc. use logind to suspend, poweroff and reboot.

Seatd also doesn't implement logind-stlye user access control lists (https://enotty.pipebreaker.pl/2012/05/23/linux-automatic-user-acl-management/).
Title: Re: Testing seatd (not to necrobump the previous thread)
Post by: gripped on 26 July 2022, 21:13:16
The only Problem all have common is that all lose the ability to reboot/shutdown over the Desktop.

This may be of interest to you ? Creating a a replacement loginctl.
https://forum.artixlinux.org/index.php/topic,3050.msg23032.html#msg23032
I've never tried it but something like this could work if replicated in a binary and set SUID.
Scripts can't be set SUID AFAIK. At least sh / bash can't.

Title: Re: Testing seatd (not to necrobump the previous thread)
Post by: pluto on 26 July 2022, 21:40:12
This may be of interest to you ? Creating a a replacement loginctl.
https://forum.artixlinux.org/index.php/topic,3050.msg23032.html#msg23032
I've never tried it but something like this could work if replicated in a binary and set SUID.
Scripts can't be set SUID AFAIK. At least sh / bash can't.



Yeah, already read that. But like already said in this Thread:

Quote
Sadly, i dont quite understand this and how to implement this for openrc: https://forum.artixlinux.org/index.php/topic,3050.msg23032.html#msg23032

https://forum.artixlinux.org/index.php/topic,3050.msg27908.html#msg27908
Title: Re: Testing seatd (not to necrobump the previous thread)
Post by: gripped on 26 July 2022, 22:40:58
The equivalent in openrc I think.
Code: [Select]
#!/bin/sh

show_usage()
{
cat <<EOT
Usage: ${0##*/} [halt|reboot|poweroff]
EOT
}

case $1 in
halt) openrc-shutdown -H 0;;
reboot) openrc-shutdown -r 0;;
poweroff) openrc-shutdown -p 0;;
*) show_usage
esac

;;
*) show_usage
esac
But it would not work from a GUI as it needs root privileges. Hence needing to convert to a compiled binary that can be set SUID.
And that's assuming loginctl is called by your desktop of choice. But if strajder believes so I expect it usually is ?
Also the result would be that any user can poweroff the machine but on a single user PC that's not a biggie imho

I can't program really but you can find small C tutorials and convert them to serve a tiny purpose such as this.

For example suspend and hibernate do not work for me from the KDE GUI. System comes back up but screen never does.
However writing directly to the kernel does work
Code: [Select]
sudo echo mem > /sys/power/state
But I wanted a hotkey combo to do it so modified a C tutorial to do the above (bar the sudo)
Code: [Select]
   #include <stdio.h>
   #include <stdlib.h>
   #include <sys/types.h>
   #include <unistd.h>

int main() {
    #define word "mem"

    // creating file pointer to work with files
    FILE *fptr;
setuid(0);
    // opening file in writing mode
    fptr = fopen("/sys/power/state", "w");

    // exiting program
    if (fptr == NULL) {
        printf("Error!");
        exit(1);
    }
    fprintf(fptr, "%s", word);
    fclose(fptr);
    return 0;
}
Compiled, moved to /usr/local/bin , set SUID, added the key combo shift-ctrl-alt-s to point at my binary and VoilĂ 

Different issue but some concepts to resolve yours are similar.
Just food for thought


 
Title: Re: Testing seatd (not to necrobump the previous thread)
Post by: nokangaroo on 28 July 2022, 14:32:45
Ah ok. Did you tried this? https://wiki.archlinux.org/title/Intel_graphics#Kernel_crashing_w/kernels_4.0+_on_Broadwell/Core-M_chips

sure i could make keyboard shortcuts wich start "sudo poweroff" for example. Or simple Desktopicons wich does this. But that only a workaround :-)

Now i simply shutdown/restart with konsole and sudo poweroff/sudo reboot. But would be nice if i could use KDE native for that. And it should be possible how i already found out. But i only found solution for dinit, initd and 66. But sadly not with openrc.

And im to stupid to implement the found solutions to openrc :-)
pluto:
I tried everything I could find, and then some more. Nothing worked so far. The problem seems to be forced preemption, which cannot be safely disabled (DRM_I915_PREEMPT_TIMEOUT=0 does not work, and if you unset the various timeouts, kconfig asks for them; they cannot be unset).
Here is the outcome of "git show 3a7a92aba8fb77162e1e9963360fd81fc15c39a5" in linux-mainline, which seems to be the relevant commit:
Code: [Select]
commit 3a7a92aba8fb77162e1e9963360fd81fc15c39a5
Author: Chris Wilson <[email protected]>
Date:   Wed Oct 23 14:31:05 2019 +0100

    drm/i915/execlists: Force preemption
   
    If the preempted context takes too long to relinquish control, e.g. it
    is stuck inside a shader with arbitration disabled, evict that context
    with an engine reset. This ensures that preemptions are reasonably
    responsive, providing a tighter QoS for the more important context at
    the cost of flagging unresponsive contexts more frequently (i.e. instead
    of using an ~10s hangcheck, we now evict at ~100ms).  The challenge of
    lies in picking a timeout that can be reasonably serviced by HW for
    typical workloads, balancing the existing clients against the needs for
    responsiveness.
   
    Note that coupled with timeslicing, this will lead to rapid GPU "hang"
    detection with multiple active contexts vying for GPU time.
   
    The forced preemption mechanism can be compiled out with
   
            ./scripts/config --set-val DRM_I915_PREEMPT_TIMEOUT 0
   
    Signed-off-by: Chris Wilson <[email protected]>
    Cc: Mika Kuoppala <[email protected]>
    Cc: Tvrtko Ursulin <[email protected]>
    Reviewed-by: Mika Kuoppala <[email protected]>
    Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]

diff --git a/drivers/gpu/drm/i915/Kconfig.profile b/drivers/gpu/drm/i915/Kconfig.profile
index 3a3881d5e44b..b071b6024152 100644
--- a/drivers/gpu/drm/i915/Kconfig.profile
+++ b/drivers/gpu/drm/i915/Kconfig.profile
@@ -12,6 +12,18 @@ config DRM_I915_USERFAULT_AUTOSUSPEND
    May be 0 to disable the extra delay and solely use the device level
    runtime pm autosuspend delay tunable.
 
+config DRM_I915_PREEMPT_TIMEOUT
+ int "Preempt timeout (ms, jiffy granularity)"
+ default 100 # milliseconds
+ help
+   How long to wait (in milliseconds) for a preemption event to occur
+   when submitting a new context via execlists. If the current context
+   does not hit an arbitration point and yield to HW before the timer
+   expires, the HW will be reset to allow the more important context
+   to execute.
+
+   May be 0 to disable the timeout.
+
 config DRM_I915_SPIN_REQUEST
  int "Busywait for request completion (us)"
  default 5 # microseconds
diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h b/drivers/gpu/drm/i915/gt/intel_engine.h
index c2d9d67c63d9..9409b7856299 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine.h
@@ -527,4 +527,13 @@ void intel_engine_init_active(struct intel_engine_cs *engine,
 #define ENGINE_MOCK 1
 #define ENGINE_VIRTUAL 2
 
+static inline bool
+intel_engine_has_preempt_reset(const struct intel_engine_cs *engine)
+{
+ if (!CONFIG_DRM_I915_PREEMPT_TIMEOUT)
+ return 0;
+
+ return intel_engine_has_preemption(engine);
+}
+
 #endif /* _INTEL_RINGBUFFER_H_ */
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index e4203eb44139..b91ea07f4819 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -308,6 +308,8 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id)
  engine->instance = info->instance;
  __sprint_engine_name(engine);
 
+ engine->props.preempt_timeout_ms =
+ CONFIG_DRM_I915_PREEMPT_TIMEOUT;
  engine->props.stop_timeout_ms =
  CONFIG_DRM_I915_STOP_TIMEOUT;
 
@@ -1338,10 +1340,11 @@ static void intel_engine_print_registers(struct intel_engine_cs *engine,
  unsigned int idx;
  u8 read, write;
 
- drm_printf(m, "\tExeclist tasklet queued? %s (%s), timeslice? %s\n",
+ drm_printf(m, "\tExeclist tasklet queued? %s (%s), preempt? %s, timeslice? %s\n",
     yesno(test_bit(TASKLET_STATE_SCHED,
    &engine->execlists.tasklet.state)),
     enableddisabled(!atomic_read(&engine->execlists.tasklet.count)),
+    repr_timer(&engine->execlists.preempt),
     repr_timer(&engine->execlists.timer));
 
  read = execlists->csb_head;
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index 87d5c4ef3ae7..1251dac91f31 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -174,6 +174,11 @@ struct intel_engine_execlists {
  */
  struct timer_list timer;
 
+ /**
+ * @preempt: reset the current context if it fails to give way
+ */
+ struct timer_list preempt;
+
  /**
  * @default_priolist: priority list for I915_PRIORITY_NORMAL
  */
@@ -544,6 +549,7 @@ struct intel_engine_cs {
  } stats;
 
  struct {
+ unsigned long preempt_timeout_ms;
  unsigned long stop_timeout_ms;
  } props;
 };
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index f9f3e985bb79..ff0dd297e782 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -1372,6 +1372,26 @@ static void record_preemption(struct intel_engine_execlists *execlists)
  (void)I915_SELFTEST_ONLY(execlists->preempt_hang.count++);
 }
 
+static unsigned long active_preempt_timeout(struct intel_engine_cs *engine)
+{
+ struct i915_request *rq;
+
+ rq = last_active(&engine->execlists);
+ if (!rq)
+ return 0;
+
+ return READ_ONCE(engine->props.preempt_timeout_ms);
+}
+
+static void set_preempt_timeout(struct intel_engine_cs *engine)
+{
+ if (!intel_engine_has_preempt_reset(engine))
+ return;
+
+ set_timer_ms(&engine->execlists.preempt,
+      active_preempt_timeout(engine));
+}
+
 static void execlists_dequeue(struct intel_engine_cs *engine)
 {
  struct intel_engine_execlists * const execlists = &engine->execlists;
@@ -1747,6 +1767,8 @@ done:
 
  memset(port + 1, 0, (last_port - port) * sizeof(*port));
  execlists_submit_ports(engine);
+
+ set_preempt_timeout(engine);
  } else {
 skip_submit:
  ring_set_paused(engine, 0);
@@ -1987,6 +2009,43 @@ static void __execlists_submission_tasklet(struct intel_engine_cs *const engine)
  }
 }
 
+static noinline void preempt_reset(struct intel_engine_cs *engine)
+{
+ const unsigned int bit = I915_RESET_ENGINE + engine->id;
+ unsigned long *lock = &engine->gt->reset.flags;
+
+ if (i915_modparams.reset < 3)
+ return;
+
+ if (test_and_set_bit(bit, lock))
+ return;
+
+ /* Mark this tasklet as disabled to avoid waiting for it to complete */
+ tasklet_disable_nosync(&engine->execlists.tasklet);
+
+ GEM_TRACE("%s: preempt timeout %lu+%ums\n",
+   engine->name,
+   READ_ONCE(engine->props.preempt_timeout_ms),
+   jiffies_to_msecs(jiffies - engine->execlists.preempt.expires));
+ intel_engine_reset(engine, "preemption time out");
+
+ tasklet_enable(&engine->execlists.tasklet);
+ clear_and_wake_up_bit(bit, lock);
+}
+
+static bool preempt_timeout(const struct intel_engine_cs *const engine)
+{
+ const struct timer_list *t = &engine->execlists.preempt;
+
+ if (!CONFIG_DRM_I915_PREEMPT_TIMEOUT)
+ return false;
+
+ if (!timer_expired(t))
+ return false;
+
+ return READ_ONCE(engine->execlists.pending[0]);
+}
+
 /*
  * Check the unread Context Status Buffers and manage the submission of new
  * contexts to the ELSP accordingly.
@@ -1994,23 +2053,39 @@ static void __execlists_submission_tasklet(struct intel_engine_cs *const engine)
 static void execlists_submission_tasklet(unsigned long data)
 {
  struct intel_engine_cs * const engine = (struct intel_engine_cs *)data;
- unsigned long flags;
+ bool timeout = preempt_timeout(engine);
 
  process_csb(engine);
- if (!READ_ONCE(engine->execlists.pending[0])) {
+ if (!READ_ONCE(engine->execlists.pending[0]) || timeout) {
+ unsigned long flags;
+
  spin_lock_irqsave(&engine->active.lock, flags);
  __execlists_submission_tasklet(engine);
  spin_unlock_irqrestore(&engine->active.lock, flags);
+
+ /* Recheck after serialising with direct-submission */
+ if (timeout && preempt_timeout(engine))
+ preempt_reset(engine);
  }
 }
 
-static void execlists_submission_timer(struct timer_list *timer)
+static void __execlists_kick(struct intel_engine_execlists *execlists)
 {
- struct intel_engine_cs *engine =
- from_timer(engine, timer, execlists.timer);
-
  /* Kick the tasklet for some interrupt coalescing and reset handling */
- tasklet_hi_schedule(&engine->execlists.tasklet);
+ tasklet_hi_schedule(&execlists->tasklet);
+}
+
+#define execlists_kick(t, member) \
+ __execlists_kick(container_of(t, struct intel_engine_execlists, member))
+
+static void execlists_timeslice(struct timer_list *timer)
+{
+ execlists_kick(timer, timer);
+}
+
+static void execlists_preempt(struct timer_list *timer)
+{
+ execlists_kick(timer, preempt);
 }
 
 static void queue_request(struct intel_engine_cs *engine,
@@ -3455,6 +3530,7 @@ gen12_emit_fini_breadcrumb_rcs(struct i915_request *request, u32 *cs)
 static void execlists_park(struct intel_engine_cs *engine)
 {
  cancel_timer(&engine->execlists.timer);
+ cancel_timer(&engine->execlists.preempt);
 }
 
 void intel_execlists_set_default_submission(struct intel_engine_cs *engine)
@@ -3572,7 +3648,8 @@ int intel_execlists_submission_setup(struct intel_engine_cs *engine)
 {
  tasklet_init(&engine->execlists.tasklet,
       execlists_submission_tasklet, (unsigned long)engine);
- timer_setup(&engine->execlists.timer, execlists_submission_timer, 0);
+ timer_setup(&engine->execlists.timer, execlists_timeslice, 0);
+ timer_setup(&engine->execlists.preempt, execlists_preempt, 0);
 
  logical_ring_default_vfuncs(engine);
  logical_ring_default_irqs(engine);
diff --git a/drivers/gpu/drm/i915/gt/selftest_lrc.c b/drivers/gpu/drm/i915/gt/selftest_lrc.c
index 7516d1c90925..b6352671c5a0 100644
--- a/drivers/gpu/drm/i915/gt/selftest_lrc.c
+++ b/drivers/gpu/drm/i915/gt/selftest_lrc.c
@@ -1697,6 +1697,105 @@ err_spin_hi:
  return err;
 }
 
+static int live_preempt_timeout(void *arg)
+{
+ struct intel_gt *gt = arg;
+ struct i915_gem_context *ctx_hi, *ctx_lo;
+ struct igt_spinner spin_lo;
+ struct intel_engine_cs *engine;
+ enum intel_engine_id id;
+ int err = -ENOMEM;
+
+ /*
+ * Check that we force preemption to occur by cancelling the previous
+ * context if it refuses to yield the GPU.
+ */
+ if (!CONFIG_DRM_I915_PREEMPT_TIMEOUT)
+ return 0;
+
+ if (!HAS_LOGICAL_RING_PREEMPTION(gt->i915))
+ return 0;
+
+ if (!intel_has_reset_engine(gt))
+ return 0;
+
+ if (igt_spinner_init(&spin_lo, gt))
+ return -ENOMEM;
+
+ ctx_hi = kernel_context(gt->i915);
+ if (!ctx_hi)
+ goto err_spin_lo;
+ ctx_hi->sched.priority =
+ I915_USER_PRIORITY(I915_CONTEXT_MAX_USER_PRIORITY);
+
+ ctx_lo = kernel_context(gt->i915);
+ if (!ctx_lo)
+ goto err_ctx_hi;
+ ctx_lo->sched.priority =
+ I915_USER_PRIORITY(I915_CONTEXT_MIN_USER_PRIORITY);
+
+ for_each_engine(engine, gt, id) {
+ unsigned long saved_timeout;
+ struct i915_request *rq;
+
+ if (!intel_engine_has_preemption(engine))
+ continue;
+
+ rq = spinner_create_request(&spin_lo, ctx_lo, engine,
+     MI_NOOP); /* preemption disabled */
+ if (IS_ERR(rq)) {
+ err = PTR_ERR(rq);
+ goto err_ctx_lo;
+ }
+
+ i915_request_add(rq);
+ if (!igt_wait_for_spinner(&spin_lo, rq)) {
+ intel_gt_set_wedged(gt);
+ err = -EIO;
+ goto err_ctx_lo;
+ }
+
+ rq = igt_request_alloc(ctx_hi, engine);
+ if (IS_ERR(rq)) {
+ igt_spinner_end(&spin_lo);
+ err = PTR_ERR(rq);
+ goto err_ctx_lo;
+ }
+
+ /* Flush the previous CS ack before changing timeouts */
+ while (READ_ONCE(engine->execlists.pending[0]))
+ cpu_relax();
+
+ saved_timeout = engine->props.preempt_timeout_ms;
+ engine->props.preempt_timeout_ms = 1; /* in ms, -> 1 jiffie */
+
+ i915_request_get(rq);
+ i915_request_add(rq);
+
+ intel_engine_flush_submission(engine);
+ engine->props.preempt_timeout_ms = saved_timeout;
+
+ if (i915_request_wait(rq, 0, HZ / 10) < 0) {
+ intel_gt_set_wedged(gt);
+ i915_request_put(rq);
+ err = -ETIME;
+ goto err_ctx_lo;
+ }
+
+ igt_spinner_end(&spin_lo);
+ i915_request_put(rq);
+ }
+
+ err = 0;
+err_ctx_lo:
+ kernel_context_close(ctx_lo);
+err_ctx_hi:
+ kernel_context_close(ctx_hi);
+err_spin_lo:
+ igt_spinner_fini(&spin_lo);
+ return err;
+}
+
 static int random_range(struct rnd_state *rnd, int min, int max)
 {
  return i915_prandom_u32_max_state(max - min, rnd) + min;
@@ -2598,6 +2697,7 @@ int intel_execlists_live_selftests(struct drm_i915_private *i915)
  SUBTEST(live_suppress_wait_preempt),
  SUBTEST(live_chain_preempt),
  SUBTEST(live_preempt_hang),
+ SUBTEST(live_preempt_timeout),
  SUBTEST(live_preempt_smoke),
  SUBTEST(live_virtual_engine),
  SUBTEST(live_virtual_mask),
diff --git a/drivers/gpu/drm/i915/i915_gem.h b/drivers/gpu/drm/i915/i915_gem.h
index 2011f8e9a9f1..f6f9675848b8 100644
--- a/drivers/gpu/drm/i915/i915_gem.h
+++ b/drivers/gpu/drm/i915/i915_gem.h
@@ -112,18 +112,4 @@ static inline bool __tasklet_is_scheduled(struct tasklet_struct *t)
  return test_bit(TASKLET_STATE_SCHED, &t->state);
 }
 
-static inline void cancel_timer(struct timer_list *t)
-{
- if (!READ_ONCE(t->expires))
- return;
-
- del_timer(t);
- WRITE_ONCE(t->expires, 0);
-}
-
-static inline bool timer_expired(const struct timer_list *t)
-{
- return READ_ONCE(t->expires) && !timer_pending(t);
-}
-
 #endif /* __I915_GEM_H__ */
diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
index d29ade3b7de6..56058978bb27 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -61,7 +61,7 @@ struct drm_printer;
  param(char *, dmc_firmware_path, NULL) \
  param(int, mmio_debug, -IS_ENABLED(CONFIG_DRM_I915_DEBUG_MMIO)) \
  param(int, edp_vswing, 0) \
- param(int, reset, 2) \
+ param(int, reset, 3) \
  param(unsigned int, inject_load_failure, 0) \
  param(int, fastboot, -1) \
  param(int, enable_dpcd_backlight, 0) \
diff --git a/drivers/gpu/drm/i915/i915_utils.c b/drivers/gpu/drm/i915/i915_utils.c
index 16acdf7bdbe6..02e969b64505 100644
--- a/drivers/gpu/drm/i915/i915_utils.c
+++ b/drivers/gpu/drm/i915/i915_utils.c
@@ -76,3 +76,32 @@ bool i915_error_injected(void)
 }
 
 #endif
+
+void cancel_timer(struct timer_list *t)
+{
+ if (!READ_ONCE(t->expires))
+ return;
+
+ del_timer(t);
+ WRITE_ONCE(t->expires, 0);
+}
+
+void set_timer_ms(struct timer_list *t, unsigned long timeout)
+{
+ if (!timeout) {
+ cancel_timer(t);
+ return;
+ }
+
+ timeout = msecs_to_jiffies_timeout(timeout);
+
+ /*
+ * Paranoia to make sure the compiler computes the timeout before
+ * loading 'jiffies' as jiffies is volatile and may be updated in
+ * the background by a timer tick. All to reduce the complexity
+ * of the addition and reduce the risk of losing a jiffie.
+ */
+ barrier();
+
+ mod_timer(t, jiffies + timeout);
+}
diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h
index 562f756da421..94f136d8a5fd 100644
--- a/drivers/gpu/drm/i915/i915_utils.h
+++ b/drivers/gpu/drm/i915/i915_utils.h
@@ -32,6 +32,7 @@
 #include <linux/workqueue.h>
 
 struct drm_i915_private;
+struct timer_list;
 
 #undef WARN_ON
 /* Many gcc seem to no see through this and fall over :( */
@@ -421,4 +422,12 @@ static inline void add_taint_for_CI(unsigned int taint)
  add_taint(taint, LOCKDEP_STILL_OK);
 }
 
+void cancel_timer(struct timer_list *t);
+void set_timer_ms(struct timer_list *t, unsigned long timeout);
+
+static inline bool timer_expired(const struct timer_list *t)
+{
+ return READ_ONCE(t->expires) && !timer_pending(t);
+}
+
 #endif /* !__I915_UTILS_H */
October 2019 is about right; that's when the trouble started.
I tried adding
Code: [Select]
./scripts/config --set-val DRM_I915_PREEMPT_TIMEOUT 0
to my linux-mainline PKGBUILD (before make oldconfig), but all it does is set CONFIG_DRM_I915_PREEMPT_TIMEOUT to 0, which I already tried.
I am currently testing "i915.enable_dc=0 processor.max_cstate=1 intel_idle.max_cstate=0" added to my kernel commandline, and disabling timeslicing (CONFIG_DRM_I915_TIMESLICE_DURATION=0). If that doesn't work, I'm out of options, unless the kernel guys come to their senses and provide a way to disable forced preemption safely on hardware that doesn't support it.
Timeslicing can also be disabled at runtime (as root; the actual names of the engines may differ):
Code: [Select]
# echo 0 > /sys/class/drm/card0/engine/bcs0/timeslice_duration_ms
# echo 0 > /sys/class/drm/card0/engine/rcs0/timeslice_duration_ms
# echo 0 > /sys/class/drm/card0/engine/vcs0/timeslice_duration_ms
# echo 0 > /sys/class/drm/card0/engine/vecs0/timeslice_duration_ms
Similarly for preempt_timeout_ms.
Title: Re: Testing seatd (not to necrobump the previous thread)
Post by: pluto on 28 July 2022, 16:19:52
that sucks, i really feel sorry for you. kurrios to see such a bug.
Title: Re: Testing seatd (not to necrobump the previous thread)
Post by: pluto on 29 July 2022, 21:08:38
The equivalent in openrc I think.
Code: [Select]
#!/bin/sh

show_usage()
{
cat <<EOT
Usage: ${0##*/} [halt|reboot|poweroff]
EOT
}

case $1 in
halt) openrc-shutdown -H 0;;
reboot) openrc-shutdown -r 0;;
poweroff) openrc-shutdown -p 0;;
*) show_usage
esac

;;
*) show_usage
esac
But it would not work from a GUI as it needs root privileges. Hence needing to convert to a compiled binary that can be set SUID.
And that's assuming loginctl is called by your desktop of choice. But if strajder believes so I expect it usually is ?
Also the result would be that any user can poweroff the machine but on a single user PC that's not a biggie imho

I can't program really but you can find small C tutorials and convert them to serve a tiny purpose such as this.

For example suspend and hibernate do not work for me from the KDE GUI. System comes back up but screen never does.
However writing directly to the kernel does work
Code: [Select]
sudo echo mem > /sys/power/state
But I wanted a hotkey combo to do it so modified a C tutorial to do the above (bar the sudo)
Code: [Select]
   #include <stdio.h>
   #include <stdlib.h>
   #include <sys/types.h>
   #include <unistd.h>

int main() {
    #define word "mem"

    // creating file pointer to work with files
    FILE *fptr;
setuid(0);
    // opening file in writing mode
    fptr = fopen("/sys/power/state", "w");

    // exiting program
    if (fptr == NULL) {
        printf("Error!");
        exit(1);
    }
    fprintf(fptr, "%s", word);
    fclose(fptr);
    return 0;
}
Compiled, moved to /usr/local/bin , set SUID, added the key combo shift-ctrl-alt-s to point at my binary and VoilĂ 

Different issue but some concepts to resolve yours are similar.
Just food for thought


 

If it interest you, i found a solution for me: https://forum.artixlinux.org/index.php/topic,3050.msg28181.html#msg28181