mbind(2)

الاسم
mbind - تعيين سياسة الذاكرة لنطاق ذاكرة

المكتبة
مكتبة سياسات NUMA (الوصول غير الموحد للذاكرة) (libnuma، -lnuma)

موجز
#include <numaif.h>

long mbind(unsigned long size, unsigned long maxnode;
           void addr[size], unsigned long size, int mode,
           const unsigned long nodemask[(maxnode + ULONG_WIDTH - 1)
/ ULONG_WIDTH],
           unsigned long maxnode, unsigned int flags);

الوصف
تضبط mbind() سياسة ذاكرة NUMA، التي تتكون من وضع سياسة وصفر أو أكثر من العقد، لنطاق الذاكرة الذي يبدأ بـ addr ويستمر لـ size بايت. تحدد سياسة الذاكرة من أي عقدة يتم تخصيص الذاكرة.

إذا تضمن نطاق الذاكرة المحدد بواسطة وسيطتي addr و size منطقة ذاكرة "مجهولة"—أي منطقة ذاكرة تم إنشاؤها باستخدام استدعاء النظام mmap(2) مع MAP_ANONYMOUS—أو ملف معين للذاكرة، تم تعيينه باستخدام استدعاء النظام mmap(2) مع العلم MAP_PRIVATE، سيتم تخصيص الصفحات فقط وفقًا للسياسة المحددة عندما يكتب التطبيق (يخزن) إلى الصفحة. بالنسبة للمناطق المجهولة، سيستخدم الوصول الأولي للقراءة صفحة مشتركة في النواة تحتوي على أصفار. بالنسبة لملف تم تعيينه باستخدام MAP_PRIVATE، سيخصص الوصول الأولي للقراءة صفحات وفقًا لسياسة الذاكرة للخيط الذي يتسبب في تخصيص الصفحة. قد لا يكون هذا هو الخيط الذي استدعى mbind().

سيتم تجاهل السياسة المحددة لأي تعيينات MAP_SHARED في نطاق الذاكرة المحدد. بدلاً من ذلك، سيتم تخصيص الصفحات وفقًا لسياسة الذاكرة للخيط الذي تسبب في تخصيص الصفحة. مرة أخرى، قد لا يكون هذا هو الخيط الذي استدعى mbind().

إذا تضمن نطاق الذاكرة المحدد منطقة ذاكرة مشتركة تم إنشاؤها باستخدام استدعاء النظام shmget(2) وتم إرفاقها باستخدام استدعاء النظام shmat(2)، سيتم تخصيص الصفحات المخصصة للمنطقة المجهولة أو المشتركة وفقًا للسياسة المحددة، بغض النظر عن العملية التي تسببت في التخصيص للمقطع المشترك. ومع ذلك، إذا تم إنشاء منطقة الذاكرة المشتركة مع العلم SHM_HUGETLB، سيتم تخصيص الصفحات الضخمة وفقًا للسياسة المحددة فقط إذا كان تخصيص الصفحة ناتجًا عن العملية التي تستدعي mbind() لتلك المنطقة.

افتراضيًا، يكون لـ mbind() تأثير فقط على التخصيصات الجديدة؛ إذا تم لمس الصفحات داخل النطاق بالفعل قبل تعيين السياسة، فلن يكون للسياسة أي تأثير. يمكن تجاوز هذا السلوك المبدئي بواسطة العلمين MPOL_MF_MOVE و MPOL_MF_MOVE_ALL الموصوفين أدناه.

يجب أن تحدد وسيطة mode واحدة من MPOL_DEFAULT، MPOL_BIND، MPOL_INTERLEAVE، MPOL_WEIGHTED_INTERLEAVE، MPOL_PREFERRED، MPOL_PREFERRED_MANY، أو MPOL_LOCAL (الموصوفة بالتفصيل أدناه). تتطلب جميع أوضاع السياسة باستثناء MPOL_DEFAULT من المستدعي تحديد العقدة أو العقد التي ينطبق عليها الوضع، عبر وسيطة nodemask.

قد يتضمن المعامل mode أيضًا علم وضع اختياري. أعلام الوضع المدعومة هي:

