Forum Linux.noyau IRQ gpio sauvegarder pendant une disable_irq comment faire pour les reseter avant un enable_irq

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
1
11
avr.
2016

Bonjour,
J'ai conçue un petit module d'échange de mémoire à travers le sdma et synchronisé par des IRQ gpio. Ce module a été écris sur imx6 dual et version de noyau 3.10. Mon module fonctionne bien en général. Mais j'ai un petit soucis lorsque je disable les irq. Pour plusieurs raison j'ai besoin de temps en temps de disable les irq gpio. Pendant se laps de temps il peut arriver que je reçoive des irq (les gpios envoient des signaux) bien sur comme elles sont déconnectées les fonctions d'interruption respectives ne sont pas appelées. Donc jusque l'à tout va bien. Mais le problème vient au moment ou je reconnecte les irq. Ces irqs qui sont arrivées pendant que j'avais tout déconnecté ont été mémorisées et du coup derrière lorsque je reconnecte, mes fonction d'interruption sont appelées du nombre d'irq sauvegardées or je voulais les jeté ces irq. Si j'ai bien compris c'est normale que les irq soit sauvegardées d'après le site https://www.safaribooksonline.com/library/view/understanding-the-linux/0596005652/ch04s06.html#understandlk-CHP-4-SECT-6.2 chapitre Reviving a lost interrupt.
Donc ma question comment je peux jeter ces irq avant de reconnecter les irq ?

Les fonctions utilisées pour gerer mes irq sont:

  • request_irq pour la creation
  • free_irq pour les libéré
  • disable_irq pour deconnecter
  • enable_irq pour les connecté

