Presentation is loading. Please wait.

Presentation is loading. Please wait.

תרגול 12 – ניהול זיכרון ב-Linux: המשך

Similar presentations


Presentation on theme: "תרגול 12 – ניהול זיכרון ב-Linux: המשך"— Presentation transcript:

1 תרגול 12 – ניהול זיכרון ב-Linux: המשך
מערכות הפעלה תרגול 12 – ניהול זיכרון ב-Linux: המשך

2 תוכן התרגול מתאר זיכרון טבלאות דפים טיפול ב – Page Fault Demand Paging
מתאר אזור זיכרון טבלאות דפים טבלאות הדפים של תהליכים יצירת תהליך חדש TLB טבלאות דפים של הגרעין טיפול ב – Page Fault זיהוי החריגה טיפול במרחב הזיכרון של הגרעין טיפול במרחב הזיכרון של תהליך Demand Paging (c) ארז חדד 2003 תרגול 12 – ניהול זיכרון ב-Linux: המשך

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

4 שדות במתאר הזיכרון של תהליך
mmap: מצביע לרשימת מתארי אזורי הזיכרון ממוינת לפי המיקום של כל אזור בזיכרון pgd: מצביע ל-Page Global Directory של מרחב הזיכרון (שורש טבלאות הדפים) mmlist: מצביע קישור ברשימה הגלובלית של מתארי הזיכרון rss: מספר המסגרות שבשימוש מרחב זיכרון זה (דפים בזיכרון הראשי) total_vm: מספר דפים כולל באזורי הזיכרון mm_users, mm_count: מוני שיתוף של מרחב הזיכרון mm_users סופר כמה תהליכי משתמש חולקים את מרחב הזיכרון mm_count סופר כמה תהליכי גרעין + משתמש חולקים את מרחב הזיכרון כל תהליכי המשתמש יחד נחשבים כאחד, אבל כל תהליך גרעין נספר בנפרד כאשר mm_users = 0, מפונים אזורי הזיכרון והטבלאות הממפות אותם. כאשר mm_count = 0, מפונה מרחב הזיכרון (וטבלאות המיפוי של אזור הגרעין). mm_count מונע פינוי מרחב זיכרון כאשר הוא בשימוש ע"י תהליך גרעין, שכן לתהליך גרעין אין מרחב זיכרון משלו, והוא מנצל את מרחב הזיכרון של תהליך המשתמש שרץ לפניו. (c) ארז חדד 2003 תרגול 12 – ניהול זיכרון ב-Linux: המשך

5 מתאר אזור זיכרון (memory region object)
רשומה עם מידע לגבי כל אזור זיכרון במרחב הזיכרון. vm_area_struct – מוגדר בקובץ גרעין include/linux/mm.h vm_mm: מצביע למתאר הזיכרון של המרחב המכיל את האזור vm_start: כתובת התחלה של אזור הזיכרון vm_end: כתובת אחת אחרי האחרונה של אזור הזיכרון vm_next: מצביע למתאר אזור הזיכרון הבא ברשימת האזורים של המרחב המכיל את אזור הזיכרון vm_page_prot: ערכי ביטים שונים שיוצבו לכל הכניסות של הדפים באזור. vm_flags – דגלים המציינים תכונות של האזור, למשל: VM_READ, VM_WRITE, VM_EXEC, VM_SHARED: הרשאות האם מותר לקרוא/לכתוב/לבצע נתונים בדפים באזור, האם מותר לשתף דפים באזור "הרשאת הרשאה" לכל אחת מההרשאות הנ"ל לדוגמה - VM_MAY_WRITE: האם מותר להדליק את VM_WRITE דגלים המציינים האם מותר לפנות את הדפים באזור מהזיכרון למאגר דפדוף ואיזה. VM_LOCKED: אסור לפנות את הדפים. VM_EXECUTABLE: הדפדוף הוא לקובץ ריצה. (c) ארז חדד 2003 תרגול 12 – ניהול זיכרון ב-Linux: המשך

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

7 טבלת דפים בשתי רמות 31 22 21 12 11 cr3 Page Global Directory Page
cr3 Page Global Directory Page DIRECTORY TABLE OFFSET + Page Table מוקצה לפי דרישה תמיד מוקצה בזכרון (c) ארז חדד 2003 תרגול 12 – ניהול זיכרון ב-Linux: המשך