MPOL_F_NUMA_BALANCING (منذ لينكس 5.15)
    عندما يكون mode هو MPOL_BIND، فَعّل موازنة NUMA في النواة للمهمة إذا كانت مدعومة من النواة. إذا كان العلم غير مدعوم من النواة، أو استُخدم مع mode غير MPOL_BIND، تُعاد القيمة -1 ويُضبط errno على EINVAL.

MPOL_F_STATIC_NODES (منذ لينكس-2.6.26)
    يحدد nodemask غير الفارغ معرفات العقد الفعلية. لا يعيد لينكس تعيين nodemask عندما ينتقل الخيط إلى سياق cpuset مختلف، ولا عندما تتغير مجموعة العقد المسموح بها بواسطة سياق cpuset الحالي للخيط.

MPOL_F_RELATIVE_NODES (منذ لينكس-2.6.26)
    يحدد nodemask غير الفارغ معرفات عقد نسبية لمجموعة معرفات العقد المسموح بها بواسطة cpuset الحالي للخيط.

يشير nodemask إلى قناع بت للعقد يحتوي على ما يصل إلى maxnode بت. يتم تقريب حجم قناع البت إلى المضاعف التالي لـ sizeof(unsigned long)، لكن النواة ستستخدم البتات فقط حتى maxnode. تحدد قيمة NULL لـ nodemask أو قيمة maxnode صفرية المجموعة الفارغة من العقد. إذا كانت قيمة maxnode صفرًا، يتم تجاهل وسيطة nodemask. حيثما يكون nodemask مطلوبًا، يجب أن يحتوي على عقدة واحدة على الأقل متصلة بالإنترنت، مسموح بها بواسطة سياق cpuset الحالي للخيط (ما لم يتم تحديد علم الوضع MPOL_F_STATIC_NODES)، وتحتوي على ذاكرة.

يجب أن يتضمن المعامل mode إحدى القيم التالية:

MPOL_DEFAULT
    يطلب هذا الوضع إزالة أي سياسة غير مبدئية، واستعادة السلوك المبدئي. عند تطبيقه على نطاق من الذاكرة عبر mbind()، يعني هذا استخدام سياسة ذاكرة الخيط، والتي قد تم تعيينها باستخدام set_mempolicy(2). إذا كان وضع سياسة ذاكرة الخيط هو أيضًا MPOL_DEFAULT، سيتم استخدام السياسة المبدئية على مستوى النظام. تخصص السياسة المبدئية على مستوى النظام الصفحات على عقدة وحدة المعالجة المركزية التي تؤدي إلى التخصيص. بالنسبة لـ MPOL_DEFAULT، يجب أن تحدد وسيطتا nodemask و maxnode المجموعة الفارغة من العقد.

MPOL_BIND
    يحدد هذا الوضع سياسة صارمة تقيد تخصيص الذاكرة بالعقد المحددة في nodemask. إذا حدد nodemask أكثر من عقدة واحدة، ستأتي تخصيصات الصفحات من العقدة التي تحتوي على ذاكرة حرة كافية والأقرب إلى العقدة التي يحدث فيها التخصيص. لن يتم تخصيص الصفحات من أي عقدة غير محددة في nodemask. (قبل لينكس 2.6.26، كانت تخصيصات الصفحات تأتي من العقدة ذات معرف العدد الأدنى أولاً، حتى لا تحتوي تلك العقدة على ذاكرة حرة. ثم تأتي التخصيصات من العقدة ذات معرف العدد الأعلى التالي المحدد في nodemask وهكذا، حتى لا تحتوي أي من العقد المحددة على ذاكرة حرة.)

MPOL_INTERLEAVE
    يحدد هذا الوضع أن تخصيصات الصفحات تكون متداخلة عبر مجموعة العقد المحددة في nodemask. يحسن هذا من عرض النطاق الترددي بدلاً من زمن الوصول عن طريق توزيع الصفحات ووصول الذاكرة إلى تلك الصفحات عبر عقد متعددة. لكي يكون فعالاً، يجب أن تكون منطقة الذاكرة كبيرة إلى حد ما، على الأقل 1 ميجابايت أو أكبر مع نمط وصول منتظم إلى حد ما. ستظل عمليات الوصول إلى صفحة واحدة من المنطقة محدودة بعرض النطاق الترددي للذاكرة لعقدة واحدة.

