Deux nouvelles versions de FreeBSD viennent de sortir pour ce début d'année: la version 6.3 et la toute nouvelle version 7.0.
La version 6.3 sortie le 18 janvier est la dernière version de maintenance de la branche RELENG_6, cette mise à jour concerne :
La version 6.3 sortie le 18 janvier est la dernière version de maintenance de la branche RELENG_6, cette mise à jour concerne :
- Correctifs de sécurité (bind, libarchive, random, openssl et libc)
- Amélioration de l'ACPI,
- Ajout de nombreux pilotes,
- Amélioration de freebsd-update qui permet maintenant, en plus des mises à jours de sécurité, de faire des montées de version.
- Réimplémentation de unionfs
- Amélioration du support des portables,
- Prise en charge de ZFS,
- Passage à GCC-4.2,
- Poursuite de la suppression du « Giant Lock »,
- Virtualisation complète de la pile réseau,
- Stabilisation et amélioration de l'ordonnanceur de processus « SCHED_ULE »,
- Gestion de la journalisation pour UFS,
- libthr devient la bibliothèque de gestions des threads par défaut.
Annonce FreeBSD 7.0 (500 hits)
Annonce FreeBSD 6.3 (96 hits)
Notes de sortie 7.0 (162 hits)
Notes de sortie 6.3 (67 hits)
Nouveautés FreeBSD 7.0 (272 hits)
Interview des développeurs sur les nouveautés de la 7.0 (199 hits)
> Lire la dépêche (90 commentaires, moyenne: 4,2).
Vous avez demandé le commentaire #909302.




