Поддерживает ли Linux (ядро) сдвиг скорости Intel?

Я написал функцию оболочки POSIX, которая может использоваться для локального пространства имен встроенной функции или функции оболочки в любом из ksh93 , тире , mksh или bash (названы специально, потому что я лично подтвердил, что он работает во всех этих случаях) . Из оболочек, в которых я его тестировал, он не оправдал моих ожиданий только в yash , и я никогда не ожидал, что он вообще будет работать в zsh . posh не тестировал. Некоторое время назад я потерял всякую надежду на шикарный и не устанавливал его некоторое время. Может быть, он работает в posh ...?

Я говорю, что это POSIX, потому что, читая спецификацию, он использует преимущества определенного поведения базовой утилиты, но, по общему признанию, спецификация расплывчато в этом отношении, и, по крайней мере, один человек очевидно не согласен со мной. Как правило, у меня были несогласия с этим. В конце концов я обнаружил, что ошибка была моей собственной, и, возможно, я также ошибаюсь на этот раз в отношении спецификации, но когда я спросил его, он не ответил.

Однако, как я уже сказал, это определенно работает в вышеупомянутых оболочках, и в основном это работает следующим образом:

some_fn(){ x=3; echo "$x"; }
x=
x=local command eval some_fn
echo "${x:-empty}"

3
empty

Команда команда указана как в основном доступная утилита и одна встроенных функций до $ PATH 'd. Одна из его заданных функций - оборачивать специальные встроенные утилиты в собственное окружение при их вызове, и поэтому ...

{       sh -c ' x=5 set --; echo "$x"
                x=6 command set --; echo "$x"
                exec <"";  echo uh_oh'
        sh -c ' command exec <""; echo still here'
}

5
5
sh: 3: cannot open : No such file
sh: 1: cannot open : No such file
still here

... поведение обоих назначений командной строки, приведенных выше, является правильным по спецификации. Поведение обоих условий ошибки также является правильным и фактически почти полностью дублируется из спецификации. Назначения с префиксом для командных строк функций или специальных встроенных функций указываются для воздействия на текущую среду оболочки. Точно так же ошибки перенаправления считаются фатальными при указании на любую из них. Команда указана для подавления специальной обработки специальных встроенных функций в этих случаях, и случай перенаправления фактически демонстрируется на примере в спецификации.

Обычные встроенные команды, такие как команда , с другой стороны, указаны для запуска в среде подоболочки , что не обязательно означает, что другой процесс ], просто он должен быть принципиально неотличим от одного. Результаты вызова обычной встроенной функции всегда должны напоминать результаты, которые можно получить с помощью аналогичной команды $ PATH 'd. Итак ...

na=not_applicable_to_read
na= read var1 na na var2 <<"" ; echo "$var1" "$na" "$var2"
word1 other words word2

word1 not_applicable_to_read word2

Но команда command не может вызывать функции оболочки, и поэтому не может использоваться для того, чтобы сделать их специальную обработку спорной, как это может быть для обычных встроенных функций.Это также указано в спецификации. Фактически, в спецификации говорится, что основная полезность команды заключается в том, что вы можете использовать ее в функции оболочки оболочки, названной для другой команды, для вызова этой другой команды без саморекурсии, потому что она не будет вызывать функцию. Примерно так:

cd(){ command cd -- "$1"; }

Если вы не использовали команду , то функция cd почти наверняка вызвала бы ошибку segfault для саморекурсии.

Но как обычная встроенная команда, которая может вызывать специальные встроенные команды , команда может делать это в среде подоболочки . И поэтому, хотя текущее состояние оболочки, определенное в ней, может придерживаться текущей оболочки - конечно, прочитали $ var1 и $ var2 сделали - по крайней мере, результаты из определений командной строки, вероятно, не должно ...

Простые команды

Если имя команды не дается, или если имя команды является специальной встроенной функцией или функцией, присвоение переменных должно влиять на текущую среду выполнения. В противном случае назначения переменных должны быть экспортированы для среды выполнения команды и не должны влиять на текущую среду выполнения.

Независимо от того, определяет ли способность command быть как обычной встроенной функцией , так и для прямого вызова специальных встроенных функций, это всего лишь своего рода неожиданная лазейка в отношении командной строки. не знаю, но я знаю, что по крайней мере четыре уже упомянутые оболочки учитывают пространство имен command .

И хотя команда не может напрямую вызывать функции оболочки, она может вызывать eval , как показано, а значит, может делать это косвенно. Поэтому я создал оболочку пространства имен на основе этой концепции. Он принимает список аргументов, например:

ns any=assignments or otherwise=valid names which are not a command then all of its args