8 מבנה כניסה בטבלת הדפים כניסה בטבלת הדפים היא בגודל bit 32.
המידע שכניסה מכילה תלוי בביט present , המציין האם הדף נמצא בזיכרון הראשי. בהרצאה דיברנו על ביט valid עם משמעות דומה. ביט 0 הוא המקום של הביט present בכניסה בטבלת הדפים. present = 1: הדף נמצא בזיכרון הראשי הכניסה מכילה שדות המתארים את הדף בזיכרון הראשי. present = 0: הדף נמצא באזור ה-swap של הדיסק (הזיכרון המשני). הכניסה מכילה שדות המתארים את הדף במאגר הדפדוף. (c) ארז חדד 2003 תרגול 12 – ניהול זיכרון ב-Linux: המשך

9 כניסה בטבלת הדפים, עם present = 1
מספר המסגרת בה מאוחסן הדף 20 ביטים, כאשר כתובות זיכרון פיזי באורך 32 ביט ביט accessed: מודלק ע"י החומרה בכל פעם שמתבצעת גישה לכתובת בדף נקרא ביט reference בהרצאה ביט dirty: מודלק ע"י החומרה בכל פעם שמתבצעת כתיבה לנתון בדף נקרא ביט modified בהרצאה ביט read/write: הרשאת גישה. 0 = קריאה בלבד. 1 = קריאה וכתיבה הרשאות הדף נקבעות לפי הרשאות האזור בהתאם לכללים הבאים: אם יש הרשאת write באזור, מדליקים את r/w (הכול מותר) אחרת, אם באזור יש הרשאת read או execute, מכבים את r/w (מותר רק לקרוא) ביט user/supervisor: גישה מיוחסת. 0 = גישה לקוד הגרעין בלבד. 1 = גישה לכל תהליך. (c) ארז חדד 2003 תרגול 12 – ניהול זיכרון ב-Linux: המשך

10 כניסה בטבלת הדפים, עם present = 0
הדף נמצא במאגר דפדוף (swap), ושומרים עבורו מזהה מגירה (Swapped-Out Page Identifier), אשר מורכב מ: מספר מאגר הדפדוף בו נמצא הדף. מספר מגירה (slot) במאגר הדפדוף, שבה נמצא הדף. מספר המגירה במאגר מספר המאגר 1 7 8 31 (c) ארז חדד 2003 תרגול 12 – ניהול זיכרון ב-Linux: המשך

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

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

13 העתקת מרחב זיכרון העתקה פשוטה של מרחב זיכרון היא:
יקרה: הרבה זמן דרוש לביצוע העתקה של כל הדפים, דבר העלול להפוך את קריאת fork() למסורבלת מאוד אולי מיותרת: מרחב הזיכרון של תהליך הבן יאותחל מחדש אם הוא יטען תוכנית חדשה מיד עם תחילת ביצועו (קריאה ל-execv()) Linux משתמשת ב Copy On Write (COW), המקובלת בכל סוגי מערכות UNIX המודרניות: דפים הניתנים לכתיבה שאינם יכולים להיות משותפים (כדוגמת דפי נתונים ומחסנית), מוגדרים בתחילה כמשותפים אבל מועתקים לעותק פרטי כאשר אחד התהליכים השותפים (האב או הבן) מנסה לכתוב אליהם לראשונה שאר הדפים (כדוגמת דפי קוד או דפי נתונים לקריאה בלבד) הופכים למשותפים בין מרחבי הזיכרון של האב והבן החיסרון של טכניקת COW הוא שלאחר fork(), כתיבה ראשונה לכל דף שאינו משותף יקרה בגלל הטיפול בחריגת דף. (c) ארז חדד 2003 תרגול 12 – ניהול זיכרון ב-Linux: המשך

14 יצירת מרחב זיכרון חדש לבן ב-COW
הפונקציה copy_mm(), המופעלת מתוך do_fork(), יוצרת עבור תהליך הבן עותק של מתאר הזיכרון של תהליך האב לכל אזור זיכרון של האב: מתאר אזור הזיכרון מועתק למתאר אזור זיכרון חדש של הבן הכניסות בטבלאות הדפים הממפות את האזור מועתקות לכניסות בטבלאות הבן. כל הדפים הופכים למשותפים. דפים ששייכים לאזור שאינו ניתן לשיתוף (VM_SHARE כבוי) וניתן לכתיבה (VM_MAY_WRITE דלוק) מסומנים בטבלת הדפים של האב והבן כדפים לקריאה בלבד (ביט r/rw כבוי) אם דף משותף נמצא בזיכרון, מוגדל מונה השיתוף במסגרת (count). עבור דף ממופה אנונימי שנמצא בדיסק, מוגדל מונה השיתוף במגירה. פרטים בתרגול הבא (c) ארז חדד 2003 תרגול 12 – ניהול זיכרון ב-Linux: המשך

