AMD всегда в своем руководстве описывала реализацию LFENCE
как инструкцию по сериализации загрузки.
Действует как барьер для принудительного упорядочивания памяти (сериализации) между инструкциями загрузки, предшествующими LFENCE, и инструкциями загрузки, которые следуют за LFENCE.
Первоначальный вариант использования LFENCE
заключался в том, чтобы упорядочивать загрузки типа памяти WC. Однако после того, как были обнаружены уязвимости спекулятивного исполнения, AMD в январе 2018 года выпустила документ, озаглавленный «Программные методы управления спекуляциями на процессорах AMD». Это первый и единственный документ, в котором упоминается MSR C001_1029 [1] (другие биты C001_1029 обсуждаются в некоторых документах AMD, но не бит 1). Когда C001_1029 [1] установлен в 1, LFENCE
ведет себя как инструкция диспетчеризации сериализации (что дороже, чем просто сериализация загрузки). Поскольку этот MSR доступен на большинстве старых процессоров AMD, кажется, что он почти всегда поддерживался. Может быть, потому что они думали, что в будущем им может понадобиться поддерживать совместимость с процессорами Intel в отношении поведения LFENCE
.
Существуют исключения из правил упорядочивания инструкций ограждения и инструкций и инструкций сериализации, которые имеют свойства сериализации. Эти исключения слегка различаются между процессорами Intel и AMD. Примером, о котором я могу думать прямо сейчас, является инструкция CLFLUSH
. Итак, AMD и Intel имеют в виду несколько разные вещи, когда говорят об инструкциях со свойствами сериализации.
Одна вещь, которая мне не ясна, - это следующая часть цитаты из ответа Харлода:
Процессоры AMD семейства 0Fh / 11h всегда поддерживают LFENCE как сериализацию, но не поддерживают этот MSR.
Это заявление расплывчато, потому что в нем четко не говорится, является ли LFENCE
в семействах AMD 0Fh и 11h полностью сериализоваться (в терминологии AMD) или сериализоваться с отправкой (в терминологии AMD). Но, скорее всего, это только сериализация отправки. В руководствах AMD для конкретных семейств не упоминается LFENCE
или MSR C001_1029.
Начиная с ядра Linux v4.15-rc8, используются свойства сериализации LFENCE
на процессорах AMD. Изменение состоит из двух коммитов 1 и 2. Были определены следующие макросы:
+#define MSR_F10H_DECFG 0xc0011029
+#define MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT 1
Первый макрос указывает адрес MSR, а второй указывает смещение. Следующий код был добавлен в init_amd
(некоторые комментарии мои):
/* LFENCE always requires SSE2 */
if (cpu_has(c, X86_FEATURE_XMM2)) {
unsigned long long val;
int ret;
/* The AMD CPU supports LFENCE, but there are three cases to be considered:
* 1- MSR C001_1029[1] must be set to enable the dispatch
* serializing behavior of LFENCE. This can only be done
* if and only if the MSR is supported.
* 2- The MSR is not supported (AMD 0Fh/11h). LFENCE is by
* default at least dispatch serializing. Nothing needs to
* be done.
* 3- The MSR is supported, but we are running under a hypervisor
* that does not support writing that MSR (because perhaps
* the hypervisor has not been updated yet). In this case, resort
* to the slower MFENCE for serializing RDTSC and use a Spectre
* mitigation that does not require LFENCE (i.e., generic retpoline).
/*
* A serializing LFENCE has less overhead than MFENCE, so
* use it for execution serialization. On families which
* don't have that MSR, LFENCE is already serializing.
* msr_set_bit() uses the safe accessors, too, even if the MSR
* is not present.
*/
msr_set_bit(MSR_F10H_DECFG,
MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT);
/*
* Verify that the MSR write was successful (could be running
* under a hypervisor) and only then assume that LFENCE is
* serializing.
*/
ret = rdmsrl_safe(MSR_F10H_DECFG, &val);
if (!ret && (val & MSR_F10H_DECFG_LFENCE_SERIALIZE)) {
/* A serializing LFENCE stops RDTSC speculation */
set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
/* X86_FEATURE_LFENCE_RDTSC is used later to choose a Spectre
mitigation */
} else {
/* MFENCE stops RDTSC speculation */
set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC);
}
}
Начиная с v5.4-rc1, код проверки записи MSR был удален. Итак, код стал:
msr_set_bit(MSR_F10H_DECFG,
MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT);
set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
Причина этого изменения обсуждается в сообщении о фиксации. (Таким образом, в большинстве случаев это не нужно и может не работать.)
В этом документе также говорится:
Все процессоры семейства AMD 10h / 12h / 14h / 15h / 16h / 17h поддерживают этот MSR. Поддержка LFENCE обозначается битом 26 EDX функции1 CPUID, SSE2. Процессоры AMD семейства 0Fh / 11h всегда поддерживают LFENCE как сериализацию, но не поддерживают этот MSR.
Но похоже, что ни одно из руководств AMD еще не обновлено, чтобы упомянуть поддержку C001_1029 [1].
AMD сообщила в этом документе следующее:
AMD планирует поддержку этого MSR и доступ к нему для всех будущих процессоров.
Это означает, что C001_1029 [1] следует рассматривать как архитектурный для будущих процессоров AMD (относительно января 2018 г.).
person
Hadi Brais
schedule
14.08.2018
lfence
не сериализируется на Intel. Этот термин имеет техническое значение, которое включает полную очистку буфера хранилища. напримерcpuid
иiret
сериализуются.lfence
сериализует только поток команд / ядро с нарушением порядка, не весь конвейер, включая буфер хранения. Я обычно говорю, что это частичная сериализация или что-то в этом роде. - person Peter Cordes   schedule 15.08.2018cpuid
, но они также используют только сериализацию для других вещей, включая вещи, которые не являются инструкции по сериализации. В предложении в разделе lfence непосредственно перед тем, что я процитировал, используется термин операция сериализации по отношению кlfence
. - person BeeOnRope   schedule 15.08.2018isa
и добавить тегmemory-barriers
, который более уместен. - person Hadi Brais   schedule 15.08.2018[memory-barriers]
, потому что нас не интересует эффект барьера памятиlfence
. Мы знаем, что это так, и это отвлекающий маневр, который отвлекает от вопроса о его другом эффекте. Однако я не настаиваю на его удалении, если вы и @Bee не находите этот аргумент убедительным. - person Peter Cordes   schedule 15.08.2018lfence
, по крайней мере, представлен как барьер памяти, а - барьер памяти, и этот побочный эффект блокировки OoO на самом деле является результатом дизайна реализации для его первоначальная основная функция. Если вас интересуетlfence
как барьер, весьма вероятно, что вы заботитесь о производительности, а также, возможно, заботитесь об этом блокирующем поведении OoO. Примите противоположную позицию: вы упоминаетеlfence
поведение OoO почти каждый раз, когда инструкция появляется в контексте ... - person BeeOnRope   schedule 15.08.2018lfence
, поэтому имеет смысл упоминать ее всякий раз, когда она возникает в контексте барьера памяти, но, возможно, не наоборот. т.е. я исправляю заблуждение, чтоlfence
полезен как барьер памяти. Но я думаю, вы правы, возможно, люди, выполняющие поиск по тегам на[x86] [memory-barriers]
, найдут этот вопрос и чему-нибудь научатся. Мне все еще понравилось редактирование моего заголовка, хотя вы убедили меня в тегах, но это ваш вопрос. - person Peter Cordes   schedule 15.08.2018LFENCE
(которая раньше должна была быть только барьером загрузки) была переопределена как барьер для спекулятивного выполнения в 2018 году. - person Brendan   schedule 19.10.2019lfence
может или не может быть сериализован в зависимости от значения, установленного в MSR. - person BeeOnRope   schedule 19.10.2019