... за исключением того, что указанное выше слово command распознается как одно только в том случае, если его можно найти с пустым $ PATH . Помимо переменных оболочки с локальной областью видимости, названных в командной строке, она также выполняет локальную область видимости для всех переменных с помощью одного нижнегорегистр буквенных имен и список других стандартных, например $ PS3 , $ PS4 , $ OPTARG , $ OPTIND , $ IFS , $ PATH , $ PWD , $ OLDPWD и некоторые другие.

И да, путем локального определения переменных $ PWD и $ OLDPWD , а затем явно cd в $ OLDPWD и $ PWD , он также может довольно надежно охватить текущий рабочий каталог. Это не гарантировано, хотя очень старается. Он сохраняет дескриптор для 7 <.> и когда его цель переноса возвращается, он выполняет cd -P / dev / fd / 7 / . Если текущий рабочий каталог был unlink () 'в промежуточный период, он все равно должен, по крайней мере, вернуться в него, но в этом случае выдаст ужасную ошибку. И поскольку оно поддерживает дескриптор, я не думаю, что нормальное ядро ​​должно позволять отключать свое корневое устройство (???) .

Он также локально просматривает параметры оболочки и восстанавливает их до состояния, в котором они были найдены, после возврата из обернутой утилиты. Он обрабатывает $ OPTS особым образом, поскольку поддерживает копию в своей собственной области видимости, которой изначально присваивается значение $ - . После обработки всех назначений в командной строке он выполнит set - $ OPTS непосредственно перед вызовом своей цели переноса. Таким образом, если вы определите - $ OPTS в командной строке, вы можете определить параметры оболочки вашей целевой оболочки.Когда цель возвращается, она устанавливает + $ - - $ OPTS со своей собственной копией $ OPTS (на которую не влияют определения командной строки) и восстанавливает все в исходное состояние.

Конечно, ничто не мешает вызывающему объекту каким-то образом возвращаться из функции посредством цели переноса или ее аргументов. Это предотвратит любое восстановление / очистку состояния, которое в противном случае было бы предпринято.

Чтобы сделать все, что нужно, нужно пройти на три уровня eval . Сначала он оборачивается в локальную область видимости, затем изнутри он считывает аргументы, проверяет их на правильность имен оболочки и завершает работу с ошибкой, если находит то, чего нет. Если все аргументы действительны и в конечном итоге одна из команд command -v "$ 1" вернет истину (напомним: $ PATH на данный момент пуста) , она eval командная строка определяет и передает все оставшиеся аргументы цели переноса (хотя игнорирует особый случай для нс - потому что это было бы не очень полезно, и глубина трех eval более чем достаточно) .

В основном это работает так:

case $- in (*c*) ... # because set -c doesnt work
esac
_PATH=$PATH PATH= OPTS=$- some=vars \
    command eval LOCALS=${list_of_LOCALS}'
        for a do  i=$((i+1))          # arg ref
              if  [ "$a" != ns ]  &&  # ns ns would be silly
                  command -v "$a" &&
              !   alias "$a"          # aliases are hard to run quoted
        then  eval " PATH=\$_PATH OTHERS=$DEFAULTS $v \
                     command eval '\''
                             shift $((i-1))         # leave only tgt in @
                             case $OPTS in (*different*)
                                  set \"-\${OPTS}\" # init shell opts 
                             esac
                             \"\$@\"                # run simple command
                             set +$- -$OPTS "$?"    # save return, restore opts
                     '\''"
              cd -P /dev/fd/7/        # go whence we came
              return  "$(($??$?:$1))" # return >0 for cd else $1
        else  case $a in (*badname*) : get mad;;
              # rest of arg sa${v}es
              esac
        fi;   done
    ' 7<.

Есть еще несколько перенаправлений и несколько странных тестов, связанных с тем, как некоторые оболочки помещают c в $ - , а затем откажитесь принимать его как вариант для установить (???) , но все это вспомогательное, и в основном используется только для защиты от испускания нежелательного вывода и тому подобного в крайних случаях. Вот как это работает.Он может делать эти вещи, потому что он устанавливает свою собственную локальную область видимости перед вызовом своей обернутой утилиты во вложенном таком.

Это долго, потому что я стараюсь быть здесь очень осторожным - три эвалей сложно. Но с его помощью вы можете:

ns X=local . /dev/fd/0 <<""; echo "$X" "$Y"
X=still_local
Y=global
echo "$X" "$Y"

still_local global
 global

Сделать еще один шаг и настойчиво указать пространство имен локальной области видимости обернутой утилиты не должно быть очень сложно. И даже в том виде, в котором он написан, он уже определяет переменную $ LOCALS для обернутой утилиты, которая состоит только из разделенного пробелами списка всех имен, определенных в среде обернутой утилиты.

Например:

ns var1=something var2= eval ' printf "%-10s%-10s%-10s%s\n" $LOCALS '

... что совершенно безопасно - $ IFS был очищен до значения по умолчанию, и только допустимые имена оболочки помещаются в $ LOCALS , если вы не установите это самому в командной строке. И даже если в переменной разделения могут быть глобальные символы, вы можете установить OPTS = f в командной строке, а также для обернутой утилиты, чтобы запретить их расширение. На всякий случай:

