लिनक्स कर्नेल साझा IRQ कैसे करता है?


14

अब तक जो मैंने पढ़ा है, उसके अनुसार, "जब कर्नेल को एक बाधा मिलती है, तो सभी पंजीकृत हैंडलर को आमंत्रित किया जाता है।"

मैं समझता हूं कि प्रत्येक IRQ के लिए पंजीकृत हैंडलर के माध्यम से देखा जा सकता है /proc/interrupts, और मैं यह भी समझता हूं कि पंजीकृत हैंडलर उन ड्राइवरों से आते हैं जिन्होंने request_irqकॉलबैक फॉर्म में मोटे तौर पर पास होने का आह्वान किया है:

irqreturn_t (*handler)(int, void *)

मुझे जो पता है, उसके आधार पर, विशेष आईआरक्यू से जुड़े इन रुकावट हैंडलर कॉलबैक में से प्रत्येक को आमंत्रित किया जाना चाहिए, और यह निर्धारित करने के लिए हैंडलर पर निर्भर है कि क्या वास्तव में इसके द्वारा नियंत्रित किया जाना चाहिए। यदि हैंडलर को विशेष व्यवधान को संभालना नहीं चाहिए, तो उसे कर्नेल मैक्रो वापस करना होगा IRQ_NONE

मुझे यह समझने में परेशानी हो रही है कि प्रत्येक चालक से यह निर्धारित करने की अपेक्षा की जाती है कि उसे व्यवधान को संभालना चाहिए या नहीं। मुझे लगता है कि वे आंतरिक रूप से ट्रैक रख सकते हैं यदि वे एक बाधा की उम्मीद कर रहे हैं। यदि हां, तो मुझे नहीं पता कि वे उस स्थिति से कैसे निपट सकते हैं जिसमें एक ही IRQ के पीछे कई ड्राइवर एक बाधा की उम्मीद कर रहे हैं।

कारण मैं इन विवरणों को समझने की कोशिश कर रहा हूं, क्योंकि मैं kexecसिस्टम ऑपरेशन के बीच में कर्नेल को फिर से निष्पादित करने के लिए तंत्र के साथ खिलवाड़ कर रहा हूं, जबकि PCIe पुल पर और साथ ही डाउनस्ट्रीम PCI पर विभिन्न रजिस्टरों के साथ खेलना डिवाइस। और ऐसा करने में, एक रिबूट के बाद मैं या तो कर्नेल पैनिक्स प्राप्त कर रहा हूं, या अन्य ड्राइवर शिकायत कर रहे हैं कि वे बाधित हो रहे हैं भले ही कोई ऑपरेशन नहीं हो रहा था।

हैंडलर ने कैसे तय किया कि बाधा को इसके द्वारा नियंत्रित किया जाना चाहिए।

संपादित करें: यदि यह प्रासंगिक है, तो प्रश्न में सीपीयू वास्तुकला है x86


1
stackoverflow.com/questions/14371513/for-a-saded-interrupt-line-how-do-i-find-which-interrupt-handler-to-usec
सिरो संतिली 新疆 est est est est 事件 事件

जवाबों:


14

इस में शामिल है 10 अध्याय के लिनक्स डिवाइस ड्राइवर , 3 संस्करण, कॉर्बेट एट अल द्वारा। यह मुफ्त ऑनलाइन के लिए उपलब्ध है , या आप कुछ शेकेल ओ'रेली के मृत पेड़ या ईबुक रूपों के लिए टॉस कर सकते हैं। आपके प्रश्न से संबंधित भाग प्रथम लिंक में पेज 278 पर शुरू होता है।