15 COW: טיפול ב-page fault
המערכת קובעת אם לשכפל את הדף לפי ערך count: אם count > 1, הדף משוכפל לעותק חדש במסגרת מוקצית אחרת במסגרת הישנה מבוצע count-- במסגרת החדשה מוצב count = 1 בעותק החדש מאופשרת הכתיבה אחרת (count == 1), הגרעין פשוט מאפשר כתיבה בדף (c) ארז חדד 2003 תרגול 12 – ניהול זיכרון ב-Linux: המשך

16 טיפול ב-TLB ב-Linux Translation Lookaside Buffer (TLB): מטמון (cache) הצמוד למעבד מכיל כניסות בטבלת הדפים, על-מנת לחסוך תרגומים חוזרים של אותה כתובת ליניארית לכתובת פיזית חוסך גישות לזיכרון (כמספר הרמות בהיררכיה) לצורך תרגום גרעין Linux פוסל כניסות ב-TLB כאשר מתבצע עדכון של רשומה בטבלת הדפים, אשר מופיעה גם ב-TLB למשל בטעינת או בפינוי דף בכל החלפת הקשר מתבצעת פסילה (invalidation) אוטומטית של תוכן ה-TLB. למעשה, בכל טעינת ערך חדש ל-cr3 (c) ארז חדד 2003 תרגול 12 – ניהול זיכרון ב-Linux: המשך

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

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

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

20 טיפול ב-Page Fault ב-Linux
גישה לדף שאינו נמצא בזיכרון ביט present בכניסה המתאימה בטבלת הדפים כבוי גישה לא חוקית (שלא לפי ההרשאות בטבלת הדפים) לדף שנמצא בזיכרון למשל: ניסיון כתיבה לדף שמותר לקריאה בלבד על הגרעין לנתח את נסיבות החריגה ולהחליט אם היא חוקית וכיצד לטפל בה כתיבה לדף שמותר לקריאה בלבד עשויה להיות חוקית, למשל ב-COW גישה לדף שאינו נמצא בזיכרון ואינו בתוך אזורי הזיכרון אינה חוקית שגרת הטיפול בחריגה נקראת do_page_fault() ומוגדרת בקובץ הגרעין arch/i386/mm/fault.c החומרה מעבירה לשגרת הטיפול קוד שגיאה של 3 ביטים הנשמר במחסנית: ביט 0 כבוי: גישה לדף שאינו בזיכרון (present == 0). אחרת, גישה לא חוקית לדף בזיכרון ביט 1 כבוי: הגישה הייתה לקריאה או לביצוע קוד. אחרת, הגישה הייתה לכתיבה ביט 2 כבוי: הגישה כשהמעבד ב-kernel mode. אחרת, הגישה ב-user mode ערך הכתובת הוירטואלית שגרמה לחריגה נשמר ברגיסטר cr2 מנגנון הטיפול בחריגות Page Fault הינו חלק מרכזי במנגנון הזיכרון הוירטואלי בשקפים הבאים נציג מקרים חשובים של טיפול ב-Page Fault כיצד הם מאובחנים ומטופלים (c) ארז חדד 2003 תרגול 12 – ניהול זיכרון ב-Linux: המשך

21 עדכון טבלאות של דפי הגרעין
אם הגישה לכתובת בגרעין (מעל TASK_SIZE) בדף לא קיים, במצב kernel mode (ביטים 0 ו-2 כבויים): הגרעין הקצה לעצמו דפים ועדכן רק את הטבלאות המרכזיות שלו, ה-kernel master page global directory צריך לקשר את כל רמות ההיררכיה החסרות (מה-PGD ומטה) בטבלת מרחב הזיכרון הנוכחי, לאלה שבטבלאות הגרעין אם אין אובייקטים מתאימים באחת הרמות בטבלה המרכזית של הגרעין, הגישה שגויה הודעת תקלה והשבתת המערכת (kernel oops) מעדכן את טבלאות הדפים של מרחבי זיכרון של תהליכי משתמש לגבי דפים שבשימוש הגרעין אם הגרעין משחרר דפים (ומעדכן את הטבלאות שלו בהתאם) השינוי משתקף מיידית בכל המרחבים האחרים: הגרעין לעולם לא משחרר את האובייקטים שבתוך הטבלה הכניסות (מתחת ל-PGD) בטבלת הדפים של מרחב זיכרון מקושרות לאובייקטים שבתוך הטבלה של הגרעין (ולא להעתקים שלהם) (c) ארז חדד 2003 תרגול 12 – ניהול זיכרון ב-Linux: המשך