Merci d'avance pour vos réponse
Yodalesage

  • # dans ton code

    Posté par  . Évalué à 2.

    Donc ma question comment je peux jeter ces irq avant de reconnecter les irq ?

    tu ne peux pas, donc tu reconnectes, tu les recois, et tu ne les interpretes pas.
    avec un peu de chance il y a un timestamp avec l'IRQ, donc tu peux ignorer les IRQ qui sont arrivées pendant que c'etait deconnecté.

  • # Il est urgent de ne rien faire

    Posté par  . Évalué à 1.

    Afin de répondre à ta question il faut savoir que tu manipules deux types d'interruptions.
    - Les interruptions matérielles, qui sont gérées par la couche matérielle GPIO je suppose. Ces interruptions sont remontées via un contrôleur matériel d'interruptions au processeur. Ce contrôleur peut être configuré pour masquer ou laisser passer certaines interruptions ainsi que gérer les priorités.
    - Les interruptions logicielles, c'est la façon générique de manipuler les interruptions que reçoit le processeur donc après le passage dans le contrôleur d'interruption.

    Les fonctions enable_irq / disable_irq vont certainement uniquement masquer les interruptions au niveau du contrôleur d'IT, ce qui veut dire que pendant que tu désactives les interruptions le matériel continue de recevoir des interruptions et de les remonter au contrôleur d'IT.

    La solution que tu demandes consisterais à désactiver les interruptions matérielles pendant ton traitement. C'est possible mais je ne suis pas sûr que Linux te fournisse un lien entre ton interruption et la fonction de désactivation de la source de cette interruption (ça existe peut-être ceci dit)

    Pourquoi Linux fonctionne de cette manière ? Car en général quand on désactive / réactive les interruptions c'est pour ne pas être interrompu pendant une section critique, ce genre de chose. Quand on réactive les interruptions on souhaite souvent être prévenu si un événement a eu lieu pendant ce temps.

    En désactivant les interruptions matérielles tu dois être absolument certain qu'aucune race condition ne peut arriver. Si le volume d'interruptions est soutenable par le système je te conseille de ne pas chercher à désactiver les interruptions matérielles. Dans le pire des cas ton handler d'IT sera appelé quelques fois pour rien, ça ne devrait pas être grave.

    Je te déconseille d'essayer d'utiliser le timestamp pour décider si une IT est à jeter ou non, c'est trop hasardeux car Linux n'est pas assez précis là dessus et que ça rajoute encore plus de race conditions.

    ça te plaît qu'on te dise qu'il est urgent de ne rien faire ou la solution proposée ne convient vraiment pas à ton usage ? Si c'est le cas essaye de nous expliquer plus en détail ce que tu fais ça pourra nous aider à mieux répondre.

  • # suite irq sauvegarde

    Posté par  . Évalué à 1.

    Au final ce que je souhaite faire transferer des donnés via un bus eim entr un fpga et un imx6dl
    En utilisant le sdma du imx6.
    Pour l'instant je n'ai pas le hard du fpga.
    Le fpga me donnera des top d'une fifo à vider via une pin out. Cette pin out en faite représente quand le niveau de remplissage de moitié (niveau threashold) est arrivé dans la fifo. Donc l'idée mettre cette pin out en temps qu'irq et lorsqu'elle à état bas transférer les données.
    Il est tout à fait possible dans ce cas que lorsque le micro lis les données à travers le bus eim le niveau threashold soit de nouveau à bas car de sont coté le fpga reçoit lui aussi des donnée en continue. Or je ne dois pas prendre en compte cette interruption. C'est seulement qu'une fois que j'aurais fini de lire mes données que le micro pourra de nouveau regarder les its.

    Tout ça c'est le fonctionnement final. Pour l'instant je simule tout ça en faisant un transfert en interne d'une mémoire à une autre (comme un memcpy mais à travers le sdma). Pour etre plus explicite on va dire que j'ai un thread fpga (simulation) qui ecrit des données dans une zone mémoire kernel à travers mon module puis qui bouge une pin out qui est connecté à la pin out threashold. De l'autre coté j'ai un thread ReadData qui lui est en attente bloquante sur le read de mon module. Donc à chaque fois que je fais bouger la pin out je recois bien les irq dans mon module et le transfert ce fait bien. Pour faire des teste j'ai volontairement fais bouger cette irq pendant que les it était masqué et c'est la que j'ai vu le problème.

    Je sais pas si j'ai bien été claire moi voilà mon problème donc oui je suis vraiment obligé de nettoyer les it avant de les reconnecter.

    Merci d'avance

    • [^] # Re: suite irq sauvegarde

      Posté par  . Évalué à 1. Dernière modification le 11 avril 2016 à 21:05.

      c'est normale que les irq soit sauvegardées d'après le site

      Non, tu n'auras que une interruption.

      j'ai volontairement fais bouger cette irq pendant que les it était masqué

      masquée != désactivée. Généralement une interruption est masquée lorsqu'une interruption de plus grande priorité s'exécute, automatiquement au niveau du PIC, matériel, ou d'un "soft"-IC… Au même titre qu'une "lost interrupt", ce mécanisme permet d'en récupèrer une lorsqu'elle est démasquée. Il n'y a pas de "queue", cela va à l'encontre du principe d'interruption !

      J'ai du mal à saisir ton problème: quel est le problème à avoir une interruption et à se rendre compte qu'il n'y a plus de travail à faire, donc à ne rien vider ? C'est comme ça que la grosse majorité des pilotes font…

      • [^] # Re: suite irq sauvegarde

        Posté par  . Évalué à 1.

        Bonjour
        Je suis d'accord avec toi normalement il n'y de queue je comprend pas pourquoi j'en ai deux. Peut être ai je mal vu à revoir ce point peut etre que ça cache quelque chose.

        Sinon si cela me pose problème d'avoir une it sauvegardé. Je suis en flux tendu avec le fpga en faite il me transmet des images. Je transfert toujours la même quantité de donnée 20 lignes par 20 ligne je n'ai aucune solution pour savoir quel quantité il reste dans la fifo à vider (c'est toujours 20 ligne). Donc si j'ai
        des its sauvegardé je crois qu'il y a 20 lignes à vider alors que c'est pas vrai.

        Je sais pas si j'ai bien expliquer mais voilà mon problème…….

        • [^] # Re: suite irq sauvegarde

          Posté par  . Évalué à 2.

          Si tu es en flux tendu sur ta FIFO la manière la plus simple de la vider consiste à la lire en boucle. La bonne séquence à faire c'est :

          1) Acquitter les interruptions
          2) Lire ta FIFO jusqu'à ce qu'un bit de status t'indique que la FIFO est vide
          3) Quitter ton handler d'IT

          Comme ton FPGA continue de te streamer des infos pendant ce temps il peut faire bouger ta GPIO d'IT pendant n'importe laquelle de ces étapes après l'acquittement. et ce n'est pas grave ! :)

          Si des données arrivent entre 1 et 2 tu va les lire pendant l'étape 2. Une nouvelle interruption matérielle peut-être levée si la FIFO dépasse son seuil de déclenchement d'IT. Cela signifie qu'à la sortie de ton handler d'IT une nouvelle interruption est levée et que tu a vidé la FIFO à l'avance. ça te coûte quelques cycles d'exécution, pas très grave. C'est à mon avis en raison d'une situation de ce type que tu vois deux interruptions.

          Si des données arrivent entre 2 et 3 tu va quitter ton handler alors que ta FIFO n'est pas vide. Aucun soucis, ils seront lus la prochaine fois.

          Une des questions à se poser c'est en cas de fin de stream : ta FIFO peut contenir des informations utiles mais si elle en contient moins de la moitié le FPGA n'aura pas forcément levé une interruption.

          Ce schéma est assez classique aussi tu le retrouvera dans plusieurs drivers. Si tu veux bien cerner ce qui peut se passer je t'invite à faire des diagrammes de séquences pour ton FPGA et ton drivers, voir quelles combinaisons d'événements peuvent se produire et évaluer si dans tous les cas tu ne crée pas une situation d'interblocage.

          Cette dernière étape est un peu pénible mais d'expérience il vaut mieux se poser ces questions au moment ou tu écrit le driver. Sinon tu peux laisser passer des bugs invisibles qui transformeront ton système en une jolie petite brique et il sera en général assez pénible de comprendre d'où vient le problème.

          • [^] # Re: suite irq sauvegarde

            Posté par  . Évalué à 1.

            bonjour,
            Déjà merci à tous pour votre aide
            Comme je le disais je n'ai pas encore le fpga. Mais j'ai suivi vos conseil et je me suis adapté à mon environnement. J'ai eu plusieurs problème mais en gérant mieux mes spin lock ainsi que mes couple disable irq et enable irq (et oui faut pas oublier que si on fait deux disable_irq il faut bien faire deux enable irq ). En suivant le conseil de teddyredm3cl (je regarde toujours l'état de la pin etat fifo à la fin de l'étape 2).
            Tout semble bien fonctionner.
            Merci encore
            Et bonne journée.
            yodalesage

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.