इसके लायक क्या है, यहाँ उन तीन पन्नों को समाहित करने का मेरा प्रयास है, साथ ही अन्य बिट्स को मैंने गुगला दिया है:

  • जब आप एक साझा IRQ हैंडलर को पंजीकृत करते हैं, तो कर्नेल जाँचता है कि:

    ए। कोई अन्य हैंडलर उस रुकावट के लिए मौजूद नहीं है, या

    ख। पहले से पंजीकृत उन सभी ने भी व्यवधान साझा करने का अनुरोध किया था

    यदि कोई मामला लागू होता है, तो यह जांचता है कि आपका dev_idपैरामीटर अद्वितीय है, ताकि कर्नेल कई हैंडलर को अलग कर सके, जैसे हैंडलर हटाने के दौरान।

  • जब एक PCI, हार्डवेयर डिवाइस IRQ लाइन को उठाता है, तो कर्नेल का निम्न-स्तर का व्यवधान हैंडलर कहलाता है, और यह बदले में पंजीकृत सभी बाधित हैंडलर को कॉल करता है, प्रत्येक के dev_idमाध्यम से आप हैंडलर को पंजीकृत करने के लिए उपयोग किया जाता है request_irq()

    dev_idमूल्य मशीन अद्वितीय की जरूरत है। ऐसा करने का सामान्य तरीका structउस डिवाइस को प्रबंधित करने के लिए आपके ड्राइवर द्वारा उपयोग किए जाने वाले प्रति-डिवाइस के लिए एक पॉइंटर पास करना है । के बाद से इस सूचक अपने ड्राइवर की स्मृति अंतरिक्ष के भीतर होना चाहिए यह ड्राइवर के लिए उपयोगी होने के लिए, यह वास्तव में ipso कि driver.² के लिए अद्वितीय

    यदि दिए गए रुकावट के लिए कई ड्राइवर पंजीकृत हैं, तो उन सभी को कॉल किया जाएगा जब कोई भी डिवाइस उस साझा रुकावट लाइन को उठाता है। यदि यह आपके ड्राइवर का उपकरण नहीं था, तो यह आपके ड्राइवर के अवरोधक हैंडलर को एक dev_idमान दिया जाएगा जो इसका नहीं है। ऐसा होने पर आपके ड्राइवर की बाधा हैंडलर को तुरंत वापस लौटना चाहिए।

    एक और मामला यह है कि आपका ड्राइवर कई उपकरणों का प्रबंधन कर रहा है। चालक के बाधा हैंडलर को dev_idचालक को ज्ञात मूल्यों में से एक मिलेगा । आपका कोड प्रत्येक डिवाइस को यह पता लगाने के लिए माना जाता है कि किसने बाधा को उठाया।

    उदाहरण कॉर्बेट एट अल। एक पीसी समानांतर पोर्ट की है। जब यह रुकावट लाइन का दावा करता है, तो यह अपने पहले डिवाइस रजिस्टर में शीर्ष बिट भी सेट करता है। (अर्थात, inb(0x378) & 0x80 == trueमानक I / O पोर्ट नंबरिंग मानकर।) जब आपका हैंडलर यह पता लगाता है, तो उसे अपना काम करना है, तो IRQ को I / O पोर्ट से पढ़े गए मान को शीर्ष पर पोर्ट के साथ लिखकर साफ़ करें। थोड़ा साफ हो गया।

    मुझे कोई कारण नहीं दिखता है कि विशेष तंत्र विशेष है। एक अलग हार्डवेयर डिवाइस एक अलग तंत्र चुन सकता है। एकमात्र महत्वपूर्ण बात यह है कि एक डिवाइस के लिए साझा इंटरप्ट को अनुमति देने के लिए, चालक के पास डिवाइस की रुकावट स्थिति को पढ़ने के लिए कुछ रास्ता होना चाहिए, और बीच में रुकावट को दूर करने के लिए कुछ तरीका है । आपको अपने डिवाइस की डेटशीट या प्रोग्रामिंग मैनुअल को पढ़ना होगा ताकि यह पता लगाया जा सके कि आपका विशेष उपकरण किस तंत्र का उपयोग करता है।

  • जब आपका रुकावट हैंडलर कर्नेल को बाधित बताता है, तो वह कर्नेल को उसी अवरोध के लिए पंजीकृत किसी अन्य हैंडलर को कॉल करने के लिए जारी रखने से नहीं रोकता है। यदि आप स्तर-ट्रिगर अंतराल का उपयोग करते समय एक बाधा रेखा साझा करना चाहते हैं तो यह अपरिहार्य है।

    दो उपकरणों की कल्पना करें कि एक ही समय में एक ही रुकावट रेखा मुखर करें। (या कम से कम, इतने समय के करीब कि कर्नेल के पास लाइन को खाली करने के लिए एक अवरोध हैंडलर को कॉल करने का समय नहीं है और इस तरह दूसरा जोर अलग है।) कर्नेल को प्रत्येक लाइन देने के लिए, उस बाधा रेखा के लिए सभी हैंडलर को कॉल करना होगा। यह देखने के लिए कि क्या इस पर ध्यान देने की जरूरत है, अपने संबद्ध हार्डवेयर को क्वेरी करने का मौका। यह दो अलग-अलग ड्राइवरों के लिए एक दिए गए अवरोध के लिए हैंडलर सूची के माध्यम से एक ही पास के भीतर एक बाधा को सफलतापूर्वक संभालने के लिए काफी संभव है।

    इस वजह से, यह जरूरी है कि आपका ड्राइवर डिवाइस को बताए कि वह व्यवधान को रोकने के लिए प्रबंध कर रहा है। यह मेरे लिए स्पष्ट नहीं है कि अन्यथा क्या होता है। निरंतर-बाधित रुकावट लाइन या तो कर्नेल में परिणामी रूप से साझा व्यवधान हैंडलर को बुलाएगी, या यह कर्नेल के नए अवरोधों को देखने की क्षमता को मुखौटा करेगा ताकि हैंडलर को कभी नहीं बुलाया जाए। किसी भी तरह से, आपदा।


