2013-01-31 12 views
6

मैं आकार में लगभग 40 एमबी आकार का एक बड़ा डीएमए बफर आवंटित करना चाहता हूं। जब मैं dma_alloc_coherent() उपयोग करें, यह विफल रहता है और क्या मैं देख रहा हूँ है:एक बड़े डीएमए बफर आवंटित

------------[ cut here ]------------ 
WARNING: at mm/page_alloc.c:2106 __alloc_pages_nodemask+0x1dc/0x788() 
Modules linked in: 
[<8004799c>] (unwind_backtrace+0x0/0xf8) from [<80078ae4>] (warn_slowpath_common+0x4c/0x64) 
[<80078ae4>] (warn_slowpath_common+0x4c/0x64) from [<80078b18>] (warn_slowpath_null+0x1c/0x24) 
[<80078b18>] (warn_slowpath_null+0x1c/0x24) from [<800dfbd0>] (__alloc_pages_nodemask+0x1dc/0x788) 
[<800dfbd0>] (__alloc_pages_nodemask+0x1dc/0x788) from [<8004a880>] (__dma_alloc+0xa4/0x2fc) 
[<8004a880>] (__dma_alloc+0xa4/0x2fc) from [<8004b0b4>] (dma_alloc_coherent+0x54/0x60) 
[<8004b0b4>] (dma_alloc_coherent+0x54/0x60) from [<803ced70>] (mxc_ipu_ioctl+0x270/0x3ec) 
[<803ced70>] (mxc_ipu_ioctl+0x270/0x3ec) from [<80123b78>] (do_vfs_ioctl+0x80/0x54c) 
[<80123b78>] (do_vfs_ioctl+0x80/0x54c) from [<8012407c>] (sys_ioctl+0x38/0x5c) 
[<8012407c>] (sys_ioctl+0x38/0x5c) from [<80041f80>] (ret_fast_syscall+0x0/0x30) 
---[ end trace 4e0c10ffc7ffc0d8 ]--- 

मैं विभिन्न मूल्यों की कोशिश की है और dma_alloc_coherent() की तरह अधिक से अधिक 2^25 बाइट्स (32 एमबी) आवंटित नहीं कर सकता यह लग रहा है।

ऐसे बड़े डीएमए बफर को आवंटित किया जा सकता है?

+0

बड़े डीएमए बफ़र्स महंगे हैं। मेमोरी ब्लॉक को संगत भौतिक स्मृति होना चाहिए (जब तक कि कुछ एसपीएआरसी सिस्टम में आई/ओ के लिए एमएमयू न हो) और लॉक डाउन (पृष्ठ प्राथमिकताओं के लिए पृष्ठ को प्राथमिकता वाले कार्यों के लिए जगह बनाने के लिए बाहर नहीं किया जा सकता है)। विशिष्ट कामकाज एक से अधिक डीएमए बफर का उपयोग करना और डीएमए चेनिंग (उर्फ स्कैटर/इकट्ठा) का उपयोग करना है। क्या आपके पास वास्तव में एक I/O ऑपरेशन है जो एक ब्लॉक में 40 एमबी स्थानांतरित करता है, या यह वास्तव में संचालन का संचय है? – sawdust

+0

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

+0

@ मिल्ज़, क्या आपने इस मुद्दे को हल किया? कैसे ? – ransh

उत्तर

6

सिस्टम बूट होने के बाद dma_alloc_coherent() बड़े आवंटन के लिए आवश्यक रूप से विश्वसनीय नहीं है। यह केवल इसलिए है क्योंकि गैर-चलने योग्य पृष्ठ आपकी भौतिक मेमोरी को जल्दी से भरते हैं जिससे बड़ी संगत श्रेणियां दुर्लभ होती हैं। यह एक लंबे समय के लिए एक समस्या रही है।

सुविधाजनक हाल ही में पैच-सेट आपकी मदद कर सकता है, यह कर्नेल 3.5 में दिखाई देने वाला संगत स्मृति आवंटक है। यदि आप इसके साथ कर्नेल का उपयोग कर रहे हैं तो आपको अपने कर्नेल कमांड लाइन पर cma=64M पास करने में सक्षम होना चाहिए और अधिक मेमोरी आरक्षित होगी (केवल चलने योग्य पृष्ठ वहां रखे जाएंगे)। जब आप बाद में अपने 40 एम आवंटन के लिए पूछते हैं तो इसे विश्वसनीय रूप से सफल होना चाहिए। साधारण!

अधिक जानकारी के लिए बाहर की जाँच इस LWN लेख:

https://lwn.net/Articles/486301/

+0

बूट समय पर स्मृति आवंटित करना मेरे लिए काफी अच्छा है, इसलिए मैंने memblock_alloc_base() और memblock_remove() का उपयोग किया। मेरी समझ के लिए, इन कार्यों को कर्नेल को स्मृति आवंटित और आवंटित करना चाहिए और यह भौतिक पते में सम्मिलित है, इस प्रकार इसे डीएमए के लिए उपयोग करना अच्छा होता है। – miluz

+0

मुझे लगता है कि काम करना चाहिए, लेकिन यह पीटा ट्रैक से थोड़ा सा है। यदि आप एक कर्नेल मॉड्यूल चाहते हैं जिसे आप लोड और अनलोड कर सकते हैं तो आपको भी परेशानी होगी। – jleahy

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