22 דפדוף לפי דרישה (1) אם הכתובת המבוקשת נמצאת בתוך אחד מאזורי הזיכרון, הגישה בהתאם להרשאות והדף המבוקש אינו בזיכרון, יש לטעון את הדף המבוקש לזיכרון נקרא דפדוף לפי דרישה (Demand Paging) שלוש סיבות לכך שהדף אינו בזיכרון (present == 0): הכניסה מכילה ערך שאינו NULL, כלומר מזהה דף פיזי של דף ממופה אנונימי (נמצא במאגר דפדוף – swap) הכניסה מכילה ערך NULL: דף "קר": ממופה אנונימי שהתהליכים החולקים את מרחב הזיכרון מעולם לא ניגשו אליו או לפחות מעולם לא כתבו אליו דף ממופה לקובץ שפונה/לא נטען במרחב זיכרון זה (c) ארז חדד 2003 תרגול 12 – ניהול זיכרון ב-Linux: המשך

23 דפדוף לפי דרישה (2) במקרה של דף שנמצא בדיסק (ממופה אנונימי או ממופה לקובץ), מבוצעת טעינה של הדף מהדיסק פרטים בתרגול הבא אם הדף "קר" אזי: אם הגישה לכתיבה, מוקצית מסגרת חדשה הממולאת אפסים אם הגישה לקריאה, הכניסה בטבלת הדפים מצביעה על מסגרת של דף קבוע מיוחד, הקרוי ZERO_PAGE, וממולא אפסים. דף זה מסומן read-only, כך שבכתיבה הראשונה לדף הוא ישוכפל לעותק פרטי לפי עיקרון ה-Copy On Write הוספת דף למיפוי הקיים עשויה לכלול גם הוספת כניסות מתאימות בכל הרמות של טבלת הדפים (c) ארז חדד 2003 תרגול 12 – ניהול זיכרון ב-Linux: המשך

24 טיפול בתקלות החריגה נקבעת כתקלה (גישה לא חוקית) אם:
הפעולה (קריאה או כתיבה) לא מורשית לפי הרשאות האזור גישה מקוד משתמש לדפי הגרעין גישה לכתובת בתחום המשתמש, שאיננה בתוך אזור זיכרון לכלל זה יש חריג אחד – כתיבה למחסנית, שעלולה "לגלוש" מעבר לאזור הזיכרון הנוכחי שלה פעולת כתיבה יחידה למחסנית יכולה להגדיל אותה לכל היותר ב-32 בתים (פעולת pusha) לכן, אם הפעולה היא כתיבה בהתאם להרשאות, אזור הזיכרון הוא מחסנית (VM_GROWDOWN דלוק), וכתובת הגישה היא עד 32 בתים מתחת לתחילת אזור המחסנית, מוקצה דף נוסף למחסנית וביצוע הכתיבה מאופשר אם הגישה הייתה מקוד תהליך משתמש, נשלח לתהליך signal מסוג SIGSEGV, לציין "גישה לא חוקית לזיכרון" אם הגישה הייתה מקוד גרעין, מוכרזת תקלת מערכת – kernel oops (c) ארז חדד 2003 תרגול 12 – ניהול זיכרון ב-Linux: המשך

25 דיאגרמה של טיפול ב-Page Fault
User address in a memory region yes no yes no Write access yes no Region is writable bad_area yes no in User Mode no yes Page is present Copy On Write yes no Address is a wrong system call parameter yes Region is readable or executable no * הדיאגרמה לא מדויקת: Demand Paging יכול לקרות גם בכתיבה “Fixup code” (typically send SIGSEGV) Demand paging Send SIGSEGV Kill process and kernel “Oops” (c) ארז חדד 2003 תרגול 12 – ניהול זיכרון ב-Linux: המשך


Download ppt "תרגול 12 – ניהול זיכרון ב-Linux: המשך"

Similar presentations


Ads by Google