फुटनोट:

  1. मैंने PCI को ऊपर निर्दिष्ट किया है क्योंकि उपरोक्त सभी मान लेवल-ट्रिगर इंटरप्ट करता है, जैसा कि मूल PCI कल्पना में उपयोग किया जाता है। आईएसए ने एज-ट्रिग्ड इंटरप्ट का उपयोग किया , जिसने हार्डवेयर को साझा करना मुश्किल बना दिया, और तब भी संभव है, जब केवल हार्डवेयर द्वारा समर्थित हो। PCIe संदेश-संकेतित इंटरप्ट का उपयोग करता है ; बाधा संदेश में एक अनोखा मूल्य होता है जो कि कर्नेल का उपयोग कर सकता है ताकि राउंड-रॉबिन अनुमान लगाने के खेल से बचा जा सके जो कि पीसीआई अवरोध साझाकरण के साथ आवश्यक हो। PCIe रुकावट साझा करने के लिए बहुत आवश्यकता को समाप्त कर सकता है। (मुझे नहीं पता कि क्या यह वास्तव में करता है, बस यह करने की क्षमता है।)

  2. लिनक्स कर्नेल ड्राइवर सभी एक ही मेमोरी स्पेस को साझा करते हैं, लेकिन एक असंबंधित ड्राइवर को दूसरे की मेमोरी स्पेस में घूमने वाला नहीं माना जाता है। जब तक आप उस पॉइंटर को चारों ओर से नहीं गुजारते, तब तक आप यह सुनिश्चित कर सकते हैं कि कोई दूसरा ड्राइवर गलती से उसी मूल्य के साथ आने वाला नहीं है।


1
जैसा कि आपने उल्लेख किया है, बाधा हैंडलर को पारित किया जा सकता है dev_idकि यह अपना नहीं है। मेरे लिए ऐसा लगता है कि एक गैर-शून्य मौका है कि एक ड्राइवर जो dev_idसंरचना का मालिक नहीं है, वह अभी भी गलती कर सकता है क्योंकि यह उसके आधार पर है कि यह सामग्री की व्याख्या कैसे करता है। यदि यह मामला नहीं है तो क्या तंत्र इसे रोक सकता है?
21

आप इसे dev_idअपने ड्राइवर की मेमोरी स्पेस में किसी चीज़ को पॉइंटर बनाकर रोकते हैं। एक अन्य चालक सकता है एक बनाने के dev_idमूल्य कि हुआ स्मृति अपने ड्राइवर का मालिक करने के लिए एक सूचक के साथ भ्रम हो सकता है, लेकिन ऐसा करने के लिए क्योंकि हर कोई नियमों से खेल रहा है नहीं जा रहा है। यह कर्नेल-स्पेस है, याद रखें: उपयोगकर्ता-स्पेस कोड के विपरीत, आत्म-अनुशासन को निश्चित रूप से माना जाता है, जो शायद यह मान सकता है कि कुछ भी निषिद्ध नहीं है।
वॉरेन यंग