LOCALS    ARG0      ARGC      HOME
IFS       OLDPWD    OPTARG    OPTIND
OPTS      PATH      PS3       PS4
PWD       a         b         c
d         e         f         g
h         i         j         k
l         m         n         o
p         q         r         s
t         u         v         w
x         y         z         _
bel       bs        cr        esc
ht        ff        lf        vt
lb        dq        ds        rb
sq        var1      var2      

А вот и функция. Все команды имеют префикс w / \ , чтобы избежать раскрытия псевдонима :

ns(){  ${1+":"} return
       case  $- in
       (c|"") ! set "OPTS=" "$@"
;;     (*c*)  ! set "OPTS=${-%c*}${-#*c}" "$@"
;;     (*)      set "OPTS=$-" "$@"
;;     esac
       OPTS=${1#*=} _PATH=$PATH PATH= LOCALS=     lf='
'      rb=\} sq=\' l= a= i=0 v= __=$_ IFS="       ""
"      command eval  LOCALS=\"LOCALS \
                     ARG0 ARGC HOME IFS OLDPWD OPTARG OPTIND OPTS     \
                     PATH PS3 PS4 PWD a b c d e f g h i j k l m n     \
                     o p q r s t u v w x y z _ bel bs cr esc ht ff    \
                     lf vt lb dq ds rb sq'"
       for a  do     i=$((i+1))
              if     \[ ns != "$a" ]         &&
                     \command -v "$a"  >&9   &&
              !      \alias "${a%%=*}" >&9 2>&9
              then   \eval 7>&- '\'    \
                     'ARGC=$((-i+$#))  ARG0=$a      HOME=~'           \
                     'OLDPWD=$OLDPWD   PATH=$_PATH  IFS=$IFS'         \
                     'OPTARG=$OPTARG   PWD=$PWD     OPTIND=1'         \
                     'PS3=$PS3 _=$__   PS4=$PS4     LOCALS=$LOCALS'   \
                     'a= b= c= d= e= f= g= i=0 j= k= l= m= n= o='     \
                     'p= q= r= s= t= u= v= w= x=0 y= z= ht=\   '      \
                     'cr=^M bs=^H ff=^L vt=^K esc=^[ bel=^G lf=$lf'   \
                     'dq=\" sq=$sq ds=$ lb=\{ rb=\}' \''"$v'          \
                            '\command eval       9>&2 2>&- '\'        \
                                   '\shift $((i-1));'                 \
                                   'case \${OPTS##*[!A-Za-z]*} in'    \
                                   '(*[!c$OPTS]*) >&- 2>&9"'\'        \
                                   '\set -"${OPTS%c*}${OPTS#*c}"'     \
                                   ';;esac; "$@" 2>&9 9>&-; PS4= '    \
                                   '\set  +"${-%c*}${-#*c}"'\'\"      \
                                          -'$OPTS \"\$?\"$sq";'       \
              '             \cd -- "${OLDPWD:-$PWD}"
                            \cd -P  ${ANDROID_SYSTEM+"/proc/self/fd/7"} /dev/fd/7/
                            \return "$(($??$?:$1))"
              else   case   ${a%%=*}      in
                     ([0-9]*|""|*[!_[:alnum:]]*)
                            \printf "%s: \${$i}: Invalid name: %s\n" \
                            >&2    "$0: ns()"   "'\''${a%%=*}'\''"
                            \return 2
              ;;     ("$a") v="$v $a=\$$a"
              ;;     (*)    v="$v ${a%%=*}=\${$i#*=}"
              ;;     esac
                     case " $LOCALS " in (*" ${a%%=*} "*)
              ;;     (*)    LOCALS=$LOCALS" ${a%%=*}"
              ;;     esac
              fi
       done'  7<.    9<>/dev/null
}

2
19.04.2019, 04:52
2 ответа

Должен поддерживаться с версии 3.19:

https://elixir.bootlin.com/linux/v3.19/source/drivers/cpufreq/intel_pstate.c

static void intel_pstate_hwp_enable(void)
{
    hwp_active++;
    pr_info("intel_pstate HWP enabled\n");

    wrmsrl( MSR_PM_ENABLE, 0x1);
}

другая фиксация (v3.19 -rc1):

Intel _pstate :Добавлена ​​поддержка HWP

https://github.com/torvalds/linux/commit/2f86dc4cddcb21290ca099e1dce2a53533c86e0b#diff-d06e88b1dd6d576c23e3654d87258879

2
27.01.2020, 21:53

Переключение скорости Intel, также известное как HWP (аппаратное обеспечение -управляемое P -состояния )работает для Intel Kaby Lake, начиная с ядра 4.10:

4
27.01.2020, 21:53

Теги

Похожие вопросы