Jump to content

neologix

INpactien
  • Posts

    585
  • Joined

  • Last visited

Posts posted by neologix

  1. En fait, la majeure partie du temps utilisé l'est en espace utilisateur, ce qui rend totalement imprédictible le moment où ce situera le prochain ordonancement (dans le sens que l'on ne sait pas si cela arrive durant un code en mode noyau et si oui lequel).

    Justement, "on ne sait jamais". Sans préemption, tu sais que ton flot d'exécution ne sera pas interrompu (ou par une iterruption hard, mais on s'en fout ici), donc pas de problème. Tu parcours ta liste chainée, fais un kmalloc(GFP_KERNEL), manipule des données locales à un processeur, c'est pas grave. Mais dès que tu as de la préemption, et bien tu es obligé d'avoir recours à des {spin,read,write}_lock, à faire des kmalloc(GFP_ATOMIC), et de façon générale à introduire des méchanismes de synchronisation, et donc augmenter le risque de deadlock. En très schématique, preemption=>synchronisation=>deadlocks. En gros, ça augmente le parallèlisme de la machine. Maintenant, c'est vrai que normalement, du code SMP-safe est preemption-safe, mais il y a quelques exceptions :

    Starting with the 2.5 development kernel (and 2.4 with an available patch), the Linux kernel is fully preemptible. This feature allows processes to be preempted by higher-priority processes, even if the current process is running in the kernel. A preemptible kernel creates many of the synchronization issues of SMP. Thankfully, kernel preemption is synchronized by SMP locks, so most issues are solved automatically by writing SMP-safe code. A few new locking issues, however, are introduced. For example, a lock may not protect per-CPU data because it is implicitly locked (it is safe because it is unique to each CPU) but is needed with kernel preemption.

    For these situations, preempt_disable() and the corresponding preempt_enable() have been introduced. These methods are nestable such that for each n preempt_disable() calls, preemption will not be re-enabled until the nth preempt_enable() call. See the “Function Reference” Sidebar for a complete list of preemption-related controls.

    Tiré de http://www.linuxjournal.com/article/5833

    Aussi, il me semble que c'est pour cette raison qu'on ne peut pas faire de calculs en virgule flottante dans le noyau : si tu es préempté, comme le noyau ne sauve pas le registre FPU (en mode noyau :-), c'est le drame (en même temps, on peut très bien s'en passer ).

    En fait, c'est surtout lorsque j'ai porté des modules du 2.4 (non-préemptif) au 2.6 que j'ai compris ma douleur (et non, je ne suis pas un hacker, loin de là ;-).

  2. Salut à tous (ça faisait un moment...).

    Dites, j'ai une question qui me turlupine.

    Aujourd'hui je me suis "accroché" au boulot avec un collègue au sujet des impacts de la préemption.

    Je pense que la préemption facilite les deadlocks, par exemple il y a plus de risques de deadlocks avec CONFIG_PREEMPT qu'avec CONFIG_PREEMPT_VOLUNTARY ou CONFIG_PREEMPT_NONE, tout simplement parce qu'il y a plus de sections critiques, et donc de problèmes de synchronisation. En plus, mon expérience personnelle me conforte dans cette idée : j'ai porté un ensemble de modules de 2.4 vers 2.6, et ça a révélé pas mals de problèmes de synchro (deadlocks, pointeurs foireux...)

    Enfin, j'ai vu que les patches RT d'Ingo Molnar ont aussi permis de découvrir des problèmes similaires.

    Des avis?

  3. La dernière fois que j'ai regardé, Atheros avait pas mal de retard. je ne sais même pas s'il existe des 802.11g avec gestion du WPA...

    Perso, j'utilise du ralink, et ça marche très bien. La branche de développement rt2x00 (qui utilise la nouvelle pile mac80211 de devicescape) est même incluse dans le noyau vanilla depuis 2.6.25.

    Le pilote est libre, et pas besoin de firmware, c'est tout bon.

  4. JE ne pense pas que ça ait à voir avec la norme ansi, mais plutôt avec le type de descripteur auquel tu accèdes. stdout est quand même un descripteur hyper particulier. essaye dans un premier temps en faisant un stty -icanon (qui enlève le mode canonique). Si ça marche, tu peux modifier le comportement d'un terminal directement en C avec les termios :francais:

    En fait c'est setvbuf() (ANSI, les termios() sont des fcontions POSIX).

    Il y a trois mode :

    _IONBF unbuffered

    _IOLBF line buffered

    _IOFBF fully buffered

    Visiblement, les fichiers sont ouverts avec _IOFBF. Je voulais savoir si c'est spécifié dans la norme.

  5. Quelqu'un aurait la norme ANSI C sous la main?

    Avec ce programme :

    #include <stdio.h>
    #include <unistd.h>
    
    int main(void)
    {
    	fputs("Test\n", stdout);
    	sleep(1);
    
    	return 0;
    }

    un strace me donne :

    execve("./test_stdout", ["./test_stdout"], [/* 34 vars */]) = 0
    brk(0)								  = 0x804a000
    access("/etc/ld.so.nohwcap", F_OK)	  = -1 ENOENT (No such file or directory)
    mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f89000
    access("/etc/ld.so.preload", R_OK)	  = -1 ENOENT (No such file or directory)
    open("/etc/ld.so.cache", O_RDONLY)	  = 3
    fstat64(3, {st_mode=S_IFREG|0644, st_size=52007, ...}) = 0
    mmap2(NULL, 52007, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f7c000
    close(3)								= 0
    access("/etc/ld.so.nohwcap", F_OK)	  = -1 ENOENT (No such file or directory)
    open("/lib/i686/cmov/libc.so.6", O_RDONLY) = 3
    read(3, "\177ELF\1\1\1\\\\\3\3\1\\260e\1"..., 512) = 512
    fstat64(3, {st_mode=S_IFREG|0755, st_size=1360292, ...}) = 0
    mmap2(NULL, 1365616, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7e2e000
    mmap2(0xb7f76000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x148) = 0xb7f76000
    mmap2(0xb7f79000, 9840, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7f79000
    close(3)								= 0
    mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7e2d000
    set_thread_area({entry_number:-1 -> 6, base_addr:0xb7e2d6b0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
    mprotect(0xb7f76000, 4096, PROT_READ)   = 0
    munmap(0xb7f7c000, 52007)			   = 0
    fstat64(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 1), ...}) = 0
    mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f88000
    #############################
    write(1, "Test\n", 5Test
    )				   = 5
    rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
    rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
    rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
    nanosleep({1, 0}, {1, 0})			   = 0
    exit_group(0)						   = ?
    #############################
    Process 20532 detached

    donc il flush bien lorsqu'on balance '\n' dans une chaîne de caractère.

    Par contre, avec celui-là :

    #include <stdio.h>
    #include <unistd.h>
    
    int main(void)
    {
    	FILE *fp = fopen("/dev/null", "w");
    
    	fputs("Test\n", fp);
    	sleep(1);
    	fclose(fp);
    
    	return 0;
    }

    j'obtiens ça :

    execve("./test", ["./test"], [/* 34 vars */]) = 0
    brk(0)								  = 0x804a000
    access("/etc/ld.so.nohwcap", F_OK)	  = -1 ENOENT (No such file or directory)
    mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f9e000
    access("/etc/ld.so.preload", R_OK)	  = -1 ENOENT (No such file or directory)
    open("/etc/ld.so.cache", O_RDONLY)	  = 3
    fstat64(3, {st_mode=S_IFREG|0644, st_size=52007, ...}) = 0
    mmap2(NULL, 52007, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f91000
    close(3)								= 0
    access("/etc/ld.so.nohwcap", F_OK)	  = -1 ENOENT (No such file or directory)
    open("/lib/i686/cmov/libc.so.6", O_RDONLY) = 3
    read(3, "\177ELF\1\1\1\\\\\3\3\1\\260e\1"..., 512) = 512
    fstat64(3, {st_mode=S_IFREG|0755, st_size=1360292, ...}) = 0
    mmap2(NULL, 1365616, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7e43000
    mmap2(0xb7f8b000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x148) = 0xb7f8b000
    mmap2(0xb7f8e000, 9840, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7f8e000
    close(3)								= 0
    mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7e42000
    set_thread_area({entry_number:-1 -> 6, base_addr:0xb7e426b0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
    mprotect(0xb7f8b000, 4096, PROT_READ)   = 0
    munmap(0xb7f91000, 52007)			   = 0
    brk(0)								  = 0x804a000
    brk(0x806b000)						  = 0x806b000
    open("/dev/null", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
    fstat64(3, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0
    ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfe03a3c) = -1 ENOTTY (Inappropriate ioctl for device)
    mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f9d000
    rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
    rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
    rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
    #############################
    nanosleep({1, 0}, {1, 0})			   = 0
    write(3, "Test\n", 5)				   = 5
    close(3)								= 0[/b]
    munmap(0xb7f9d000, 4096)				= 0
    exit_group(0)						   = ?
    #############################
    Process 20558 detached

    il ne flush qu'après le sleep (au moment du close() en fait).

    Donc visiblement, le comportement dépend selon que le descripteur correspond à un tty ou non.

    Cela me semble étrange, et je n'ai pas la norme pour vérifier. Quelqu'un pourrait jeter un coup d'oeil?

    neo

  6. Bah, disons que pour le quidam, ce répertoire n'est pas vraiment utile (sauf s'il s'amuse à coder par exemple ;-), mais pour un admin qui s'occupe de pcs à la fac ou école d'ingé, il vaut mieux se pencher dessus si on ne veut pas que le moindre rigolo puisse crasher le serveur depuis le shell ou par ssh.

    Parmi les gourous qu'il y a ici, personne ne sait si on peut limiter le % de cpu utilisé?

  7. Facile, tu as ça :

    :(){ :|:& };:

    "Facile": toi tu ne connais pas mon niveau en bash!

    Où ":" est le nom de ta fonction (ça c'est de l'obfuscating :) ). Si on change le nom de la fonction ça donne :

    Effectivement, j'aurais pu comprendre si j'avais remarqué que ":" est le nom de la fonction. Je pensais que c'était un opérateur spécial (c'est vrai quoi, c'est pas conseillé d'autoriser des noms pareils ;-)

    En tout cas, merci pour cette explication!

  8. De quel code tu parles? :D

    Avec un while(), les processus ne se termineront jamais tant que la condition est vraie...

    donc avec un while(fork()); c'est clair que c'est nul

    mais un while(fork()!=-1); c'est pas mal (17 caractères)

    un while(fork()!=1); c'est pas mal aussi... (16 caractères)

    mais le mieux ça reste quand même le while(1)fork(); qui utilise une lettre de moins (15 caractères) ;)

    Bah, ça te remplit ta table de processus de zombies, ce qui est encore plus marrant!

    (Bon, on a peut-être pas le même sens de l'humour...)

    Sinon, un

    for(;;)fork();
    

    est plus court.

    Par contre, y'aurait quelqu'un pour décortiquer le fork-bomb en bash :non: ?

  9. Ah, je m'y attendais...

    Faites le test, vous verrez.

    En fait, ils vont tous être "defunct", des zombies quoi, parce que contrairement au dernier, ils se terminent, et ils n'ont pas été wait()é.

    Donc tute trimbales avec une table de processus remplie de defunct, ce qui est bien chiant aussi.

    Le problème c'est que vous n'avez pas une bonne vision du pid renvoyé par fork().

    Ce n'est pas un entier dont la valeur est fixée (d'ailleurs elle ne peut pas être partagée), mais elle dépend du processus en exécution.

    exemple:

    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    
    main()
    {
    	pid_t pid;
    	int rv;
    
    	switch(pid=fork()) {
    		case -1:
    			perror("fork");  /* something went wrong */
    			exit(1);		 /* parent exits */
    
    		case 0:
    			printf(" CHILD: This is the child process!\n");
    			printf(" CHILD: My PID is %d\n", getpid());
    			printf(" CHILD: My parent's PID is %d\n", getppid());
    			printf(" CHILD: Enter my exit status (make it small): ");
    			scanf(" %d", &rv);
    			printf(" CHILD: I'm outta here!\n");
    			exit(rv);
    
    		default:
    			printf("PARENT: This is the parent process!\n");
    			printf("PARENT: My PID is %d\n", getpid());
    			printf("PARENT: My child's PID is %d\n", pid);
    			printf("PARENT: I'm now waiting for my child to exit()...\n");
    			wait(&rv);
    			printf("PARENT: My child's exit status is: %d\n", WEXITSTATUS(rv));
    			printf("PARENT: I'm outta here!\n");
    	}
    }
    

    Si c'était une vraie variable, le switch ne fonctionnerait pas.

  10. Ca dépend surtout de l'application. Par exemple, j'ai eu des problèmes avec amarok et gxine.

    Si tu n'as pas les mêmes versions d'applications, il est possible que le bug ait été corrigé.

    Je crois que la gestion de L'HT sous Linux est propre, ça a été le premier OS à l'implémenter, et le patch a été fourni par Intel.

    Le problème, c'est que les développeurs n'ont pas forcément un HT ou un bi-pro sous la main, alors les problèmes dûs au multithreading, et bien ils ne les voient pas, ou n'arrivent pas à les reproduire.

    J'ai déjà codé quelques applis multithread, et bien c'est pas évident.

    Pour tester, utilisez amarok <1.3, ou gxine <= 0.4.8

    Chez moi, il n'y a pas photo: HT => gxine crashe quand passé en fullscreen.

    edit:

    Apparemment, le problème vient du noyau. D'ailleurs c'est plutôt logique, parce que l'HT est cnsé être vu comme du multiprocesseur, mais seul l'HT pose problème.

    Je ne sais pas si certains bossent dessus.

  11. Salut à tous.

    Juste un passage pour vous signaler que si vous avez des crahs aléatoires sur un processeur qui gère l'hyperthreading, il ne faut pas chercher plus loin. Il faut utiliser un noyau sans HT.

    Par exemple, gxine crashait àchauqe fois que je le passais en fullscrenn, maintenant aucun problème.

    J'avais aussi des problèmes avec amarok, et apparemment ils ont été résolus depuis le 1.3.5, mais étaient bien lié à l'HT.

    Les applications multithread sont difficiles à concevoir, cela pose des problèmes de sunchronisation, etc. Je vous conseille de ne pas activer l'HT.

    neo

  12. en testing, il n'y a plus un seul logiciel de lectre multimedia.
    Je suis en testing et j'ai deux moteurs (xine et gstreamer) et comme player gxine, totem, xfmedia (et mplayer de marrillat, mais ça ne compte pas)

    Par contre vlc est en stable.

    Ah et je précise que le jour où tu me vois utiliser autre chose que main... RDDV millitera contre les DRM et installera une lfs...

    theocrite@pascal  vrms
    No non-free packages installed on pascal!  rms would be proud.

    Oui, mais je tourne sous fluxbox.

    Installer gnome juste pour pouvoir lire mes films, ça me gonfle.

    J'ai essayé gxine, mais dès que je le passe en fullscreen il plante.

    Pour ce qui est des brevets, il ne faut pas s'étonner.

    Moi je vais brevetter l'addition, les anneaux, les isomorphismes et la théorème de Fermat-Wiles. Quelle bande de débiles...

    Par contre ça fera chier les projets plus confinés comme OpenBSD où le travail est de bonne qualité mais n'avance pas vite du fait du nombre ultra limité de devs et l'audi du code (qui prend beaucoup de temps).

    Sachant qu'il est dur (impossible) de trouver aussi bien que OpenSSH OpenNTPD ou tout simplement OpenBSD...

    Bref, ça craint :cartonrouge:

    (en fait ça fait un peu plus qu'une ligne).

    Je ne m'en fais pas pour OpenBSD et ses copains, ils sont trop importants. Je crois que Theo de Raadt est un mec vachement influant, qui est sponsorisé par des gouvernements, etc.

×
×
  • Create New...