LDD3 के अध्याय दस के अनुसार: "जब भी दो या दो से अधिक ड्राइवर एक बाधा रेखा साझा कर रहे होते हैं और हार्डवेयर उस रेखा पर प्रोसेसर को बाधित करता है, तो कर्नेल उस बाधा के लिए पंजीकृत प्रत्येक हैंडलर को आमंत्रित करता है, प्रत्येक अपने स्वयं के dev_id से गुजरता है" यह पिछली समझ की तरह लगता है इस बारे में गलत था कि एक बाधा हैंडलर में पारित किया जा सकता है dev_idकि यह खुद नहीं है।
bsirang

यह मेरी ओर से गलत पढ़ा गया था। जब मैंने लिखा कि, मैं दो अवधारणाओं का सामना कर रहा था। मैंने अपना उत्तर संपादित कर दिया है। शर्त यह है कि आपके अवरोधक हैंडलर को जल्दी से लौटने की आवश्यकता है, यह एक डिवाइस द्वारा एक व्यवधान के कारण इसे प्रबंधन नहीं होने के कारण कहा जाता है। यह dev_idनिर्धारित करने में आपकी मदद नहीं करता है कि क्या हुआ है। आपको हार्डवेयर से पूछना होगा, "आपने रंग दिया?"
वॉरेन यंग

हां, अब मुझे यह पता लगाने की आवश्यकता है कि मैं किस तरह से छेड़छाड़ कर रहा हूं, वास्तव में अन्य ड्राइवरों को कर्नेल को फिर से शुरू करने के बाद अपने उपकरणों "विश्वास" करने का कारण बनता है kexec
bsirang

4

जब कोई ड्राइवर साझा IRQ का अनुरोध करता है, तो यह ड्राइवर के मेमोरी स्पेस के भीतर डिवाइस विशिष्ट संरचना के संदर्भ में कर्नेल को एक पॉइंटर पास करता है।

LDD3 के अनुसार:

जब भी दो या अधिक ड्राइवर एक बाधा रेखा साझा कर रहे होते हैं और हार्डवेयर उस रेखा पर प्रोसेसर को बाधित करता है, तो कर्नेल उस बाधा के लिए पंजीकृत प्रत्येक हैंडलर को अपने स्वयं के dev_id से गुजरता है।

कई ड्राइवरों के आईआरक्यू हैंडलर्स की जांच करने पर, ऐसा प्रतीत होता है कि वे हार्डवेयर की जांच स्वयं करते हैं ताकि यह निर्धारित किया जा सके कि यह रुकावट या वापसी को संभालना चाहिए या नहीं IRQ_NONE

उदाहरण

UHCI-HCD ड्राइवर
  status = inw(uhci->io_addr + USBSTS);
  if (!(status & ~USBSTS_HCH))  /* shared interrupt, not mine */
    return IRQ_NONE;

उपरोक्त कोड में, ड्राइवर यह USBSTSनिर्धारित करने के लिए रजिस्टर पढ़ रहा है कि क्या सेवा में कोई बाधा है।

SDHCI ड्राइवर
  intmask = sdhci_readl(host, SDHCI_INT_STATUS);

  if (!intmask || intmask == 0xffffffff) {
    result = IRQ_NONE;
    goto out;
  }

पिछले उदाहरण की तरह, ड्राइवर एक स्थिति रजिस्टर की जांच कर रहा है, SDHCI_INT_STATUSयह निर्धारित करने के लिए कि उसे एक बाधा की सेवा करने की आवश्यकता है या नहीं।

Ath5k चालक
  struct ath5k_softc *sc = dev_id;
  struct ath5k_hw *ah = sc->ah;
  enum ath5k_int status;
  unsigned int counter = 1000;

  if (unlikely(test_bit(ATH_STAT_INVALID, sc->status) ||
        !ath5k_hw_is_intr_pending(ah)))
    return IRQ_NONE;

बस एक और उदाहरण।


0

कृपया इस लिंक को देखें :

इसकी एक सामान्य प्रैक्टिस है कि IRQ हैंडलर में नीचे-हिस्सों या किसी अन्य तर्क को ट्रिगर करने के लिए, एक मेमोरी टैप किए गए रजिस्टर से IRQ स्टेटस चेक करने के बाद ही। इसलिए समस्या एक अच्छे प्रोग्रामर द्वारा डिफ़ॉल्ट रूप से हल की गई है।


आपके लिंक की सामग्री उपलब्ध नहीं है
user3405291
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.