TSO et LRO
> Toujours dans le domaine des réseaux il est maintenant possible
> d'utiliser certaines cartes accélératrices de type TSO (TCP/IP
> segmentation offload) et LRO (Large Receive Offload) au lieu de
> faire ces opérations uniquement avec le processeur central.
Cartes accélératrices est très abusé là...
TSO c'est juste découper un gros paquet à envoyer en plusieurs MTU et être capable d'ajuster quelques headers genre le numéro de séquence. Pas de quoi casser 3 pattes à un canard. Toutes les cartes modernes dignes de ce nom savent le faire.
LRO, c'est une autre histoire. Il n'a d'Offload que son nom. Agréger des paquets en réception implique de connaître l'état de toutes les connexions. C'est impossible dans les cartes réseau pour des raisons de ressources mémoire, de puissance et synchro avec l'hôte. Toutes les implémentations actuelles de LRO sont logicielles. C'est la pile basse de réception (au niveau des drivers) qui agrège des paquets avant de les passer à la pile haute (genre TCP) pour réduire les coûts. Mais on sait très bien faire ça sans assistance d'une carte "accélératrice". La plupart des drivers Linux qui font du LRO le font purement logiciellement.
Le seul point sur lequel les cartes peuvent aider le LRO, c'est le header-splitting qui consiste à déposer les headers et données en des endroits séparés en mémoire pour faciliter l'agrégation LRO au dessus. Certaines cartes savent faire ça (Neterion notamment), mais beaucoup de drivers n'en ont pas besoin pour avoir du LRO très performant (Myri-10G et eHEA notamment).
[^]Re: TSO et LRO
http://trac.neterion.com/cgi-bin/trac.cgi/wiki/FreeBSD/Readm(...)
http://www.FreeBSD.org/cgi/man.cgi?query=nxge&sektion=4&(...)
truc de ouf hein ? ;)
vjm
[^]Re: TSO et LRO
On est censé voir quoi de "ouf" la dedans? Y a aucun détail sur l'implementation. Ca reste du LRO software...
Pour les détails techniques, il vaut mieux regarder
http://lwn.net/Articles/244206/
http://fxr.watson.org/fxr/source/dev/mxge/mxge_lro.c?v=RELEN(...)
http://fxr.watson.org/fxr/source/dev/nxge/if_nxge.c?v=RELENG(...)
On y voit le code qui accumule logiciellement les paquets (code générique dans Linux, et code spécifique à 2 drivers dans FreeBSD). On se demande pourquoi ca s'appelle LR"O" au final...
[^]Re: TSO et LRO
Pour mieux "décharger" les bourses des pigeons^wclients qui l'achetent ?
[^]Re: TSO et LRO
et si tu regardes là
http://fxr.watson.org/fxr/source/dev/nxge/xgehal/xgehal-devi(...)
avec l'aide de http://fxr.watson.org/fxr/source/dev/nxge/include/xgehal-typ(...) ?
vjm
[^]Re: TSO et LRO
> et si tu regardes là
Je vois un driver qui agrege en software...
Tout se passe dans xge_hal_lro_process_rx():
La carte vient de déposer un nouveau paquet en mémoire, le driver appelle d'abord__hal_lro_capable() pour savoir si on peut agreger ce paquet, puis __hal_get_lro_session() pour recuperer/creer la session de LRO, puis __hal_append_lro() pour accumuler le paquet dans cette session. Il n'y aucune intervention de la carte dans tout ca.
Et comme tu peux le remarquer, le code n'est pas très compliqué. Il s'agit grosso-modo d'ajuster les checksums, longueur et numeros de sequence dans les headers IP et TCP, et de chainer les buffers de donnees.
Tu veux peut-être aussi que je t'explique comment LRO marche dans le driver que je maintiens dans Linux ? :)
[^]Re: TSO et LRO
> Tu veux peut-être aussi que je t'explique comment LRO marche dans le driver que je maintiens dans Linux ? :)
Ah, et bien si tu le propose... ça ne serait pas inintéressant de savoir :)
[^]Re: TSO et LRO
Pour ma défense, j'étais de bonne foi, je pensais sincèrement que neterion puisque leurs cartes le supportent et qu'ils sont les auteurs du driver avait fait ça correctement mais effectivement tes explications (qui sont bien meilleures que ce que j'avais compris et c'est normal vu ton expérience) m'oblige à le dire : je m'incline.
Et je suis également de l'avis d'herodiade, dis-nous tout :)
vjm
[^]Re: TSO et LRO
Dans Linux, y a du LRO spécifique a certains drivers (neterion et netxen iirc) et du LRO générique depuis peu. A terme tout le monde devrait utiliser le générique...
Pour bien suivre la suite, je conseille d'ouvrir net/ipv4/inet_lro.c pour voir le code du LRO générique auquel je vais faire reference ci-dessous ainsi que driver/net/ehea/ehea_main.c pour son utilisation dans le driver eHEA.
Lorsqu'un paquet arrive, les drivers normaux appelent netif_receive_skb() (ou netif_rx() selon si NAPI est actif ou pas) qui passe le paquet aux couches supérieures (genre IP et TCP). Si tu supportes LRO, tu appelles lro_receive_skb() a la place.
La-dedans, le vrai travail est fait dans __lro_proc_skb(). Quand cette fonction n'arrive pas a LROer, elle retourne une erreur et lro_receive_skb() se rabat sur les netif_receive_skb() ou netif_rx() habituels.
Le détail de __lro_proc_skb() maintenant. D'abord, elle utilise un callback get_skb_header() du driver pour recuperer des infos sur le paquet. Comme chaque carte stocke les headers et donnees de sa propre maniere, le callback est defini par le driver a l'initialisation et le LRO l'appelle quand il a besoin de trucs specifiques, l'endroit ou est stocké le header dans le paquet actuel en l'occurence.
Ensuite, __lro_proc_skb() verifie que c'est du IPv4 et TCP puis on essaie de recuperer un "descripteur" de LRO (l'equivalent des sessions de neterion) par lro_get_desc. On l'initialise si nécessaire, on vérifie que le nouveau paquet va bien juste après ce qui a deja ete recu dans ce descripteur, puis l'ajoute avec lro_add_packet()
lro_get_desc(), c'est juste un tableau de connexions en cours de LRO. Chaque driver en supporte un certain nombre (genre 8), limite plus ou moins arbitraire. Chaque arrivee de plein de paquets d'une meme connexion cree une session, et on la flushe un peu plus tard en passant l'agregation de tous les paquets d'un coup aux couches superieures.
Comme en general, meme si on a plein de connexions ouvertes, on a pas plein de paquet entrelacés de toutes les connexions a la fois, 8 sessions suffisent a peu pres pour couvrir les connexions qui bourrinent vraiment. A noter que si une connexion alterne entre activité et calme, elle acquiera/relachera des sessions LRO au fur et a mesure. On ne peut pas garder une session indefiniment, elle sera flushee de force de temps en temps pour la preter aux autres connexions. Bref ca marche :)
__lro_proc_skb() finit par l'ajout de paquet avec lro_add_packet(). C'est des trucs chiants de manipulation des buffers contenus dans le skb (on les chaine a la queueleuleu), et d'adaptation des longueurs, checksums et seqnums, pas grand chose d'intéressant.
La question finale, c'est "quand est-ce qu'on arrete d'agreger?". Deja, il y a un nombre max de paquets defini par le driver (lro_mgr->max_aggr, 64 souvent). De plus Linux n'aime pas les paquets de plus de 64ko, donc on arrete d'agreger avant.
Concretement, arreter d'agreger, c'est fermer une session et la passer aux couches superieures. On utilise lro_flush() pour faire ca. Elle finit d'ajuster les headers TCP/IP et passe le gros paquet agregé a netif_receive_skb() (ou netif_rx() selon si NAPI est actif). Apres ca, le descripteur/session LRO est relaché, donc une autre connexion (ou la meme) pourra l'utiliser.
De plus, on agrege les paquets qui se suivent dans une mem connexion. Mais si ca arrive pas dans l'ordre, on arrete d'agreger. Ca evite d'avoir a gerer des trous. Et aussi ca evite par exemple de passer des paquets tres tres dans le desordre aux couches superieures. Par exemple un paquet recent serait deja remonté pendant que des paquets vieux continueraient a se faire agreger au niveau du driver au lieu de remonter eux aussi.
Et enfin, on arrete d'agreger a intervalle vaguement regulier (quand NAPI fait un coup de polling du driver) pour éviter que des paquets soient ralentis trop longtemps dans le driver pour rien. On appelle lro_flush_all() qui fait lro_flush() sur tous les descripteurs/sessions en cours.
Vous pouvez aussi regarder drivers/net/myri10ge/myri10ge.c qui utilise le LRO generique avec des fragments (pages physiques discontigues) par opposition a eHEA qui utilise des skb lineaires (socket buffer contigus en memoire virtuelle). C'est juste une differente gestion de la memoire et de la facon dont la carte depose les paquets en reception. Le LRO fournit des fonctions *_skb() et *_frags() pour gerer les 2 modeles.
[^]Re: TSO et LRO
Ca me fait un peu penser aux cartes RAID intégrées ou non aux CM : toutes les CM grand public qui incluent du RAID sont en soft (fakeraid), et une grande partie des cartes PCI(e) qui font du RAID sont aussi du fakeraid (a moins d'y mettre au moins 300€), meme si pleins de constructeurs essayent de trouver des termes pour dire que la carte fait quand meme un petit peu de boulot. Mais en gros c'est juste un controleur IDE/SATA supplémentaires avec un BIOS qui permet de booter sur l'array. Mais après, tout est fait en soft ...