Presentation is loading. Please wait.

Presentation is loading. Please wait.

תרגול 10 – זיכרון וירטואלי ב-Linux

Similar presentations


Presentation on theme: "תרגול 10 – זיכרון וירטואלי ב-Linux"— Presentation transcript:

1 תרגול 10 – זיכרון וירטואלי ב-Linux
מערכות הפעלה תרגול 10 – זיכרון וירטואלי ב-Linux

2 תוכן התרגול (1) מבוא לזיכרון וירטואלי ב-Linux זיכרון וירטואלי ב-IA32
סגמנטציה דפדוף (Paging) TLB ניהול זיכרון וירטואלי ב-Linux שימוש מנוון בסגמנטציה מודל אחיד לטבלת דפים מיקום מרחב הזיכרון של הגרעין טיפול ב-TLB (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

3 תוכן התרגול (2) מרכיבי מערכת הזיכרון ב-Linux תמונת על
ניהול זיכרון לתהליך מאגרי הדפדוף טבלת המסגרות מטמון הדפים טיפול ב-Page Fault Demand Paging Copy On Write מנגנון פינוי הדפים (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

4 מבוא לזיכרון וירטואלי ב-Linux (1)
במחשב יש בד"כ זיכרון פיזי ראשי (אלקטרוני) קטן בהרבה מהזיכרון הפיזי המשני (דיסק) הבדל של 3 סדרי גודל: MB לעומת GB מטרת מנגנון הזיכרון הוירטואלי היא לאפשר לכל תהליך מרחב זיכרון פרטי שאינו מוגבל בגודל הזיכרון הראשי של המחשב ב-Linux – מרחב זיכרון וירטואלי לכל תהליך בגודל 232 = 4GB כדי להשיג מטרה זו, מנצל מנגנון הזיכרון הוירטואלי את הזיכרון המשני כהרחבה של הזיכרון הראשי הרעיון: לפנות לדיסק את אותם חלקים מהזיכרון הוירטואלי של כל תהליך שאינם בשימוש כרגע יעילותו של מנגנון הזיכרון הוירטואלי נובעת מעקרון הלוקליות: על-פני פרקי זמן קצרים, תהליך ניגש בד"כ רק לחלק קטן מאוד ממרחב הזיכרון העומד לרשותו (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

5 מבוא לזיכרון וירטואלי ב-Linux (2)
ע"י אחסון רק החלק ה"פעיל" של מרחב הזיכרון של תהליך: ניתן להריץ יישום שדרישות הזיכרון שלו גדולות בהרבה מהזיכרון הפיזי ניתן להריץ מספר רב של יישומים כנ"ל באותו מחשב עם זיכרון פיזי קטן יחסית החסרון של השיטה: הגדלה משמעותית של זמן הביצוע של תהליך, כתוצאה מהצורך לבצע תחלופה של קטעי זיכרון בין הזיכרון הראשי והדיסק מנגנון זיכרון וירטואלי דורש תמיכה של החומרה תרגום בין כתובת לוגית לכתובת פיזית זיהוי גישה לזיכרון וירטואלי שאינו מצוי בזיכרון הראשי (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

6 ניהול זיכרון ב-IA32 (1) כזכור מתרגולים קודמים, על-מנת לגשת לזיכרון יש לספק כתובת לוגית בפורמט segment:offset segment: מספר בן 16 ביט המזהה "איזור זיכרון" של התהליך offset: מספר בן 32 ביט המזהה תא זיכרון מסוים באיזור הזיכרון המבוקש כתובת לוגית זו עוברת תרגום בחומרה לכתובת פיזית: כתובת תא בזיכרון הראשי (האלקטרוני) של המחשב כתובת לוגית segment:offset כתובת ליניארית (32 ביט) כתובת פיזית (32/36 ביט) מנגנון סגמנטציה מנגנון דפים (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

7 ניהול זיכרון ב-IA32 (2) מודל הזיכרון הוא כדלקמן:
מוגדר מרחב זיכרון ליניארי - "שטוח" - במיעון 32 ביט, כלומר בגודל עד 4GB הכתובת הליניארית היא כתובת תא במרחב זיכרון זה מנגנון הדפים ממפה את המרחב הליניארי לאוסף דפים נפרד לכל תהליך – כך מושגת ההפרדה בין איזורי הזיכרון של התהליכים מעל מרחב זיכרון זה מוגדרת חלוקה לסגמנטים, שהם "איזורי הזיכרון" שלמדנו עד כה תיתכן חפיפה חלקית או מלאה בין סגמנטים לא נשתמש יותר במושג "איזור זיכרון" אלא במושג סגמנט, כדי לא לבלבל עם מושג איזור הזיכרון של Linux שנפגוש בהמשך (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

8 סגמנטציה ב-IA32 (1) ניהול זיכרון ב-IA32 לכל סגמנט יש רשומה הקרויה מתאר הסגמנט (segment descriptor) ומכילה: כתובת הבסיס (הליניארית) של הסגמנט גודל הסגמנט (בכפולות של 4K או בבתים) סוג הסגמנט, לקביעת הרשאות הגישה לדוגמה: בסגמנט של קוד מותר לקרוא ולהריץ נתונים בלבד. בסגמנט נתונים מותר לקרוא ולכתוב נתונים בלבד סוגים קיימים: קוד, נתונים, TSS (מתרגול החלפת הקשר..) ועוד DPL – ערך CPL מקסימלי לגישה לסגמנט הגבלת הגישה לקוד תהליכי משתמש לסגמנטים של הגרעין (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

9 סגמנטציה ב-IA32 (2) ניהול זיכרון ב-IA32 כל מתארי הסגמנטים מאוחסנים בטבלה הקרויה GDT (Global Descriptor Table) המוצבעת מרגיסטר מיוחד הקרוי gdtr ערכו של רגיסטר סגמנט (cs, ds, …) נקרא segment selector ומכיל שדה של אינדקס מתאר הסגמנט ב-GDT התרגום מכתובת לוגית לליניארית הינו, לפיכך, פשוט ביותר: המעבד שולף את כתובת הבסיס ממתאר הסגמנט המוצבע מרגיסטר הסגמנט ומוסיף לה את ערך ה-offset פעולה זו כרוכה בבדיקת הרשאות לפי סוג הפעולה וה-CPL, ובבדיקת אי-גלישה מהסגמנט (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

10 סגמנטציה ב-IA32 (3) : ניהול זיכרון ב-IA32 GDT זיכרון ליניארי 0x1000
DPL סוג גודל כתובת בסיס כניסה 3 קוד 0x3 0x1000 0x5 0x1000 0x1152 + 0x3fff segment selector offset : index=0x5 0x152 *נניח שגודל הסגמנט כתוב בכפולות של 4K (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

11 ניהול דפים ב-IA32 (1) מנגנון ניהול הדפים ב-IA32 הוא זה המאפשר:
יצירת מרחבי זיכרון שונים ובלתי תלויים זה בזה אי הגבלת הזיכרון הוירטואלי בגודל הזיכרון הראשי טעינת קטעים מזכרון התהליך לפי הצורך (page fault) מרחב הזיכרון הוירטואלי של תהליך מחולק לדפים – קטעי זיכרון עוקבים בעלי גודל קבוע בד"כ 4KB כל דף יכול להמצא בזיכרון או במאגר דפדוף (swap) בדיסק (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

12 ניהול דפים ב-IA32 (2) ניהול זיכרון ב-IA32 הזיכרון הראשי (הפיזי) של המחשב מחולק למסגרות בגודל דף כאשר דף נמצא בזיכרון הראשי, הוא משובץ למסגרת כלשהי עבור כל תהליך מוחזק, לפי הצורך, רק חלק מהדפים שלו בזיכרון הראשי בכל זמן נתון רק הדפים שנמצאים בשימוש התהליך "לאחרונה" כך מושג אפקט הוירטואליות: הרצת מספר תהליכים עם דרישת זיכרון כוללת או בנפרד גדולה מהזיכרון הראשי טבלת הדפים (page table) של כל תהליך מנהלת את הדפים של התהליך האם הדף נמצא בזיכרון ובאיזו מסגרת (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

13 ניהול דפים ב-IA32 (3) בתרגום כתובת ליניארית לכתובת פיזית:
המעבד מחשב תחילה באיזה דף נמצאת הכתובת הליניארית ואת מרחקה מתחילת הדף (offset) המעבד בודק בטבלת הדפים באיזה מסגרת נמצא הדף הכתובת הפיזית היא כתובת תחילת המסגרת + offset אם הדף המכיל את הכתובת אינו נמצא בזיכרון, נוצרת חריגה מסוג page fault הגורמת לגרעין מערכת ההפעלה להביא את הדף לזיכרון בסיום הטיפול בפסיקה מבוצעת מחדש ההוראה שגרמה לפסיקה (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

14 טבלת הדפים ב-IA32 (1) טבלת הדפים של תהליך מוצבעת מרגיסטר מיוחד בשם cr3
הטבלה אמורה להכיל כניסה בגודל 4 בתים עבור כל דף במרחב הזיכרון של התהליך כניסה של דף שלא הוקצה לשימוש מכילה ערך NULL (כל הביטים 0) כדי למפות 4GB בדפים של 4KB צריך מיליון כניסות – גודל הטבלה יכול להגיע ל-4MB לכל תהליך עם זאת, תהליך מנצל בדרך-כלל רק חלק מזערי ממרחב הזיכרון הוירטואלי – לא כדאי להחזיק את הטבלה כולה הפתרון: להחזיק שתי רמות היררכיה (או יותר) בטבלה אם מוקצה דף חדש לשימוש התהליך, צריך להקצות, לפי הצורך, דפים נוספים לטבלאות ביניים בהיררכיה עד (לא כולל) השורש מבנה טיפוסי: שתי רמות היררכיה, כמוצג בשקף הבא (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

15 DIRECTORY TABLE OFFSET
31 22 21 12 11 DIRECTORY TABLE OFFSET + Page + Page Table Page Directory + cr3 (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

16 טבלת הדפים ב-IA32 (3) ניהול זיכרון ב-IA32 כל כניסה של דף בטבלת הדפים (בכל רמת היררכיה) מכילה: ביט present: מציין האם הדף נמצא בזיכרון מקביל לביט valid מההרצאה מספר המסגרת בה מאוחסן הדף אם הוא בזיכרון (20 ביטים כאשר הזיכרון הפיזי ממען 32 ביט) ביט accessed: מודלק ע"י החומרה בכל פעם שמתבצעת גישה לכתובת בדף מקביל לביט reference מההרצאה ביט dirty: מודלק ע"י החומרה בכל פעם שמתבצעת כתיבה לנתון בדף מקביל לביט modified מההרצאה ביט read/write: הרשאת גישה. 0 = קריאה בלבד. 1 = קריאה וכתיבה ביט user/supervisor: גישה מיוחסת. 0 = גישה אם CPL < 3. 1 = גישה בכל ערך CPL ועוד (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

17 TLB ב-IA32 ניהול זיכרון ב-IA32 כמקובל בארכיטקטורות חומרה רבות התומכות ב-paging, גם ב-IA32 ממומש Translation Lookaside Buffer (TLB) זהו מטמון (cache) של כניסות בטבלת הדפים הצמוד לכל מעבד, שמטרתו לחסוך תרגומים חוזרים של אותה כתובת ליניארית לפיזית חוסך את הגישה לזיכרון (כפול מספר רמות ההיררכיה) לצורך חישוב בכל החלפת הקשר (למעשה, בכל טעינת ערך חדש ל-cr3) מבוצעת פסילה (invalidation) אוטומטית של תוכן ה-TLB של המעבד (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

18 ניהול זיכרון ב-Linux (1)
משתמשת רק במינימום ההכרחי על-פי הגדרות החומרה: כל ה-segment registers בכל התהליכים מצביעים לאותם סגמנטים המכסים כולם אותו תחום – כל התחום הליניארי סיבה 1: אי-תלות בחומרה: Linux רצה גם בארכיטקטורות חומרה אחרות שתומכות בדפים אבל לא בסגמנטציה סיבה 2: פשטות: מימוש מנגנון שאינו מצריך עדכון segment registers בהחלפת הקשר או בגישה ממרחב הזיכרון של הגרעין לזה של תהליך (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

19 ניהול זיכרון ב-Linux (2)
סגמנט קוד וסגמנט נתונים עבור הגרעין (DPL=0) סגמנט קוד וסגמנט נתונים עבור כל תהליכי המשתמש (DPL=3) ההחלפה בין הסגמנטים (ברגיסטרים cs לקוד ו-ds, es, ss לנתונים) מתבצעת במעבר בין kernel mode ו-user mode כל הסגמנטים, כאמור, מכסים את כל התחום הוירטואלי (כתובת בסיס = 0x0, גודל בדפים = 0xfffff) כתובת לוגית (offset בלבד) = כתובת ליניארית כמו כן, מוגדר סגמנט TSS עבור כל אחד מהמעבדים כפי שראינו בתרגול על החלפת הקשר (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

20 ניהול זיכרון ב-Linux (3)
הרמה הגבוהה ביותר נקראת Page Global Directory (PGD). יש טבלה כזו לכל תהליך הרמה האמצעית נקראת Page Middle Directory (PMD) הרמה התחתונה נקראת Page Table Entry (PTE) טבלאות נוספות בשתי הרמות הנמוכות מוקצות לפי הצורך יחד עם הקצאת דפים חדשים לתהליך (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

21 GLOBALDIR MIDDLEDIR TABLE OFFSET
Page Page Table Page Middle Directory + + Page Global Directory + + base register (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

22 ניהול זיכרון ב-Linux (5)
כיצד מתמפה היררכית 3 רמות של Linux להיררכית 2 רמות טיפוסית של IA32 שראינו קודם? ה-PGD מתמפה ל-Directory (10 ביטים עליונים) ה-PMD מוגדרת כמכסה 0 ביטים: טבלה ברמת PMD מוגדרת כמכילה כניסה אחת שנמצאת בזיכרון באותו מקום כמו הכניסה ב-PGD שמצביעה עליה ה-PTE מתמפה ל-Table (10 ביטים אמצעיים) גודל דף מוגדר כ-4KB (12 ביטים נמוכים משמשים כ-offset) (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

23 מרחב הזיכרון של הגרעין (1)
ניהול זיכרון ב-Linux הזיכרון שבשימוש גרעין Linux לעולם אינו מפונה לדיסק (swapped) זיכרון זה כולל את טבלאות הדפים של התהליכים מרחב הזיכרון של הגרעין ממופה לקטע קבוע של הזיכרון הוירטואלי של כל תהליך באופן זה, הכתובת (הלוגית) של כל אוביקט בגרעין נשארת קבועה בכל מרחבי הזיכרון של תהליכי המשתמש מסיבה זו ומפני שאין הפרדה באמצעות סגמנטים, ניתן להעביר לגרעין פרמטרים מסוג מצביע המכילים offset (32 ביט) בלבד – ללא סגמנט קטע הזיכרון הליניארי המשמש את הגרעין הוא מהכתובת 0xc ומעלה ("הג'יגהבייט הרביעי"), המוגדרת בקבועים PAGE_OFFSET ו-TASK_SIZE קבועים אלו מוגדרים בקבצי הגרעין include/asm-i386/page.h ו-include/asm-i386/processor.h בהתאמה (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

24 מרחב הזיכרון של הגרעין (2)
ניהול זיכרון ב-Linux לפיכך, לרשות תהליך המשתמש עומדים 3GB זיכרון וירטואלי להקצאה לשימוש הגרעין מחזיק טבלת דפים משלו הקרויה Kernel Master Page Global Directory טבלה זו מתעדכנת בכל פעם שהגרעין מקצה ומשחרר דפים לשימוש עצמו בלבד אף תהליך לא משתמש בטבלה זו – תפקידה הוא לשמש כמקור ממנו מתעדכנות טבלאות הדפים של תהליכי המשתמש בכל הנוגע לדפים שבשימוש הגרעין על עדכון טבלאות הדפים של תהליכי המשתמש מתוך טבלת הדפים של הגרעין נלמד בהמשך (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

25 טיפול ב-TLB ב-Linux ניהול זיכרון ב-Linux ישנם מצבים בהם גרעין Linux מצליח להימנע מפסילת כל תוכן ה-TLB בעת ביצוע החלפת הקשר: כאשר התהליך הבא לביצוע חולק את אותו מרחב זיכרון (אותן טבלאות דפים) יחד עם התהליך הקודם ..כלומר, כאשר מדובר בשני חוטים של אותו יישום כאשר התהליך הבא לביצוע הוא חוט גרעין (kernel thread) כמו init או ksoftirq_CPUn לתהליכי/חוטי גרעין אלו אין מרחב זיכרון משלהם – הם פועלים על מרחב הזיכרון של הגרעין. עם זאת, חוט גרעין מנצל את טבלאות הדפים של תהליך המשתמש שרץ לפניו, מפני שאין לו טבלאות דפים משלו מאידך, ישנם מצבים בהם גרעין Linux חייב לפסול בעצמו כניסות ב-TLB: כאשר מתבצע עדכון של רשומה בטבלת הדפים המופיעה גם ב-TLB, כמו למשל בטעינת דף או בפינוי דף (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

26 מרכיבי מערכת הזיכרון ב-Linux (1)
דפים מועברים בין הזיכרון הראשי, שם הם מאוחסנים במסגרות, לבין הזיכרון המשני (דיסקים) שם הם מאוחסנים במאגרי דפדוף (swap areas) ייעודיים או בקבצים הגרעין שומר במרחב הזיכרון שלו מבני נתונים עבור כל תהליך המתארים את מרחב הזיכרון של התהליך, כולל טבלאות הדפים שלו המסגרות הצבועות באלכסונים שחורים מוקצות לגרעין כזכור, דפי הגרעין לעולם לא מפונים לדיסק ב-Linux המסגרות הצבועות בפסים אפקיים כחולים שייכות למטמון הדפים פרטים בהמשך (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

27 מרכיבי מערכת הזיכרון ב-Linux (2)
טעינת דפים לזיכרון הראשי מבוצעת בפעולות Demand Paging דפדוף על-פי דרישה המובעת באמצעות Page Fault פינוי דפים מבוצע בפעולות Page Frame Reclaiming מחזור מסגרות – פעולה המבוצעת כברירה אחרונה כאשר אין מספיק מקום פנוי בזיכרון הראשי טבלאות הדפים מעודכנות להצביע על דף לפי מיקומו וסוגו – בזיכרון, בדיסק או NULL אנו נסקור כל אחד מהמרכיבים שבתרשים בפירוט בהמשך (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

28 זיכרון ראשי Page Frame Reclaiming Demand Paging טבלת דפים דיסקים
מבני הנתונים של הגרעין, כולל: מתארי זיכרון מתארי מרחבי זיכרון טבלת מסגרות + מטמון דפים טבלאות דפים Page Frame Reclaiming Demand Paging טבלת דפים דיסקים מאגר דפדוף swap1 מאגר דפדוף swap2 קובץ /bin/ls קובץ /home/eli/file1 (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

29 ניהול זיכרון תהליך ב-Linux (1)
כזכור, מרחב הזיכרון של תהליך כולל את מרחב הזיכרון של הגרעין (1GB) ואת תחום הזיכרון של 3GB המיועד לשימוש קוד התהליך תהליך לא מקבל לשימושו את כל תחום הזיכרון של 3GB מיד עם תחילת קיומו, אלא רק כמות התחלתית קטנה בהמשך, מוקצה זיכרון נוסף לתהליך מתוך ה-3GB לפי דרישתו הקצאת הזיכרון מבוצעת באמצעות איזורי זיכרון (Memory Regions) איזורי זיכרון הם רצפים לא-חופפים של כתובות במרחב הזיכרון, שרק אליהם מותר לתהליך לגשת (וגם זה תחת הרשאות ספציפיות לכל איזור) ניתן להוסיף, להסיר, להגדיל ולהקטין איזורי זיכרון כתובת התחלתית וגודל של איזור זיכרון הם כפולות של גודל דף (4KB), מפני שיחידת ההקצאה הבסיסית של מנגנון הזיכרון הוירטואלי היא דף הקצאת איזור זיכרון לתהליך לא מוסיפה מיד דפים וכניסות בטבלת הדפים. הקצאת הדפים עצמם נדחית עד לרגע בו הם נדרשים, כפי שנראה בהמשך (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

30 ניהול זיכרון תהליך ב-Linux (2)
הזיכרון שבשימוש הגרעין אינו מופיע כאיזור זיכרון, אבל מופיע בטבלאות הדפים מרחב הזיכרון של תהליך מוגדר ב-Linux באמצעות טבלת דפים וקבוצת איזורי זיכרון איזורי הזיכרון קובעים איזה תת-תחומי כתובות נמצאים בשימוש התהליך (מתוך התחום של 3GB) טבלאות הדפים מציינות היכן (בזיכרון או בדיסק) נמצאים הדפים שמכילים את הכתובות הנ"ל ואת הכתובות שבשימוש הגרעין עם תחילת קיומו, תהליך מקבל מרחב זיכרון ובו קבוצה התחלתית של איזורי זיכרון איזורים "סטנדרטיים" למערכות UNIX: איזור אחד לקוד, אחד לנתונים סטטיים (data), אחד לערימה של הזיכרון הדינמי (heap) ואחד למחסנית user mode איזורים נוספים: אחד לפרמטרים של שורת הפקודה, אחד למשתני מערכת (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

31 ניהול זיכרון תהליך ב-Linux (3)
במהלך ריצת התהליך, קבוצת איזורי הזיכרון במרחב הזיכרון של התהליך יכולה להשתנות איזור המחסנית ב-user mode יכול לגדול עם הגידול במחסנית (אך לא לקטון) איזור הערימה יכול לגדול או לקטון לפי הצורך (הקצאה או שחרור) טעינת / הסרת ספריות דינמיות והפעלה / סגירה של מנגנוני זיכרון משותף הם דוגמאות למצבים של הוספה והסרה של איזורי זיכרון למז"מ של תהליך מרחב זיכרון יכול להיות משותף למספר תהליכים שימושי במיוחד למימוש חוטים עם זאת, יש לזכור שחוטים עדיין צריכים מחסניות נפרדות, המוקצות (לפי LinuxThreads) כאיזורי זיכרון נוספים במרחב הזיכרון המשותף מרחב זיכרון מפונה כאשר אינו בשימוש אף תהליך (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

32 ניהול זיכרון תהליך ב-Linux (4)
בכל פעולה של טעינת התוכנה מחדש כדוגמת execve() ודומיה, מרחב הזיכרון מוחלף לחלוטין (איזורי זיכרון + טבלאות דפים) שחרור מרחב הזיכרון הישן או התנתקות ממנו (אם הוא משותף) והקצאת מרחב זיכרון חדש אם עובדים עם LinuxThreads (חוטים הממומשים כתהליכים החולקים את אותו מרחב זיכרון), אז ספריית החוטים משנה את execve() וגורמת לכך שבנוסף לפעולתה, שאר החוטים (פרט לזה שקרא ל-execve()) מופסקים, כך שמרחב הזיכרון משוחרר בעקבות הקריאה ל-execve() (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

33 ניהול זיכרון תהליך ב-Linux (5)
מתאר הזיכרון מכיל מידע גלובלי על כל מרחב הזיכרון מתאר איזור זיכרון מכיל מידע על איזור זיכרון ספציפי השדה mmap במתאר הזיכרון מצביע על רשימה מקושרת של מתארי איזורי הזיכרון המוכלים במרחב הזיכרון השדה pgd במתאר הזיכרון מצביע על שורש טבלת הדפים הסדר של סוגי איזורי הזיכרון (קוד, data וכו) בדוגמה שבתרשים אינו מחייב (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

34 . environment user mode stack heap data code pgd mmap vm_next vm_end
מתאר איזור זיכרון (vm_area_struct) PAGE_OFFSET environment command line arguments . מתאר זיכרון (mm_struct) user mode stack pgd mmap heap vm_next vm_end vm_start vm_mm data code (c) ארז חדד 2003 מערכות הפעלה - תרגול 10 0x0

35 מתאר הזיכרון של תהליך (1)
ניהול זיכרון תהליך ב-Linux כאמור, מתאר זיכרון (memory descriptor), הוא רשומה המכילה מידע על מרחב הזיכרון של התהליך רשומה מסוג mm_struct קובץ גרעין include/linux/process.h השדה mm במתאר תהליך מצביע על מתאר הזיכרון של התהליך מתארי תהליכים, החולקים אותו מרחב זיכרון, מצביעים על אותו מתאר זיכרון לתהליך גרעין ערך שדה mm הוא NULL – אין לו מרחב זיכרון משלו והוא משתמש במרחב הזיכרון ובמתאר הזיכרון של תהליך משתמש שזומן לריצה לפניו כל מתארי הזיכרון שבמערכת מקושרים זה לזה ברשימה מקושרת (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

36 מתאר הזיכרון של תהליך (2)
ניהול זיכרון תהליך ב-Linux להלן מספר שדות המופיעים במתאר הזיכרון: mmap – מצביע לרשימת מתארי איזורי הזיכרון הרשימה של מתארי איזורי הזיכרון תמיד ממוינת לפי המיקום של כל איזור בזיכרון pgd – מצביע ל-Page Global Directory של מרחב הזיכרון (שורש טבלאות הדפים) זהו הערך הנטען ל-cr3 בהחלפת הקשר mmlist – מצביע קישור ברשימה הגלובלית של מתארי הזיכרון rss – מספר המסגרות שבשימוש מרחב זיכרון זה (דפים בזיכרון הראשי) total_vm – סה"כ דפים באיזורי הזיכרון (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

37 מתאר הזיכרון של תהליך (3)
ניהול זיכרון תהליך ב-Linux mm_users, mm_count – מוני שיתוף של מרחב הזיכרון mm_users סופר כמה תהליכי משתמש חולקים את מרחב הזיכרון mm_count סופר כמה תהליכים (גרעין + משתמש) חולקים את מרחב הזיכרון, כאשר כל תהליכי המשתמש יחד נחשבים כאחד וכל תהליך גרעין בנפרד נחשב כאחד כאשר mm_users = 0 , מפונים איזורי הזיכרון והטבלאות הממפות אותם. מרחב הזיכרון (וטבלאות המיפוי של איזור הגרעין) מפונה כאשר mm_count = 0. בהתאם למה שהוזכר בעבר, חוט/תהליך גרעין מנצל את מרחב הזיכרון של תהליך המשתמש שרץ לפניו, מפני שאין לו מרחב זיכרון משלו. mm_count נועד למנוע מצב בו מרחב הזיכרון מפונה כאשר הוא בשימוש ע"י תהליך גרעין (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

38 מתאר הזיכרון של תהליך (4)
ניהול זיכרון תהליך ב-Linux הפונקציות הבאות המוגדרות בקובץ הגרעין kernel/fork.c מטפלות במתאר הזיכרון של תהליך: הקצאת מתאר זיכרון חדש מבוצעת בפונקציה mm_alloc() שגם מאתחלת את מוני השיתוף ל-1 שיתוף מרחב זיכרון (clone()) מגדיל את mm_users בפונקציה copy_mm() סיום שימוש במרחב זיכרון (do_exit() או execve()) מפעיל את הפונקציה mmput() המקטינה את mm_users ב-1. אם mm_users=0 מפונים איזורי הזיכרון והטבלאות הממפות אותם, ומופעלת הפונקציה mmdrop(), המקטינה את mm_count ב-1 ובודקת אם הוא 0, שאז מפונה מתאר הזיכרון לחלוטין (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

39 מתאר איזור זיכרון (1) ניהול זיכרון תהליך ב-Linux לכל איזור זיכרון במרחב הזיכרון יש, כאמור, מתאר איזור זיכרון (memory region object), שהוא רשומה המכילה מידע לגבי איזור הזיכרון מתאר איזור הזיכרון אינו ניתן לשיתוף. אם לשני (או יותר) מרחבי זיכרון שונים יש איזור זיכרון משותף, ייווצר בכל אחד מהם מתאר איזור זיכרון המצביע כל אחד לרצף הדפים המשותף כל דף באיזור משותף מוגדר כדף משותף – יש לו כניסה בטבלת הדפים בכל אחד ממרחבי הזיכרון החולקים בו בדרך-כלל האיזור המשותף אף ממופה לתחומי כתובות שונים במרחבי הזיכרון השונים מתאר איזור הזיכרון הוא מסוג vm_area_struct קובץ גרעין include/linux/mm.h (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

40 מתאר איזור זיכרון (2) מספר שדות במתאר איזור הזיכרון:
ניהול זיכרון תהליך ב-Linux מספר שדות במתאר איזור הזיכרון: vm_mm – מצביע למתאר הזיכרון של המרחב המכיל את האיזור vm_start – כתובת התחלה של איזור הזיכרון vm_end – כתובת אחת אחרי האחרונה של איזור הזיכרון vm_next – מצביע למתאר איזור הזיכרון הבא ברשימת האיזורים של המרחב המכיל את איזור הזיכרון vm_page_prot – ערכי ביטים שונים שיוצבו לכל הכניסות של הדפים באיזור. ראה בהמשך vm_flags – דגלים המציינים תכונות של האיזור, למשל: VM_READ, VM_WRITE, VM_EXEC, VM_SHARED – הרשאות: האם מותר לקרוא/לכתוב/לבצע נתונים בדפים באיזור, האם מותר לשתף דפים באיזור דגלים המציינים האם מותר לפנות את הדפים באיזור מהזיכרון למאגר דפדוף ואיזה. לדוגמה – VM_LOCKED – אין לפנות את הדפים. VM_EXECUTABLE – הדפדוף הוא לקובץ ריצה (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

41 מתאר איזור זיכרון (3) ניהול זיכרון תהליך ב-Linux דגלים המציינים התפתחות של איזור הזיכרון: VM_GROWSDOWN מציין שהאיזור גדל בכיוון הכתובות הנמוכות (אופייני למחסניות), VM_GROWSUP מציין גידול לכיוון הכתובות הגבוהות ערכי הביטים בכניסות טבלת הדפים המתאימות לכל הדפים באיזור זיכרון נקבעים לפי ערכי דגלי ההרשאות שבאובייקט איזור הזיכרון כזכור, IA32 מאפשרת ברמת דף (באמצעות הביט r/w) רק קריאה או קריאה וכתיבה (execute מוגדר כ-read) לפיכך, נקבעות הרשאות הדף לפי הרשאות האיזור לפי ה"אלגוריתם" הבא: מדליקים את present (כי כשדף מוקצה לראשונה, הוא בזיכרון) ואת user/supervisor (כי הדף אמור להיות נגיש לקוד תהליכי משתמש) אם יש הרשאת write באיזור, מדליקים את r/w (הכל מותר) (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

42 מתאר איזור זיכרון (4) ניהול זיכרון תהליך ב-Linux אחרת, אם באיזור יש הרשאת read או execute, מכבים את r/w (מותר רק לקרוא) אחרת (אין הרשאות), מכבים את present לדף שכזה, אסור להתיר גישה, וכיבוי present גורם לחריגת page fault בגישה לדף כדי להבדיל דף כזה מדף שבאמת לא נמצא בזיכרון, מדליקים ביט נוסף בכניסה בטבלת הדפים הקרוי PSE, שאינו בשימוש החומרה ישנם מצבים בדפים משותפים בהם הביטים מוצבים בכוונה לערך שאינו מתאים להרשאות האיזור. פרטים בהמשך (copy on write) שיטת החישוב המדויקת של הרשאות דף מבוצעת דרך המערך protection_array, שממפה את הרשאות האיזור להרשאות דף התוצאה של החישוב נשמרת בשדה vm_page_prot ומוצבת לדפים באיזור עם הקצאתם (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

43 מאגרי דפדוף ב-Linux (1) Linux מאפשרת הגדרה של מספר מאגרי דפדוף (Swap Areas) אליהם מפונים דפים (מיפוי אנונימי) מהזיכרון הראשי עד MAX_SWAPFILES (32) מאגרים ניתן להפעיל ולכבות מאגרי דפדוף באופן דינמי תוך כדי פעולת המערכת עומס הדפים המפונים מחולק בין המאגרים כל מאגר דפדוף הוא שטח דיסק המחולק למגירות (slots), כאשר כל מגירה היא בגודל דף (4KB) ומשמשת לאיחסון דף מהזיכרון הראשי המגירה הראשונה אינה משמשת לאחסון דפים – מכילה מידע ניהולי על המאגר (גודל, גרסת אלגוריתם דפדוף וכו') אלגוריתם הדפדוף משתדל להקצות מגירות לדפים מפונים ברצף כדי לשפר את זמן הגישה (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

44 מאגרי דפדוף ב-Linux (2) לכל מאגר דפדוף מחזיק הגרעין בזיכרון רשומת מתאר מאגר (Swap Area Descriptor) מסוג swap_info_struct קובץ גרעין include/linux/swap.h מספר שדות המופיעים ברשומת מתאר המאגר: swap_device, swap_file – מזהי ההתקן בו נמצא מאגר הדפדוף (יכול להיות קובץ או התקן חומרה) swap_map – מערך מוני שימוש עבור כל המגירות. לכל מגירה, סופר כמה מרחבי זיכרון מצביעים אליה (דרך טבלת דפים) max – גודל מאגר הדפדוף בדפים כל מתארי המאגרים שבשימוש המערכת נמצאים במערך swap_info (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

45 מאגרי דפדוף ב-Linux (3) דף זיכרון השמור במאגר דפדוף מזוהה בפשטות באמצעות מספר הכניסה של מאגר הדפדוף במערך swap_info + מספר המגירה במאגר הדפדוף: הצירוף שלעיל נקרא מזהה הדף הפיזי (Swapped-Out Page Identifier) כאשר דף מפונה לדיסק, מוצב ערך זה בכניסה בטבלת הדפים שהצביעה לדף ביט 0 (שערכו 0) הוא גם המקום של הביט Present בכניסה בטבלת הדפים – כך מסמנים לחומרה שהדף אינו הזיכרון 31 8 7 1 מספר המגירה במאגר מספר המאגר (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

46 טבלת המסגרות ב-Linux גרעין Linux מחזיק מערך עם כניסה לכל מסגרת בזיכרון הראשי של המחשב המערך נקרא mem_map וכל כניסה היא מסוג struct page קובץ גרעין include/linux/mm.h מספר שדות חשובים בכל כניסה: count – מונה שימוש (reference counter) של הדף שבמסגרת: כמה מרחבי זיכרון מצביעים לדף זה כשהוא בזיכרון. אם ערך המונה הוא 0, המסגרת פנויה mapping, index, next_hash, pprev_hash – משמשים במטמון הדפים, כפי שנראה מיד lru – משמש למנגנון פינוי הדפים. פרטים בהמשך flags – דגלים המתארים את מצב הדף שבמסגרת, כגון: PG_locked – מציין שהמסגרת נעולה עקב פעולת פינוי/הבאת דף שעדיין לא הסתיימה PG_referenced, PG_active, PG_lru, PG_dirty, PG_launder – משמשים למנגנון פינוי הדפים. פרטים בהמשך (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

47 מטמון הדפים ב-Linux (1) כפי שכבר הוזכר, מערכת ההפעלה מפנה וטוענת דפים של מרחבי זיכרון של תהליכים במסגרת פעולת מנגנון הזיכרון הוירטואלי עם זאת, Linux טוענת ומפנה דפים בין הדיסק לזיכרון גם בשביל פעולת מערכת הקבצים: כאשר תהליך פותח קובץ לעבודה, Linux טוענת דפים המכילים מידע מהקובץ ומשתמשת בהם כחוצצים לשיפור הביצועים בקריאות וכתיבות – קריאות מהזיכרון וכתיבות לזיכרון מתבצעות מהר יותר מאשר בעבודה ישירה עם הדיסק בנקודות זמן שונות, נכתבים דפי החוצצים בחזרה לקובץ בדיסק כדי לעדכן אותו התקני חומרה ב-Linux מהווים חלק ממערכת הקבצים, ולכן העבודה מולם מתבצעת בצורה דומה (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

48 מטמון הדפים ב-Linux (2) מטמון הדפים (Page Cache) הוא המנגנון המרכזי לטעינת ופינוי דפים בין הזיכרון לדיסק ב-Linux לכל מטרה שהיא מטמון הדפים ממומש בתוך טבלת המסגרות דפים מוכנסים ומוסרים במטמון באופן דינמי, ובהתאם לכך המסגרות שלהם דוגמאות לדפים שאינם במטמון: דפים של הגרעין, דפים שאינם מיועדים לפינוי, ועוד גם דפים הניתנים לפינוי יכולים להצטרף ולצאת מהמטמון, כפי שנראה בהמשך (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

49 מטמון הדפים ב-Linux (3) דף המכיל מידע מהדיסק, יכול להכיל סוגים שונים של מידע: קטע של קובץ: קוד מתוכנית טעונה, נתונים מקובץ נתונים דף כזה נקרא ממופה לקובץ (file mapped) דף זיכרון של תהליך שנשמר בדיסק במאגר דפדוף כלשהו (swap area) דף כזה נקרא ממופה אנונימי (anonymous mapped) שימו לב! דפים של קוד במרחב זיכרון תהליך, כמו גם דפים המכילים נתונים מקבצים, אינם מטופלים כמו דפים של נתונים או מחסנית של תהליך, בכך שהם מפונים אל הקבצים מהם נטענו ולא אל מאגר דפדוף כללי כלשהו בהתאם לסוג המידע המוכל בדף, משתנה הטיפול בדף בטעינה ופינוי טעינה ופינוי לקובץ מסוים או למאגר דפדוף (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

50 מטמון הדפים ב-Linux (4) בהתאם לכך, שדה mapping ברשומת מסגרת של דף במטמון הדפים, מצביע לאובייקט ניהול המכיל מידע ופונקציות לטיפול בדף שבמסגרת (פינוי וטעינה) אם הדף ממופה לקובץ, אובייקט הניהול מקושר לקובץ המתאים אם הדף ניתן לדפדוף וממופה אנונימי (ומיועד לפיכך למאגרי דפדוף), אובייקט הניהול הוא מטמון הדפדוף (swap cache) שהוא אובייקט מיוחד עבור דפים כאלו שדה index ברשומת מסגרת כל דף במטמון הדפים מציין את המיקום הפיזי של הדף במאגר המידע בדיסק עבור מידע מקובץ, את ההיסט מתחילת הקובץ (offset) עבור דף מזכרון תהליך, את מזהה הדף הפיזי (כלומר מצביע למגירה) (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

51 מטמון הדפים ב-Linux (5) מטמון הדפים מכיל hash-table המתרגם צירוף של (mapping+index) לכתובת מסגרת (אם יש כזו) המכילה את הדף במיקום index של האוביקט mapping כל המסגרות שמתאימות לאותו hash מקושרות ברשימה כפולה מעגלית דרך השדות next_hash ו-pprev_hash ברשומת המסגרת ה-hash table שימושי במיוחד עבור מנגנון הדפדוף, כפי שנראה בהמשך הפונקציות/מאקרו הבאות, המוגדרות בקבצי הגרעין mm/filemap.c ו-include/linux/pagemap.h, קשורות ל-hash table: page_hash() – פונקצית ה-hash (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

52 מטמון הדפים ב-Linux (6) find_get_page() – מקבלת mapping+index ומחזירה מצביע למסגרת המכילה את הדף המתאים (או NULL אם אין) add_to_page_cache() – הוספת מסגרת + מיקום פיזי (מגירה או בקובץ) למטמון וכך גם ל-hash-table מבחינת מונה השימוש של מסגרת (שדה count) או מגירה (מונה swap_map), מטמון הדפים נחשב כמרחב זיכרון נפרד המשתמש בדף המאוחסן בה כאשר מסגרת או מגירה בשימוש מטמון הדפים, מוגדל המונה ב-1. הקטנת המונה ב-1 מבוצעת עם ניתוק המסגרת או המגירה מהמטמון המטרה: למנוע שיבוש במיפוי ה-hash-table באמצעות הקצאה מחדש של המסגרת/מגירה עד להוצאת הדף מהמטמון (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

53 הקשר בין מסגרת למגירה (1)
מטמון הדפים ב-Linux הקשר בין מסגרת ומגירה, המכילות את אותו דף ממופה אנונימי, הינו דינמי: דף המצוי במגירה יכול להטען לכל מסגרת פנויה שתוקצה בעת הצורך דף מפונה למגירה בדיסק רק לאחר שכל מרחבי הזיכרון השותפים בו מצביעים על המגירה בדיסק – והקשר הקיים בין המסגרת למגירה ניתן לניתוק Linux מאפשרת קישור דינמי גם בכיוון ההפוך: לאחר שדף נטען לזיכרון וכל מרחבי הזיכרון מצביעים למסגרת, ניתן לשחרר את המגירה ולנתק את הקשר הקיים בעת הכנת דף לפינוי, מקצים לו מסגרת חדשה אם אין לו מטמון הדפדוף (בתוך מטמון הדפים) מחזיק את הקשר בין המגירה והמסגרת של אותו דף, כל עוד קשר זה מתקיים (ומסמן בכך את קיום הקשר) כאשר הקשר ניתק, המסגרת מוצאת ממטמון הדפים ..וגם מונה השיתוף של המגירה מוקטן (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

54 הקשר בין מסגרת למגירה (2)
מטמון הדפים ב-Linux בתרשים בהמשך מוצגת דוגמה לתהליך פינוי דף ממופה אנונימי למסגרת S1 ו-S2 הם שני מרחבי זיכרון שלהם דף משותף P, המצוי בתחילה (שלב 1) במסגרת בזיכרון. PC הינו מטמון הדפים הערך הכתוב במשבצת של המסגרת של P ושל המגירה של P בכל השלבים הינו מונה השיתוף (count או swap_map) במסגרת פינוי דפים, מבוצע מעבר על הטבלאות של S1 והגרעין מחליט לפנות את P (שלב 2): הדף P אינו במטמון הדפים (שדה mapping במסגרת מצביע על NULL) ולכן: מוקצית מגירה עבור P המסגרת והמגירה של P מקושרות למטמון הדפים (עדכון מוני השיתוף, עדכון mapping ו-index במסגרת) הטבלה ב-S1 עוברת להצביע על המגירה של P (מזהה הדף הפיזי מוצב בטבלה, עדכון מוני השיתוף) P עדיין לא מפונה פיזית מהזיכרון! (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

55 הקשר בין מסגרת למגירה (3)
מטמון הדפים ב-Linux בהמשך, מבוצע מעבר גם על הטבלאות של S2 ושוב הגרעין מחליט לפנות את P (שלב 3): כעת, הדף P כבר במטמון הדפים ולכן: הטבלה ב-S2 עוברת להצביע על המגירה של P P עדיין לא מפונה פיזית מהזיכרון! מאוחר יותר, מתבצע פינוי פיזי של הדף P, לאחר שהמסגרת כבר לא משמשת מרחבי זיכרון של תהליכים: תוכן המסגרת נכתב לדיסק המסגרת מוצאת ממטמון הדפים ומסומנת כפנויה (מונה השיתוף) המגירה מוצאת אף היא ממטמון הדפים (עדכון מונה השיתוף) ראינו בדוגמה זו כיצד מאפשר מטמון הדפים פעולה הדרגתית של פינוי דף, ממרחב זיכרון אחד בכל פעם, תוך שמירה על תיאום בין מרחבי הזיכרון המשתמשים בדף אין צורך לעדכן את כל טבלאות הדפים המתייחסות לאותו דף בבת אחת ניתן לדחות את פעולת הפינוי הפיזי ככל הרצוי הדף מפונה פיזית פעם אחת, ולמקום אחד בדיסק (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

56 הקשר בין מסגרת למגירה (4)
מטמון הדפים ב-Linux בטעינת דף מתבצעות הפעולות בסדר הפוך בקירוב, תוך שימוש במטמון הדפים בטעינת דף למרחב זיכרון מסוים, בודקים אם הדף כבר נטען למסגרת בזיכרון באמצעות find_get_page(): אם כן, רק מעדכנים את טבלת הדפים ומוני השיתוף אחרת, טוענים את הדף לזיכרון ומכניסים אותו למטמון הדפים גם טעינת דף משותף מתבצעת בצורה הדרגתית תוך שמירה על תיאום בין התהליכים הדף נטען פעם אחת בלבד ולמסגרת אחת בלבד התמונה הכללית דומה מאוד עבור דפים ממופים לקובץ ההבדל העיקרי הוא שהמיקום של הדף בדיסק הוא קבוע, ולכן אין צורך "להקצות מגירה" בפינוי לדיסק הדף נמצא במטמון הדפים כל עוד הוא בזיכרון, כי אינו מנותק מהמיקום הפיזי אין צורך לשמור מצביע למיקום הפיזי בטבלת הדפים, כי ניתן לחשב את המיקום לפי מקום הדף באיזור הזיכרון הממופה לקובץ, ולכן שומרים NULL בטבלת הדפים כשהדף מפונה (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

57 2 1 4 3 2 2 S1 S1 PC PC S2 S2 2 1 S1 S1 PC PC S2 S2 2 3 P זיכרון ראשי
מאגר דפדוף מאגר דפדוף 4 3 זיכרון ראשי P זיכרון ראשי 1 S1 S1 PC PC S2 S2 P P 2 3 מאגר דפדוף מאגר דפדוף (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

58 פינוי דפים ב-Linux כפי שכבר הוזכר קודם, פינוי דפים ב-Linux מתבצע כפעולה של חוסר ברירה Linux נוטה לנצל את הזיכרון הראשי ככל האפשר מבלי לפנות דפים כלל מוגדר סף "קריטיות" של כמות מינימלית של מסגרות שחייבת להשאר פנויה – לצורך הפעלת אלגוריתמים של פינוי זיכרון למעשה, הזיכרון הראשי מחולק למתחמי זיכרון (Memory Zones) שבמתאר של כל אחד מהם מוגדר סף קריטי מינימלי (pages_low), ובכל אחד מהם מתבצע פינוי מסגרות בנפרד לכל מתחם זיכרון מוגדר גם סף עליון (pages_high), שמעבר לו אין צורך לבצע פינוי מסגרות מנגנון פינוי הדפים, הקרוי מנגנון מחזור מסגרות (Page Frame Reclaiming), מופעל בקריאה לפונקציה try_to_free_pages() המקבלת כפרמטר מצביע למתאר מתחם הזיכרון המיועד לפינוי קובץ גרעין mm/vmscan.c (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

59 אלגוריתם פינוי הדפים פינוי דפים מהזיכרון לדיסק הינו מנגנון בעל שלושה מרכיבים ב-Linux: דירוג דינמי של רמת הפעילות של כל דף במסגרת בזיכרון (שאינו שייך לגרעין) כאשר עולה הצורך בפינוי זיכרון: מעבר על רשימת המסגרות בעלות ה"פעילות הנמוכה ביותר" ופינוי המסגרות שאינן בשימוש מרחבי זיכרון של תהליכים אם אין מספיק מסגרות לפינוי כשצריך: מעבר על טבלאות הדפים של כל מרחבי הזיכרון של תהליכי משתמש: כאשר מאותרת כניסה השייכת לאיזור זיכרון ומצביעה למסגרת הניתנת לפינוי ובעלת פעילות "נמוכה", מבוצע פינוי של הדף ממרחב הזיכרון הנבדק פינוי דף ממרחב זיכרון יחיד, בהתאם לשיטה שהודגמה קודם (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

60 פינוי דפים ב-Linux הפעלת הפונקציה try_to_free_pages() מבוצעת במקרים הבאים: כאשר מתעורר חוט גרעין מיוחד הקרוי kswapd (או "swapper"), בודק את כמות המסגרות הפנויה ומגלה שהגיעה לסף הנמוך או עברה אותו, ומפעיל כתוצאה את try_to_free_pages(). הפונקציה מופעלת שוב ושוב עד שכמות המסגרות הפנויות עוברת את הסף העליון (כדי למנוע סחרור – thrashing) חוט גרעין זה (pid=0) רץ בעדיפות נמוכה ומנצל לפיכך את ה-idle time (זמן ללא פעילות תהליכים) לפעולות ארוכות של פינוי הזיכרון, כך שכשתהליכי משתמש חוזרים לרוץ, יש להם יותר זיכרון זמין – שיפור ביצועי המערכת כאשר הקצאת מסגרת חדשה נכשלת (בעקבות הגעה לסף הקריטי) מתבצעת הפעלה ישירה של הפונקציה או שמעירים את kswapd (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

61 בחירת דפים לפינוי הגרעין מחזיק שתי רשימות מקושרות כפולות מעגליות של מסגרות במטמון הדפים: active_list – רשימת מסגרות הדפים ה"פעילים", כלומר דפים שניגשו אליהם "לאחרונה" inactive_list – רשימת מסגרות הדפים ה"לא-פעילים", כלומר דפים שלא נגשו אליהם "זמן מה" active_list, inactive_list הם שמות המשתנים הגלובליים המצביעים לראשי הרשימות, המוגדרים בקובץ הגרעין mm/page_alloc.c הרשימות לא-חופפות, ומסגרות מועברות בין הרשימות כפי שנראה בהמשך מסגרת מוספת לרשימה דרך ראש הרשימה הדגל PG_lru דולק ברשומת מסגרת הנמצאת באחת מהרשימות (לא מסגרת השייכת לגרעין, למשל) הקישור של מסגרת לאחת הרשימות הוא באמצעות השדה lru ברשומת המסגרת הדגל PG_active דולק רק בכל רשומת מסגרת השייכת לרשימה active_list (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

62 בחירת דפים לפינוי הדגל PG_referenced ברשומת מסגרת מציין שבוצעה גישה לדף במסגרת זו דגל זה משמש ליצירת שתי הזדמנויות למסגרת להשאר ב-active_list אבל גם שתי מדרגות למסגרת על-מנת להכנס ל-active_list מתוך ה-inactive_list הפונקציה mark_page_accessed(), המופעלת לציון גישה למסגרת, מבצעת כדלקמן: אם המסגרת ב-active_list, מדליקה את PG_referenced. אחרת, אם PG_referenced כבוי, מדליקה אותו. אחרת, מכבה את PG_referenced ומכניסה את המסגרת ל-active_list קובץ גרעין mm/filemap.c הפונקציה refill_inactive(), המופעלת לעדכון inactive_list מפעם לפעם, עוברת על כל המסגרות ב-active_list מסוף הרשימה (מסגרות ותיקות ביותר): אם PG_referenced דלוק, מכבה אותו ומכניסה את המסגרת מחדש ל-active_list. אחרת, מעבירה את המסגרת ל-inactive_list עם דגל PG_referenced דולק קובץ גרעין mm/vmscan.c (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

63 בחירת דפים לפינוי PG_referenced=0 PG_active=0 PG_referenced=0 PG_active=1 add_to_page_cache() refill_inactive() mark_page_accessed() PG_referenced=1 PG_active=0 PG_referenced=1 PG_active=1 הפונקציה mark_page_accessed() מופעלת עבור דף כלשהו כאשר: בכל פעם שדף זה נטען מהדיסק בכל פעם שהגרעין מגלה שביט accessed של דף זה בטבלת הדפים דלוק – אז גם הביט accessed מכובה פינוי הדפים מבוצע החל מסוף רשימת ה-inactive_list האלגוריתם המתקבל הוא קירוב ל-LRU: "אלגוריתם ההזדמנות השלישית??" (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

64 הפונקציה try_to_free_pages()
פונקציה זו מנסה לפנות SWAP_CLUSTER_MAX (32) מסגרות במתחם זיכרון נתון קוד עקרוני של הפונקציה בשקף הבא מחזירה 1 בהצלחה, 0 בכישלון הפונקציה קוראת לפונקצית פינוי המסגרות shrink_caches() במספר רמות עולות של עדיפות (priority) על-מנת לגרום לפינוי כמות המסגרות הדרושה shrink_caches() מחזירה בכל פעם את מספר המסגרות שנותרו לפינוי מהיעד שלה אם עדיין לא הושגה הכמות הרצויה (מצב קיצוני של מחסור בזיכרון), הפונקציה קוראת ל-out_of_memory() על-מנת להרוג תהליך משתמש (ואת שותפיו למרחב הזיכרון) ולקחת את מרחב הזיכרון שלו אם אין תהליכי משתמש, המערכת מושבתת בהודעת שגיאה (kernel oops) (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

65 הפונקציה try_to_free_pages()
תהליך המשתמש שמועדף כקורבן הוא כזה שאמור להביא "מקסימום תועלת במינימום נזק": הרבה מסגרות במרחב הזיכרון, מעט זמן ריצה (לא הספיק הרבה..), עדיפות נמוכה מהרגיל (nice > 0 - פחות חשוב..), ללא זכויות superuser (שוב, פחות חשוב) וללא גישה לחומרה (כדי שלא ישבש את פעולת המערכת) הריגת תהליך משתמש נחשבת ככישלון – מוחזר 0 קוד הפונקציה: int priority = DEF_PRIORITY; /* 6 */ int nr_pages = SWAP_CLUSTER_MAX; /* 32 */ .. do { nr_pages = shrink_caches(classzone, priority, gfp_mask, nr_pages); if (nr_pages <= 0) return 1; } while (--priority); out_of_memory(); return 0; (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

66 פונקציות פינוי המסגרות
הפונקציה shrink_caches() מנסה בכל הפעלה לפנות מסגרות על-ידי סדרת שלבים, כשהמעבר לשלב הבא מותנה בכך שעדיין לא הושגה כמות המסגרות הפנויות הנדרשת: הפעלת פונקציות לצמצום גודל מטמוני זיכרון (פרט למטמון הדפים) הפעלת refill_inactive() על-מנת להגדיל את ה-inactive_list, ואחריה קריאה ל-shrink_cache() על-מנת לנסות לשחרר מסגרות מה-inactive_list צמצום מטמונים של מערכת הקבצים, בתקווה שזה יגרום לשחרור דפים עד להפעלה הבאה של הפונקציה כאמור, הפונקציה מחזירה את מספר המסגרות שנותר לה לפנות מתוך היעד המקורי shrink_caches() ו-shrink_cache () מוגדרות בקובץ הגרעין mm/vmscan.c (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

67 פונקציות פינוי המסגרות
הפונקציה shrink_cache() מקבלת כפרמטרים את העדיפות (priority), מתחם הזיכרון (classzone) וכמות יעד של מסגרות לפינוי (nr_pages) פעולת הפונקציה היא אלגוריתם השחרור כפי שהוזכר קודם: מתחילה לסרוק מסגרות החל מסוף ה-inactive_list מנסה לפנות רק מסגרות: הנמצאות במתחם המבוקש שעדיין לא פונו ממטמון הדפים (count > 0) שאינן בשימוש תהליכי משתמש (count = 1) לכל מסגרת מתאימה: אם המסגרת בתהליך כתיבה לדיסק (PG_launder דולק), ממתינה לסיום הכתיבה אם המסגרת "מלוכלכת" (דגל PG_dirty דולק), יוזמת התחלת כתיבה של המסגרת, מדליקה את PG_launder ומכבה את PG_dirty שחרור המסגרת מתבטא (c) ארז חדד 2003 מערכות הפעלה - תרגול 10

68 טיפול ב-Page Fault ב-Linux
(c) ארז חדד 2003 מערכות הפעלה - תרגול 10


Download ppt "תרגול 10 – זיכרון וירטואלי ב-Linux"

Similar presentations


Ads by Google