diff --git a/figs/lstopo.pdf b/figs/lstopo.pdf new file mode 100644 index 0000000..c2c7160 Binary files /dev/null and b/figs/lstopo.pdf differ diff --git a/main.tex b/main.tex index 00cfcb8..e761512 100644 --- a/main.tex +++ b/main.tex @@ -20,8 +20,8 @@ % titre \title{Caractérisation de l’instruction \texttt{clflush} sur systèmes multi-\ang{socket}} -\author{\textsc{Augustin LUCAS}\\ENS de Lyon\\ \\Encadré par :\\ -\textsc{Guillaume DIDIER}, \textsc{Angeliki KRITIKAKOU}\\ +\author{Augustin \textsc{Lucas}\\ENS de Lyon\\ \\Encadré par :\\ +Guillaume \textsc{Didier}, Angeliki \textsc{Kritikakou}\\ Équipe \textsc{Taran}\\ Laboratoire \textsc{Irisa}\\ Université de \textsc{Rennes} 1} @@ -46,24 +46,35 @@ Université de \textsc{Rennes} 1} \section{Introduction} -\TODO{ - Points à aborder - \begin{itemize} - \item NUMA balancing - \item Low Core Count, possibilité cores fantôme - \item Pourquoi nombre de coeurs = puissance de 2 ? - \end{itemize} -} +\TODO{Réordonner, faire des liens entre les subsubsections} + +\subsubsection{Low Core Count} + +Pour répondre à des demandes variées, \ang{Intel} base ses processeurs serveurs sur +trois tailles \TODO{à partir de la micro-architecture Haswell ?}: +\begin{itemize} + \item LCC (\ang{Low Core Count}) : de 4 à 8 coeurs physiques pour + la micro-architecture Haswell (jusqu'à 10 pour Broadwell) + \item MCC (\ang{Medium Core Count}) : de 10 à 12 coeurs pour Haswell (12 à 14 pour Broadwell) + \item HCC (\ang{High Core Count}) : de 14 à 18 coeurs pour Haswell (16 à 24 pour Broadwell) +\end{itemize} + +Les machines que nous utiliserons sont uniquement basées sur la \ang{die} LCC, mais certaines +(les Broadwell à 8 coeurs par exemple) sont alors livrées avec des coeurs désactivés. La \ang{slice} +de cache L3 associée est alors désactivée également. Cela pose tout de même question sur la possibilité +de sauts supplémentaires dûs à ces coeurs manquants. \TODO{Alors, quel est le coeur désactivé ? +Est-ce similaire sur toutes les puces du même modèle ou choisi spécifiquement en usine ? Quelle +est la conséquence dans ce cas ?} \subsection{Hiérarchie de cache} La mémoire DRAM d'un ordinateur est lente comparée à la fréquence du CPU. Le CPU dispose donc de caches, -basés sur une mémoire SRAM, plus petite mais plus rapide. Stocker en cache les éléments accédés +basés sur des mémoires SRAM, plus petites mais plus rapides. Stocker en cache les éléments accédés le plus fréquemment permet donc de réduire le nombre d'appels à la mémoire et donc le temps d'exécution. Les processeurs que nous étudions disposent de 3 niveaux de cache : L1, L2, L3. -Chaque coeur possède, au premier niveau, un L1i (cache des instructions) et -un L1d (cache des données). Au second niveau, il possède un L2 qui contient potentiellement +Chaque coeur possède, au premier niveau, un L1-I (cache des instructions) et +un L1-D (cache des données). Au second niveau, il possède un L2 qui contient potentiellement des données et des instructions. Au dernier niveau, le L3 est partagé entre tous les coeurs de la \ang{socket}, et celui-ci est inclusif de tous les caches de niveau inférieur : toute ligne stockée dans le cache L1 ou L2 est également dans le L3. @@ -75,7 +86,7 @@ mais est réparti en différentes \ang{slices} : des tranches de mémoire accol \begin{figure}[ht] \centering \includegraphics[width=0.4\textwidth]{broadwell-die-shot} - \caption{Broadwell Deca-Core die shot by Intel - annotated by Wikichip~\cite{broadwelldieshot}} + \caption{Broadwell Deca-Core die shot by Intel - annotated by Wikichip~\cite{broadwell-wikichip}} % L'espace vide l'est bien sur le die-shot, donc sûrement "Intel being stupid" \end{figure} @@ -85,6 +96,34 @@ la ligne y est chargée également. Une fonction de hachage non-documentée attr physique une unique \ang{slice} dans laquelle elle peut être mise en cache. Différents travaux~\cite{slice-reverse, practicalTiming} ont permis de déterminer cette fonction. +\label{poweroftwo} Si les fonctions initialement utilisées +étaient simplement basés sur certains bits de l'adresse, +la fonction de hachage utilisée à partir de la micro-architecture Sandy Bridge +(et au moins jusqu'à Tiger Lake) utilise le XOR de plusieurs bits de chaque adresse physique +pour générer chaque bit du numéro de \ang{slice}. Alors, la fonction de hachage est linéaire sur les +processeurs avec un nombre de coeurs qui est une puissance de 2, mais une composante non-linéaire +s'ajoute sur les autres processeurs. + +\subsubsection{\ang{NUMA}} + +\begin{figure}[ht] + \centering + \includegraphics[width=1.0\textwidth]{lstopo} + \caption{Topologie \ang{NUMA} de \textit{paravance} extraite + avec l'outil \texttt{lstopo} de \texttt{hwloc}} +\end{figure} + +Dans un système à plusieurs \ang{sockets}, chaque \ang{socket} a de la mémoire DRAM à laquelle il +peut accéder directement. Sur les machines Intel, le \ang{QPI} (\ang{QuickPath Interconnect}) +permet à un processeur d'accéder au données localisées dans la mémoire rattachée à un autre processeur. + +Le principe \ang{NUMA} (\ang{Non-uniform memory access}) délimite alors des groupes contenant +un processeur et les adresses mémoire qui en sont rapprochées et les transmet au système d'exploitation. +Cela permet à ce dernier d'allouer la mémoire dans les adresses proche du processeurs qui en a besoin. + +Sur Linux, si beaucoup d'accès mémoire sont réalisés d'un processeur +à des adresses qui lui sont éloignées, les pages correspondantes sont migrées. + \subsection{Protocoles de cohérence de cache} Dans des systèmes à plusieurs coeurs, d'autant plus avec plusieurs processeurs, où chaque coeur a @@ -121,11 +160,6 @@ même \ang{socket}, mais par \ang{snooping} entre les deux \ang{sockets}. \subsubsection{Mémoire partagée} -\TODO{était bien formulé dans le 2.2 de~\cite{flushflush} -donc reprend largement les mêmes idées, ce n'est pas une citation et ces infos -ne sont pas non plus particulières à ce papier. -Comment dire que ça en est inspiré, faut-il le faire ?} - Les systèmes d'exploitation utilisent le principe de mémoire partagée pour réduire l'utilisation totale de mémoire physique. C'est-à-dire que différentes pages de mémoire virtuelle correspondent à une même page de mémoire physique, @@ -141,8 +175,8 @@ les différentes instances du programme. Une autre forme de déduplication consiste à regarder les pages de mémoire contenant les mêmes données et à les combiner. -Cela peut amener différents processus \TODO{\ang{sandbox}és} -ou même de machines virtuelles différentes à partager des données en commun. +Cela peut amener différents processus \ang{sandbox}és +même de machines virtuelles différentes à partager des données en commun. \subsubsection{L'instruction \texttt{clflush}} @@ -246,10 +280,24 @@ messages échangés en fonction de l'état de cohérence des lignes évincées du cache. Cela passe par l'étude des sources de variabilité et permet de mieux choisir un seuil propre à chaque combinaison attaquant/victime/\ang{slice}. -Ce travail s'était intéressé à certains processeurs Intel de micro-architectures \ang{Coffee Lake} et +Ce travail s'était intéressé à certains processeurs Intel de micro-architectures +\ang{Coffee Lake} et \ang{Haswell} à une seule \ang{socket}, mais a révélé que les résultats seraient bien plus complexes sur des systèmes à plusieurs \ang{sockets}. +\TODO{paragraphe à déplacer} +\label{nonprivilegedinfo} Dans un scénario réel, +l'attaquant peut choisir le coeur sur lequel il s'exécute, +a accès au coeur sur lequel le processus victime s'exécute via \texttt{/proc/pid}. +La \ang{slice} peut-être trouvée en utilisant l'adresse physique mais cette information demande +généralement des privilèges qu'un attaquant n'aura pas. En revanche, si la fonction de hachage +est linéaire -- ce qui est le cas si le nombre de coeurs +est une puissance de 2 (\ref{poweroftwo}) -- +il est possible de définir une classe d'équivalence des adresses des pages qui appartiennent aux +mêmes \ang{slices}. Une connaissance fine d'éléments dépendants du numéro de \ang{slice} -- comme +le temps d'exécution de \texttt{clflush} dans certaines conditions -- permettrait alors +de déterminer la \ang{slice}. + \section{Organisation des expériences} Les expériences ont été faites sur 6 machines différentes, @@ -258,8 +306,7 @@ par processeur répondant aux critères suivants: \begin{itemize} \item Processeur Intel ; \item Exactement 2 \ang{socket} ; - \item Nombre de coeurs par \ang{socket} est une puissance de - deux \footnote{\TODO{l'expliquer en amont et le rappeler ici, voir Intro}} ; + \item Nombre de coeurs par \ang{socket} est une puissance de deux \item Micro-architecture antérieure à SkyLake\footnote{Le L3 n'est plus inclusif sur les processeurs serveur à partir de SkyLake et la topologie devient plus complexe} \end{itemize} @@ -281,12 +328,29 @@ Les machines suivantes ont donc été utilisées~\cite{g5k-nodes} \end{tabular} \end{center} -Le turbo a été désactivé sur toutes les machines. -La fréquence des coeurs fixée : à la fréquence minimale supportée par les processeurs ; -le mode performance ne donnant pas le même résultat que sur les machines \ang{Intel Core}. -Le \ang{NUMA balancing} a également été désactivé (à l'échelle du système), -ce qui peut se faire pour le processus courant sans -privilèges\footnote{\TODO{à vérifier ! voir les "À faire"}}. +La prise de mesure consistait à relever pour un lot d'adresse (chacune correspondant à une \ang{slice}) +les temps d'exécution de l'instruction \texttt{clflush} pour toutes les paires de coeurs +et tous les états de cohérence possibles. + +Initialement, le turbo était désactivé sur toutes les machines, la fréquence des coeurs était fixée +à la fréquence maximale en activant le mode "performance" via \texttt{cpufreq}. + +Nous avons trouvé que: +\begin{itemize} + \item Contrairement aux machine \ang{Intel Core}, le mode performance ne permet pas + de fixer la fréquence de tous les coeurs à la fréquence maximale possible. + Nous avons donc fixé la fréquence des coeurs à la fréquence minimale (généralement 400MHz) ; + \item L'architecture \ang{NUMA} impliquant de déplacer les pages exploitées principalement par un + processeur distant, les adresses physiques changeaient durant l'expérience, ce qui rendait + tous les résultats complètement incohérents. + Nous avons donc désactivé le \ang{NUMA balancing} via \texttt{numactl}, + ce qui peut se faire pour le processus courant sans privilèges\footnote{ + Il faudrait vérifier que cela fonctionne aussi pour les pages + partagées comme les bibliothèques + }. + \item Nous avons également fixé la fréquence de l'\ang{uncore} via un MSR, mais cela n'a + pas eu de grand impact sur la clarté des résultats. +\end{itemize} Les fichiers de résultats bruts sont accessibles en ligne~\cite{g5k-results}. @@ -332,17 +396,12 @@ c'est la numérotation que nous utiliserons pour la suite: Pour trouver la numérotation des \ang{slices}, deux méthodes sont possibles: \begin{itemize} + \item Utiliser la méthode proposée pour un attaquant non-privilégié (\ref{nonprivilegedinfo}). + Cela nécessite une connaissance préalable de la topologie ; \item Utiliser les compteurs de performance pour déterminer la \ang{slice} d'une adresse. Cela nécessite de lire les MSR correspondants donc d'avoir un accès \ang{root}. Nous avons suivi cette méthode - afin d'être sûr que les numéros de \ang{slice} correspondent aux numéros de coeurs ; - \item Utiliser la fonction de hachage~\cite{slice-reverse} pour - déterminer la \ang{slice} de chaque adresse. Comme la fonction est appliquée sur - l'adresse virtuelle et non pas physique, celle-ci est déterminée à permutation - près.\footnote{\TODO{référence à l'explication du nb de coeur = puissance de 2 en intro}} - Il serait envisageable de donner une méthode permettant de - réordonner automatiquement les \ang{slices}, et donc de déterminer l'information de la slice - depuis un utilisateur non privilégié. + afin d'être sûr que les numéros de \ang{slice} correspondent aux numéros de coeurs. \end{itemize} diff --git a/refs.bib b/refs.bib index d66f71c..72a53be 100644 --- a/refs.bib +++ b/refs.bib @@ -32,7 +32,7 @@ HAL_VERSION = {v1}, } -@misc{broadwelldieshot, +@misc{broadwell-wikichip, title={Broadwell - Microarchitectures - Intel - WikiChip (2024)}, url={https://en.wikichip.org/wiki/intel/microarchitectures/broadwell_(client)#Deca-core_Broadwell}, note={\url{https://en.wikichip.org/wiki/intel/microarchitectures/broadwell_(client)#Deca-core_Broadwell}},