MPOL_WEIGHTED_INTERLEAVE (منذ لينكس 6.9)
    يُبادل هذا الوضع تخصيصات الصفحات عبر العقد المحددة في nodemask وفقًا للأوزان في /sys/kernel/mm/mempolicy/weighted_interleave. على سبيل المثال، إذا ضُبطت البتات 0 و2 و5 في nodemask، وكانت محتويات /sys/kernel/mm/mempolicy/weighted_interleave/node0، و /sys/.../node2، و /sys/.../node5 هي 4 و7 و9 على التوالي، فستُخصص الصفحات في هذه المنطقة على العقد 0 و2 و5 بنسبة 4:7:9.

MPOL_PREFERRED
    يحدد هذا الوضع العقدة المفضلة للتخصيص. ستحاول النواة تخصيص الصفحات من هذه العقدة أولاً والرجوع إلى العقد الأخرى إذا كانت العقدة المفضلة منخفضة في الذاكرة الحرة. إذا حدد nodemask أكثر من معرف عقدة واحد، سيتم تحديد العقدة الأولى في القناع كعقدة مفضلة. إذا حددت وسيطتا nodemask و maxnode المجموعة الفارغة، فسيتم تخصيص الذاكرة على عقدة وحدة المعالجة المركزية التي أدت إلى التخصيص.

MPOL_PREFERRED_MANY (منذ لينكس 5.15)
    يحدد مجموعة من العقد للتخصيص؛ انظر set_mempolicy(2).

MPOL_LOCAL (منذ لينكس 3.8)
    يُحدد هذا الوضع "التخصيص المحلي"؛ حيث تُخصص الذاكرة على عقدة وحدة المعالجة المركزية التي أدت إلى التخصيص ("العقدة المحلية"). يجب أن تُحدد الوسيطتان nodemask و maxnode مجموعة فارغة. إذا كانت "العقدة المحلية" تعاني من نقص في الذاكرة الحرة، فستحاول النواة تخصيص ذاكرة من عقد أخرى. ستُخصص النواة ذاكرة من "العقدة المحلية" كلما توفرت ذاكرة لهذه العقدة. إذا لم يكن استخدام "العقدة المحلية" مسموحًا به ضمن سياق مجموعة المعالجات الحالي للخيط، فستحاول النواة تخصيص ذاكرة من عقد أخرى. ستُخصص النواة ذاكرة من "العقدة المحلية" كلما أصبح ذلك مسموحًا به ضمن سياق مجموعة المعالجات الحالي للخيط. في المقابل، يعود MPOL_DEFAULT إلى سياسة الذاكرة الخاصة بالخيط (والتي يمكن ضبطها عبر set_mempolicy(2))؛ وقد تكون هذه السياسة مختلفة عن "التخصيص المحلي".

إذا مُرر MPOL_MF_STRICT في flags ولم يكن mode هو MPOL_DEFAULT، فإن الاستدعاء يفشل مع الخطأ EIO إذا كانت الصفحات الموجودة في نطاق الذاكرة لا تتبع السياسة.

إذا حُدد MPOL_MF_MOVE في flags، فستحاول النواة نقل جميع الصفحات الموجودة في نطاق الذاكرة بحيث تتبع السياسة. لن تُنقل الصفحات المشتركة مع عمليات أخرى. إذا حُدد MPOL_MF_STRICT أيضًا، فإن الاستدعاء يفشل مع الخطأ EIO إذا تعذر نقل بعض الصفحات. إذا حُددت سياسة MPOL_INTERLEAVE، فلن تُنقل الصفحات الموجودة بالفعل في العقد المحددة بحيث تكون متداخلة.

إذا مُرر MPOL_MF_MOVE_ALL في flags، فستحاول النواة نقل جميع الصفحات الموجودة في نطاق الذاكرة بغض النظر عما إذا كانت العمليات الأخرى تستخدم الصفحات. يجب أن يتمتع خيط المستدعي بامتياز (CAP_SYS_NICE) لاستخدام هذا العلم. إذا حُدد MPOL_MF_STRICT أيضًا، فإن الاستدعاء يفشل مع الخطأ EIO إذا تعذر نقل بعض الصفحات. إذا حُددت سياسة MPOL_INTERLEAVE، فلن تُنقل الصفحات الموجودة بالفعل في العقد المحددة بحيث تكون متداخلة.

