[Bug 102646] Screen flickering under amdgpu-experimental [buggy auto power profile]

bugzilla-daemon at freedesktop.org bugzilla-daemon at freedesktop.org
Wed Mar 20 16:59:00 UTC 2019


https://bugs.freedesktop.org/show_bug.cgi?id=102646

--- Comment #71 from bmilreu at gmail.com ---
(In reply to George Scorer from comment #70)
> Building on julien tempel's workaround, here's a somewhat more complex
> script to manage the memory p-state jumps. It switches between low and high
> memory p-states very reluctantly, so minimizing instances of flickering. I'm
> not a bash expert so please excuse the clumsy coding, but this works for me.
> 
> #!/bin/bash
> 
> # Each memory p-state switch causes a screen flicker. Tweak these variables
> to match
> # your personal 'flicker aversion' vs efficiency trade-off.
> CORE_P_STATE_UP=6    # The gpu core p-state at which we should jump up to
> memory p-state 2
> CORE_P_STATE_DOWN=1  # The gpu core p-state at which we should drop down to
> low memory p-state
> UP_DELAY=2           # in seconds. How long to stay in low memory p-state
> before checking whether we can jump up to 2.
> DOWN_DELAY=10        # in seconds. How long to stay in memory p-state 2
> before checking whether we can drop down to low.
> SLEEP_INTERVAL=1     # in seconds. How frequently we should poll the core
> p-state.
> LOW_MEM_STATE=0      # Choose between 0 & 1
> 
> # Sysfs paths here are hardcoded for one amdgpu card at card0; adjust as
> needed.
> FILE_PERF_LEVEL=/sys/class/drm/card0/device/power_dpm_force_performance_level
> FILE_MEM_P_STATE=/sys/class/drm/card0/device/pp_dpm_mclk
> FILE_CORE_P_STATE=/sys/class/drm/card0/device/pp_dpm_sclk
> 
> 
> # check for root privileges
> if [ $UID -ne 0 ]
> then
>   echo "Writing to sysfs requires root privileges; relaunch as root"
>   exit 1
> fi
> 
> # Set gpu performance level control to manual
> # echo "Setting performance level control to manual"
> echo "manual" > "$FILE_PERF_LEVEL"
> 
> # Read the current core p-state and set a corresponding initial memory
> p-state
> 
> CORE_P_STATE="$(grep -F '*' $FILE_CORE_P_STATE)"
> CORE_P_STATE=${CORE_P_STATE:0:1}
> 
> if [ "$CORE_P_STATE" -ge "$CORE_P_STATE_UP" ]; then
>   MEM_P_STATE=2
> else
>   MEM_P_STATE=$LOW_MEM_STATE
> fi
> 
> echo "$MEM_P_STATE" > "$FILE_MEM_P_STATE"
> PROPOSED_MEM_P_STATE=$MEM_P_STATE
>   
> function check_core_p_state {
> 
>   CORE_P_STATE="$(grep -F '*' $FILE_CORE_P_STATE)"
>   CORE_P_STATE=${CORE_P_STATE:0:1}
> 
> # Propose what the corresponding memory p-state should be
>   OLD_PROPOSED_MEM_P_STATE=$PROPOSED_MEM_P_STATE
>   PROPOSED_MEM_P_STATE=$MEM_P_STATE
>   if [ "$CORE_P_STATE" -ge "$CORE_P_STATE_UP" ]; then
>     PROPOSED_MEM_P_STATE=2
>   elif [ "$CORE_P_STATE" -le "$CORE_P_STATE_DOWN" ]; then
>     PROPOSED_MEM_P_STATE=$LOW_MEM_STATE
>   fi
>   
>   if [ "$PROPOSED_MEM_P_STATE" -ne "$MEM_P_STATE" ]; then
> #   We want to change so determine where we are in the countdown.    
>     if [ "$PROPOSED_MEM_P_STATE" -ne "$OLD_PROPOSED_MEM_P_STATE" ]; then
>       if [ "$PROPOSED_MEM_P_STATE" -eq 2 ]; then
>         CHANGE_COUNTDOWN=$UP_DELAY
>       else
>         CHANGE_COUNTDOWN=$DOWN_DELAY
>       fi
>     fi
>     (( CHANGE_COUNTDOWN = $CHANGE_COUNTDOWN - $SLEEP_INTERVAL ))
>       
>     if [ $CHANGE_COUNTDOWN -le 0 ]; then
> #   The countdown has reached 0 so change the memory p-state.
>       MEM_P_STATE=$PROPOSED_MEM_P_STATE
>       echo "$MEM_P_STATE" > "$FILE_MEM_P_STATE"
>     fi
> #  else
> #   we don't want to change.  
>   fi
> 
> #    echo "Old  Prop  Mem  Core  Countdown"
> #    echo "  $OLD_PROPOSED_MEM_P_STATE     $PROPOSED_MEM_P_STATE   
> $MEM_P_STATE     $CORE_P_STATE         $CHANGE_COUNTDOWN"
> #    echo ""
> }
> 
> function reset_on_fail {
>   echo "Exiting, setting memory p-state to 2"
>   echo "manual" > "$FILE_PERF_LEVEL"
>   echo "2" > "$FILE_MEM_P_STATE"
>   exit 1
> }
> 
> # always try to fix memory p-state 2 on failure
> trap "reset_on_fail" SIGINT SIGTERM
> 
> function run_daemon {
>   while :; do
>     sleep $SLEEP_INTERVAL
>     check_core_p_state
>   done
> }
> 
> # start the loop
> 
> run_daemon

Thanks for the script, it doesn't work 100% of the time but the flickers are
very rare. Good thing about it is that you still save power when idle since it
reclocks back. I'd guess similar logic could be used to fix the driver while
still having the feature working, just reclocking less agressively.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20190320/606c9327/attachment-0001.html>


More information about the dri-devel mailing list