2011-08-20 13 views
19

मेरा प्रश्न यह है: जब मैं अपने डिवाइस ड्राइवर में [pci_]dma_sync_single_for_{cpu,device} का सही ढंग से उपयोग कर रहा हूं तो कैश स्नूपिंग को अक्षम करना सुरक्षित कैसे हो सकता है?डीएमए कैश समेकन प्रबंधन

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

बाधा दिनचर्या मैं pci_dma_sync_single_for_cpu() और ..._for_device() फोन में के रूप में उपयुक्त है, जब डीएमए बफ़र्स स्विच कर देंगे, लेकिन 32-बिट Linux 2.6.18 (RHEL 5) पर यह पता चला है कि इन आदेशों मैक्रो जो कुछ भी करने के लिए विस्तार कर रहे हैं ... जो बताता है कि इस उपकरण पर कैश स्नूपिंग अक्षम होने पर मेरा डिवाइस कचरा क्यों देता है!

मैंने कर्नेल स्रोतों के इतिहास के माध्यम से ट्रेल किया है, और ऐसा लगता है कि 2.6.25 तक केवल 64-बिट x86 में डीएमए सिंक्रनाइज़ेशन के लिए हुक था। 2.6.26 से dma_map_ops के क्षेत्र sync_single_for_{cpu,device} के माध्यम से डीएमए सिंक्रनाइज़ेशन (वर्तमान में include/asm-generic/dma-mapping-common.h में) के लिए एक सामान्य एकीकृत इंडिकेशन तंत्र प्रतीत होता है, लेकिन अब तक मैं इन परिचालनों की किसी भी परिभाषा को खोजने में विफल रहा हूं।

+0

वहाँ डीएमए और कैश जुटना आप lwn.net – Spudd86

+1

पर चारों ओर देखने के लिए चाहते हो सकता आप प्रदर्शन आप कैश स्नूपिंग को अक्षम करके प्राप्त हासिल मापा है के बारे में कुछ LWN लेख हो गया है , न केवल हस्तांतरण पर बल्कि कुल मिलाकर आवेदन पर? डीएमए समेकन इतना सुविधाजनक है, और हार्डवेयर के साथ बातचीत करने के बारे में सोचने को इतना आसान बनाता है कि मैं इसे बंद करने से पहले ध्यान से मापता हूं। –

उत्तर

15

मैं वास्तव में, हैरान कर रहा हूँ इसलिए यहाँ कोई भी इस का उत्तर दिया है हम एक गैर लिनक्स विशिष्ट जवाब पर जाने (मैं लिनक्स कर्नेल ही अधिक विशिष्ट की अपर्याप्त ज्ञान है) ...

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

तो आप कैसे सुनिश्चित करते हैं कि डीएमएड क्षेत्र से पढ़ना हमेशा मुख्य मेमोरी पर जाएंगे?

चरण 1::

दिन इससे पहले कि हम डीएमए कैश स्नूपिंग, हम क्या करने के लिए इस्तेमाल टूट चरणों की एक श्रृंखला के माध्यम से खिला इस प्रकार से पाइप लाइन डीएमए स्मृति के लिए गया था की तरह आकर्षक सुविधाओं के लिए किया था में वापस जोड़ें " गंदे "डीएमए मेमोरी क्षेत्र को" गंदा और साफ करने की जरूरत है "डीएमए मेमोरी सूची।

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

चरण 3: अगला डीएमए इंटरप्ट (जो निश्चित रूप से आप सुनिश्चित हैं कि पिछले कैश अमान्य होने से पहले नहीं होगा), "साफ" सूची से एक नया क्षेत्र लें और डिवाइस को बताएं कि उसका अगला डीएमए जाना चाहिए उस में। किसी भी गंदे ब्लॉक रीसायकल।

चरण 4: दोहराना।

जितना अधिक काम है, इसके कई प्रमुख फायदे हैं। सबसे पहले, आप एक एकल सीपीयू (आमतौर पर प्राथमिक CPU0) या एक एकल एसएमपी नोड को डीएमए हैंडलिंग पिन कर सकते हैं, जिसका मतलब है कि केवल एक ही सीपीयू/नोड को कैश अमान्यता के बारे में चिंता करने की आवश्यकता है।दूसरा, आप मेमोरी सबसिस्टम को समय के साथ परिचालनों को दूर करके और कैश कोहिरेंसी बस पर लोड फैलाने के लिए मेमोरी लेटेंसी को छिपाने का अधिक अवसर देते हैं। प्रदर्शन के लिए कुंजी आम तौर पर संभावित डीएमए नियंत्रक के करीब जितनी संभव हो सके सीपीयू पर किसी भी डीएमए को और उस सीपीयू के करीब जितनी संभव हो सके स्मृति में करने की कोशिश करने के लिए होती है।

आप हमेशा हाथ नव स्मृति में उपयोगकर्ता अंतरिक्ष और/या अन्य सीपीयू को DMAed हैं, तो बस हाल में हासिल कर ली स्मृति में async कैश अमान्य पाइप लाइन के सामने इंजेक्षन। कुछ ओएस (लिनक्स के बारे में निश्चित नहीं) में शून्य की स्मृति को पूर्ववर्ती करने के लिए एक अनुकूलित दिनचर्या है, इसलिए ओएस मूल रूप से पृष्ठभूमि में स्मृति को शून्य करता है और एक त्वरित संतुष्ट कैश रखता है - यह आपको कैश की गई राशि के नीचे नए मेमोरी अनुरोधों को रखने के लिए भुगतान करेगा क्योंकि स्मृति को शून्य करना बेहद धीमी है। मुझे पिछले दस वर्षों में उत्पादित किसी भी प्लेटफॉर्म से अवगत नहीं है जो हार्डवेयर ऑफ़लोडेड मेमोरी शून्यिंग का उपयोग करता है, इसलिए आपको यह मानना ​​चाहिए कि सभी ताजा मेमोरी में वैध कैश लाइनें हो सकती हैं जिन्हें अमान्य करने की आवश्यकता है।

मैं इस प्रश्न का केवल आधा प्रश्न पूछता हूं, लेकिन यह कुछ भी नहीं है। सौभाग्य!

नियाल

4

शायद थोड़ा समय से अपेक्षित है, लेकिन:

आप कैश स्नूपिंग अक्षम करते हैं, हार्डवेयर अब कैश जुटना की देखभाल करेंगे। इसलिए, कर्नेल को यह करने की ज़रूरत है। पिछले कुछ दिनों में, मैंने कुछ tiem [pci_] dma_sync_single_for_ {cpu, device} के X86 प्रकारों की समीक्षा करने में व्यतीत किया है। मुझे कोई संकेत नहीं मिला है कि वे समेकन बनाए रखने के लिए कोई प्रयास करते हैं। यह इस तथ्य के अनुरूप है कि पीसीआई (ई) spec में डिफ़ॉल्ट रूप से कैश स्नूपिंग चालू है।

इसलिए, यदि आप कैश स्नूपिंग बंद कर रहे हैं, तो आपको अपने ड्राइवर में स्वयं को सहवास बनाए रखना होगा। संभवतः clflush_cache_range() (X86) या इसी तरह से कॉल करके?

Refs:

संबंधित मुद्दे