قيمة الإرجاع
عند النجاح، يعيد mbind() القيمة 0؛ وعند حدوث خطأ، تعاد القيمة -1 ويُضبط errno ليشير إلى الخطأ.

الأخطاء

EFAULT
    جزء أو كل نطاق الذاكرة المحدد بواسطة nodemask و maxnode يشير إلى خارج مساحة العنوان القابلة للوصول. أو، كان هناك فجوة غير معيّنة في نطاق الذاكرة المحدد بواسطة addr و size.

EINVAL
    قيمة غير صالحة حُددت لـ flags أو mode؛ أو addr + size كان أقل من addr؛ أو addr ليس مضاعفًا لحجم صفحة النظام. أو، mode هو MPOL_DEFAULT و nodemask حدد مجموعة غير فارغة؛ أو mode هو MPOL_BIND أو MPOL_INTERLEAVE و nodemask فارغ. أو، maxnode يتجاوز حدًا تفرضه النواة. أو، nodemask يحدد واحدًا أو أكثر من معرفات العقدة التي أكبر من الحد الأقصى لمعرف العقدة المدعوم. أو، لا شيء من معرفات العقدة المحددة بواسطة nodemask متصل بالإنترنت ومسموح به بواسطة سياق cpuset الحالي للخيط، أو لا شيء من العقد المحددة يحتوي على ذاكرة. أو، الوسيط mode حدد كلاً من MPOL_F_STATIC_NODES و MPOL_F_RELATIVE_NODES.

EIO حُدد MPOL_MF_STRICT وكانت هناك صفحة موجودة بالفعل في عقدة لا تتبع السياسة؛ أو حُدد MPOL_MF_MOVE أو MPOL_MF_MOVE_ALL وتعذرت النواة عن نقل جميع الصفحات الموجودة في النطاق.

ENOMEM
    ذاكرة النواة المتوفرة غير كافية.

EPERM
    تضمن المعامل flags العلم MPOL_MF_MOVE_ALL والمستدعي لا يملك امتياز CAP_SYS_NICE.

المعايير
لينكس.

التاريخ
لينكس 2.6.7.

دعم سياسة الصفحات الضخمة أُضيف مع لينكس 2.6.16. لكي تكون سياسة التداخل فعالة على تعيينات الصفحات الضخمة، تحتاج الذاكرة المُسيّسَة إلى عشرات الميغابايت أو أكثر.

قبل لينكس 5.7. MPOL_MF_STRICT كان يُتجاهل على تعيينات الصفحات الضخمة.

MPOL_MF_MOVE و MPOL_MF_MOVE_ALL متاحان فقط على لينكس 2.6.16 وما بعده.

ملاحظات
للحصول على معلومات حول دعم المكتبات، انظر numa(7).

سياسة NUMA غير مدعومة على نطاق ملف معيّن في الذاكرة تم تعيينه بالعلامة MAP_SHARED.

الوضع MPOL_DEFAULT يمكن أن يكون له تأثيرات مختلفة لـ mbind() و set_mempolicy(2). عندما يُحدد MPOL_DEFAULT لـ set_mempolicy(2)، تعود سياسة ذاكرة الخيط إلى السياسة المبدئية للنظام أو التخصيص المحلي. عندما يُحدد MPOL_DEFAULT لنطاق من الذاكرة باستخدام mbind()، أي صفحات تُخصص لاحقًا لذلك النطاق ستستخدم سياسة ذاكرة الخيط، كما هو مضبوط بواسطة set_mempolicy(2). هذا يزيل فعليًا السياسة الصريحة من النطاق المحدد، "بالتراجع" إلى سياسة ربما غير مبدئية. لاختيار "تخصيص محلي" صريح لنطاق ذاكرة، حدد mode من MPOL_LOCAL أو MPOL_PREFERRED مع مجموعة فارغة من العقد. هذه الطريقة ستعمل أيضًا لـ set_mempolicy(2).

انظر أيضًا
get_mempolicy(2), getcpu(2), mmap(2), set_mempolicy(2), shmat(2), shmget(2), numa(3), cpuset(7), numa(7), numactl(8)

ترجمة
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 (https://www.gnu.org/licenses/gpl-3.0.html) أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.