1 / 36

מערכות הפעלה

מערכות הפעלה. תרגול 9 – פסיקות ב- Linux. תוכן התרגול. מבוא לפסיקות ב- Linux פסיקות ב- IA32 : סוגי הפסיקות טבלת הפסיקות ( IDT ) טיפול בפסיקות אתחול ה- IDT ב- Linux טיפול בפסיקות ב- Linux : טיפול בחריגות טיפול בפסיקות חומרה משימות ממתינות סיום הטיפול. מבוא לפסיקות ב- Linux (1).

mahsa
Télécharger la présentation

מערכות הפעלה

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. מערכות הפעלה תרגול9 – פסיקות ב-Linux

  2. תוכן התרגול • מבוא לפסיקות ב-Linux • פסיקות ב-IA32: • סוגי הפסיקות • טבלת הפסיקות (IDT) • טיפול בפסיקות • אתחול ה-IDT ב-Linux • טיפול בפסיקות ב-Linux: • טיפול בחריגות • טיפול בפסיקות חומרה • משימות ממתינות • סיום הטיפול תרגול9 – פסיקות ב-Linux

  3. מבוא לפסיקות ב-Linux (1) • פסיקה היא אות חשמלי הנשלח למעבד לציון אירוע הדורש את טיפולו המיידי • גורם למעבד להפסיק לבצע את הקוד הנוכחי ולעבור לבצע קוד מיוחד לטיפול בפסיקה • בהרצאה קוד הטיפול בפסיקה נקראInterrupt Service Routine. • ב-Linux יש למונח זה משמעות אחרת, כפי שנראה בהמשך. • התקני חומרה שולחים פסיקות למעבד כדי לקבל טיפול • לדוגמה: לחיצת מקש במקלדת גורמת למקלדת לשלוח פסיקה למעבד על-מנת שיקרא את המידע על המקש שנלחץ תרגול9 – פסיקות ב-Linux

  4. מבוא לפסיקות ב-Linux (2) • המעבד יכול לשלוח לעצמו פסיקות כתוצאה מביצוע קוד כדי לדווח על תקלה בביצוע או בכוונה כדרך לביצוע של הקוד המיועד לטיפול בפסיקה • לדוגמה: פקודת חלוקה ב-0 גורמת לפסיקה • במערכות IA32 יש 256 סוגי פסיקות • ממוספרים 0-255 • מספר הפסיקה נקרא גם וקטור הפסיקה (interrupt vector) • במערכת מרובת מעבדים, מעבדים שולחים פסיקות זה לזה כאמצעי תקשורת • למשל לצורך חלוקת תהליכים ביניהם תרגול9 – פסיקות ב-Linux

  5. מבוא לפסיקות ב-Linux (3) • המעבד בודק אם יש פסיקות ממתינות לטיפול בין ביצוע של כל שתי הוראות עוקבות בקוד • פסיקה אינה קוטעת ביצוע של הוראת מכונה בסיסית • לאחר סיום הטיפול בפסיקה, המעבד יכול להמשיך בביצוע הקוד המקורי (כתובת החזרה נשמרת לפני הקפיצה לשגרת הטיפול) • פסיקה יכולה להשלח למעבד באופן אסינכרוני, בלי קשר למצב המעבד כרגע • קינון (nesting)- פסיקות עשויות להגיע בזמן שהמעבד מטפל בפסיקה קודמת • במערכת מרובת מעבדים, מספר מעבדים יכולים לטפל בפסיקות שונות בו-זמנית תרגול9 – פסיקות ב-Linux

  6. מבוא לפסיקות ב-Linux (4) • הטיפול בפסיקות ב-Linux הוא בתחום אחריותו של הגרעין בלבד • בתגובה על פסיקה מבוצע מסלול בקרה בגרעין (Kernel Control Path) • הגרעין חייב לסנכרן את הגישה למבני הנתונים שלו כדי להגן עליהם מפני מסלולי בקרה מקוננים או מקבילים (במעבדים שונים) • פסיקה מטופלת תמיד בהקשר הביצוע של התהליך הנוכחי • גם אם לתהליך אין קשר לפסיקה שקרתה • טיפול בפסיקה מצריך מעבר ל-Kernel Mode כולל החלפת מחסניות לפי הצורך עבור התהליך הנוכחי • בפסיקה מקוננת אין החלפת מחסניות כי המעבד כבר נמצא ב-Kernel Mode תרגול9 – פסיקות ב-Linux

  7. פסיקות ב-IA32: Interrupts • נשלחות אל המעבד באופן אסינכרוניע"י התקני חומרה חיצוניים • חלקן ניתנות לחסימה (masking) ע"י דגל ה-Interrupt Flag (IF), ברגיסטר הדגלים • פסיקה חסומה אינה מטופלת עד שהחסימה מוסרת • פקודות המכונה cli ו-sti חוסמות ומסירות את החסימה ע"י כיבוי והדלקת הדגל IF • במהלך טיפול בפסיקת חומרה מבוצעת חסימה באופן אוטומטי • פסיקות מסוימות לא ניתנות לחסימה • נקראות NMI – Non-Maskable Interrupts • משמשות לדיווח על בעיות חומרה קריטיות, כגון נפילת מתח תרגול9 – פסיקות ב-Linux

  8. פסיקות ב-IA32: Interrupts (2) • מועברות אל המעבד באמצעות בקר פסיקות מתוכנת נפרד לכל מעבד ([Advanced] Programmable InterruptController – [A]PIC) שעון מעבד IRQ0 APIC מדפסת IRQ7 כרטיס קול IRQ11 דיסק תרגול9 – פסיקות ב-Linux

  9. פסיקות ב-IA32: Interrupts (3) • כל התקן חומרה המבקש לשלוח פסיקה שולח אות IRQ (Interrupt ReQuest) לאחד מקווי הכניסה של בקר הפסיקות אליו ההתקן מחובר • ישנם 16-24 קווי כניסה ממוספרים IRQ0-IRQ15/IRQ23 • אפשר לחבר כמה התקנים לאותו קו (IRQ Sharing)  טיפול בפסיקת חומרה מחייב בדיקת כל ההתקנים שיכלו לגרום לה • כאשר בקר הפסיקות מבחין בבקשה מהתקן חומרה, הוא מעביר אות פסיקה למעבד אליו הוא מחובר • מספר הפסיקה הנוצרת עבור קו IRQn ניתן לבחירה. • בדרך כלל, n+32 תרגול9 – פסיקות ב-Linux

  10. פסיקות ב-IA32: exceptions • פסיקות סינכרוניות (חריגות), אשר נוצרות ע"י המעבד כתוצאה מביצוע הוראה אחרונה בקוד ולא ע"י רכיבים חיצוניים • אינן תלויות בדגל הפסיקות • שלושה סוגים של חריגות: • Faults – מציינות תקלות הניתנות לתיקון בביצוע ההוראה האחרונה בקוד • דוגמה: חלוקה ב-0 • כתובת החזרה בסיום הטיפול היא זו של ההוראה שגרמה את התקלה, כדי לבצע אותה מחדש • Traps – נגרמות באופן מכוון ע"י ההוראה האחרונה בקוד, כדי להפעיל את קוד הטיפול בפסיקה • משמש בד"כ בהקשר של debuggers, למשל למימוש breakpoint • כתובת החזרה בסיום הטיפול היא זו שאחרי ההוראה שגרמה ל-trap • Aborts – מציינות תקלות חמורות בביצוע ההוראה האחרונה בקוד • דוגמה: מנגנון בדיקה אוטומטי של הזיכרון יכול לייצר חריגה מסוג Machine Check בעקבות גילוי שיבוש בתכולת הזיכרון תרגול9 – פסיקות ב-Linux

  11. programmed exceptions • חריגות מתוכנתות (programmed exceptions) או פסיקות תוכנה (software interrupts) הן סוג של traps המשמשות לביצוע קריאות מערכת • כפי שכבר ראינו בתרגולים קודמים • כזכור, ב-Linux ההוראה int 0x80 משמשת לקריאות מערכת תרגול9 – פסיקות ב-Linux

  12. Interrupt Descriptor Table (1) • הקישור ב-IA32 בין וקטור פסיקה לשגרת הטיפול בפסיקה מבוצע דרך טבלה הקרויה Interrupt Descriptor Table (IDT) • רגיסטר מיוחד, idtr, מצביע לטבלת ה-IDT • נטען ע"י מערכת ההפעלה בזמן האתחול, בפקודת מכונה lidt • ב-IDT יש רשומה עבור כל וקטור פסיקה • סה"כ 256 רשומות • כל רשומה בגודל 8 בתים • כל רשומה נקראת interrupt descriptor תרגול9 – פסיקות ב-Linux

  13. רשומה מכילה: ציון סוג הרשומה כתובת שגרת הטיפול (segment:offset) DPL– ערך CPLמקסימלי להרצת שגרת הטיפול קוד המשתמש יוכל לגרום לפסיקות מסוימות (קריאות מערכת, debugging), באמצעות פסיקות תוכנה אבל לא פסיקות אחרות (כגון טיפול בדיסק) 3 סוגי רשומות ב-IDT: Interrupt Gate: לפסיקות חומרה דגל ה-IF מכובה אוטומטית בגישה לטיפול דרך רשומה זו Trap Gate: לחריגות אין שינוי ב-IF בגישה לטיפול בפסיקה דרך רשומה זו Task Gate: מגדיר תהליך שיזומן לטיפול בפסיקה סוג זה אינו בשימוש ב-Linux, כי הגרעין מטפל בפסיקות Interrupt Descriptor Table (2) תרגול9 – פסיקות ב-Linux

  14. דוגמאות של רשומות בטבלת ה-IDT להפעלה מקוד משתמש לא להפעלה מקוד משתמש תרגול9 – פסיקות ב-Linux

  15. אתחול ה-IDT ב-Linux (1) • טבלת ה-IDT מאותחלת במקור ע"י ה-BIOS • Linux מחליפה את כל הטבלה, בזמן הטעינה. • ראשית, מופעלת הפונקציה setup_idt() המאתחלת את כל הרשומות בטבלה לערכי ברירת מחדל הבאים: • Interrupt Gate • כתובת השגרה ignore_int() • שגרה זו מדפיסה הודעת "Unknown Interrupt" על המסך בתגובה לפסיקה – לא אמורה להיות מופעלת לעולם (אחרת באג או בעית חומרה) • DPL=0 • setup_idt() ו-ignore_int() מוגדרות באסמבלר בקובץ הגרעין arch/i386/kernel/head.S • לאחר האתחול, מעבר נוסף על ה-IDT מעדכן את הכניסות המתאימות לטיפול בחריגות ובפסיקות מהחומרה המותקנת • במהלך פעולת המערכת ייתכן עדכון נוסף של הטבלה עקב התקנת drivers תרגול9 – פסיקות ב-Linux

  16. אתחול ה-IDT ב-Linux (2) • עדכון כניסה משתמש באחת הפונקציות הבאות, המוגדרות בקובץ הגרעין arch/i386/kernel/traps.c: • set_intr_gate(n, addr) • מיועדת לטיפול בפסיקות חומרה • כותבת interrupt gateבכניסה nבטבלה, עם DPL=0 וכתובת שגרת טיפול kcs:addr (kcs מציין את ה-code segment של הגרעין) • set_system_gate(n, addr) • כותבת system gate (trap gate לשימוש תהליכי משתמש) בכניסה n בטבלה • כתובת kcs:addr, DPL=3 • שגרות טיפול בפסיקה הנקבעות באופן זה נגישות לכל תוכנית משתמש • משמשת לפסיקות debuggingולפסיקה 128 (0x80) המיועדת לקריאות מערכת • set_trap_gate(n,addr) • כותבת trap gateבכניסה nבטבלה, עם כתובת kcs:addr ו-DPL=0 • משמשת לטיפול בחריגות תרגול9 – פסיקות ב-Linux

  17. אתחול ה-IDT ב-Linux (3) • הפונקציה trap_init(), המוגדרת בקובץ הגרעין arch/i386/kernel/traps.c, מכילה חלק מהאתחול המשני של טבלת ה-IDT. להלן חלק מהפונקציה: set_trap_gate(0, &divide_error); ... set_system_gate(4, &overflow); ... set_trap_gate(6, &invalid_op); ... set_trap_gate(13, &general_protection); set_intr_gate(14, &page_fault); set_trap_gate(16, &coprocessor_error); ... set_system_gate(128, &system_call); תרגול9 – פסיקות ב-Linux

  18. טיפול בחריגות ב-Linux (1) • עבור חלק מהחריגות נדחף למחסנית קוד שגיאה - hardware error code • למשל, עבור חריגה מתמטית נשמר סוג השגיאה • קוד טיפוסי של שגרת טיפול בחריגה: handler_name: pushl $0 /* only if no handler error code */ pushl $do_handler_name /* C handler function */ jmp error_code • השגרה error_code שולפת את שני הערכים שנדחפו למחסנית לעיל ודוחפת למחסנית (-1) ואחריו כל הרגיסטרים מלפני הפסיקה (בדומה ל-SAVE_ALL) • בהמשך, error_code תבצע קריאה ל-do_handler_name עם הפרמטרים hardware error code, ומצביע לתחילת הרגיסטרים (מסוג struct pt_regs *). • לאחר החזרה מהשגרה הפנימית, error_code מורידה את הפרמטרים של השגרה הפנימית מהמחסנית וקוראת ל-ret_from_exception לסיום הטיפול תרגול9 – פסיקות ב-Linux

  19. טיפול בחריגות ב-Linux (2) • מרבית שגרות הטיפול הפנימי בחריגות שולחות signal לתהליך הנוכחי כדי שיטפל בתקלה שנגרמה • סוג ה-signal נקבע על-פי סוג החריגה המטופלת • לדוגמה: עבור floating point exception נשלח SIGFPE • שליחת ה-signal באמצעות פונקציה כדוגמת force_sig() המוגדרת בקובץ הגרעין kernel/signal.c: force_sig(sig_number, current); • לפני החזרה ל-User Mode, התהליך יגלה שיש signalהממתין לו, ויפנה לטפל ב-signal זה. תרגול9 – פסיקות ב-Linux

  20. טיפול בפסיקות חומרה ב-Linux • כל כניסה של פסיקת חומרה מצביעה לקוד מהצורה הבאה: IRQn_interrupt: pushl $n-256 jmp common_interrupt • הטיפול בכל פסיקות החומרה עובר דרך מנגנון מרכזי אחד המתחיל ב-common_interrupt, כאשר האבחנה בין הפסיקות היא באמצעות הערך הנשמר במחסנית מיד בתחילת שגרת הפסיקה • השגרה common_interrupt: common_interrupt: SAVE_ALL /* save registers */ call do_IRQ /* handle interrupt */ jmp ret_from_intr /* resume execution */ תרגול9 – פסיקות ב-Linux

  21. הפונקציה do_IRQ() טיפול בפסיקות חומרה ב-Linux • הפונקציה do_IRQ(), הכתובה ב-C, מבצעת את הטיפול בפסיקה ברמת תפעול ה-APIC וקוראת לפונקציה handle_IRQ_event() להפעלת ה-ISRs • קובץ גרעין arch/i386/kernel/irq.c • do_IRQ() מוגדרת כדלקמן: unsigned int do_IRQ(struct pt_regs regs); • הפרמטר regs מאפשר לפונקציה לגשת לרגיסטרים השמורים במחסנית, ובפרט גם לערך הבקרה המכיל את מספר הפסיקה (השדה הקרוי orig_eax) • הערך המוחזר אינו בשימוש מתוך common_interrupt תרגול9 – פסיקות ב-Linux

  22. טיפול ב-APIC טיפול בפסיקות חומרה ב-Linux • כאשר קורית פסיקת חומרה, ה-APIC מודיע על הפסיקה למעבד • "ננעל" ואינו מודיע על פסיקות נוספות עד שיקבל אישור מהמעבד • טכניקה מקובלת (ובפרט ב-Linux) לטיפול ב-APIC בפסיקת חומרה היא לשלוח לו בהקדם אישור להודיע על פסיקות חדשות פרט לכאלה מהסוג המטופל כרגע • באופן זה, ברגע שיאופשרו פסיקות במעבד, ניתן יהיה לטפל "במקביל" (מסלולי בקרה אחרים) בפסיקות חומרה נוספות • מצד שני, נמנע re-entrancy לקוד הטיפול באותו סוג פסיקה • בסיום הטיפול בפסיקה, יש לאפשר ל-APIC להודיע גם על פסיקה מהסוג שטופל תרגול9 – פסיקות ב-Linux

  23. הפונקציה do_IRQ() (2) טיפול בפסיקות חומרה ב-Linux • סדר הפעולות של do_IRQ(): • שליפת סוג הפסיקה המטופלת • שליחת אישור סלקטיבי ל-APIC • הפעלת שגרות טיפול בפסיקה ע"י handle_IRQ_event(…) • ISR – Interrupt Service Routine (פרטים בהמשך) • אפשור סוג הפסיקה המטופלת ב-APIC • ביצוע משימות ממתינות (פרטים בהמשך) תרגול9 – פסיקות ב-Linux

  24. הפעלת ה-ISRs (1) טיפול בפסיקות חומרה ב-Linux • כל ISR מיועד בדרך-כלל לטפל בהתקן מסוים בתגובה לפסיקת חומרה מסוימת: • ISR עבור המקלדת קורא את קוד המקש שנלחץ • ISR עבור כרטיס הרשת קורא נתונים שהתקבלו מהרשת • אחד הפרמטרים ש-Handle_IRQ_event() מקבלת הוא רשימה מקושרת של ISRs עבור טיפול בפסיקה שהתקבלה. • לכל אחד מה-ISRs מצוינים דגלים לגבי אופן פעולתו • השגרה handle_IRQ_event() מפעילה את כל ה-ISRs הרשומים עבור הפסיקה הנוכחית בזה אחר זה. • בדיקת כל ההתקנים שיכלו לגרום לפסיקה תרגול9 – פסיקות ב-Linux

  25. הפעלת ה-ISRs (2) טיפול בפסיקות חומרה ב-Linux • הפונקציה handle_IRQ_event() מבצעת בעיקר: • מאפשרת פסיקות במעבד אלא אם מוגדר שלא בדגל SA_INTERRUPT • בודקת רק את הדגלים של ה-ISR הראשון בשרשרת • מפעילה את ה-ISRs שבשרשרת בזה אחר זה • חוסמת את הפסיקות מחדש בסיום תרגול9 – פסיקות ב-Linux

  26. חלוקת הטיפול בפסיקות חומרה • טיפול בפסיקות חומרה מסוימות עשויות לדרוש זמן רב • כזכור, הפסיקות במעבד חסומות (IF כבוי) בתחילת הטיפול בפסיקת חומרה • ביצוע שגרת טיפול במלואה בפסיקות חסומות עלול לגרום לעיכוב הטיפול בפסיקות אחרות • פגיעה בביצועים • אובדן פסיקות ואובדן נתונים אפשרי (למשל: הקשות מקלדת) • לכן, מנסים לצמצם למינימום את הפעילות הנעשית בפסיקות חסומות תרגול9 – פסיקות ב-Linux

  27. דרגות דחיפות בטיפול בפסיקות חומרה • critical: פעולות שהכרחי לבצען בפסיקות חסומות–פעולות אלו מתבצעות במהירות • דוגמא: עבודה עם ה-APIC • דוגמא: ה-ISR של השעון קורא ומסנכרן ערכי שעוני חומרה במחשב בסדרות של פעולות. פסיקה שתקרה במהלך ה-ISR עלולה ליצור עיכוב שישבש ערכי השעון או יגרום לשני שעונים לצאת מסנכרון • noncritical: פעולות שיש לבצען מיד במסגרת הפסיקה, אך אין צורך בחסימת הפסיקות • דוגמא: העתקת קוד המקש שנלחץ לחוצץ של מערכת ההפעלה ב-ISR של המקלדת: חייב להתבצע במסגרת הפסיקה הנוכחית (כדי לא לאבד את ההקשה הנוכחית) אבל אינו מצריך חסימת פסיקות • noncritical deferred: משימות שיש צורך לבצען בעקבות הפסיקה, אך לא באופן מיידי, אלא כשיסתיים הטיפול המיידי בפסיקה • דוגמא: העברת נתוני הקשות מקלדת שהצטברו בחוצץ מערכת ההפעלה לתהליך המפעיל את המסוף המתאים. • משימות אלה מוכנסות לַמאגר של משימות ממתינות (deferrable functions) לביצוע בעתיד תרגול9 – פסיקות ב-Linux

  28. סוגי משימות ממתינות ב-Linux • Softirq: מנגנון בסיסי, מממש את הסוגים האחרים • פונקציה המתבצעת ב-softirq יכולה להיות מופעלת במקביל משני מעבדים שונים (re-entrant) • Tasklet: המנגנון המומלץ, לשימוש רגיל • קוד של tasklet מוגן מפני הפעלה במקביל ממעבדים שונים ולכן איננו צריך להיות re-entrant • Bottom Halves: tasklets בעדיפות גבוהה • כל ה-bottom halves מהווים קטע קריטי יחיד, כלומר, שני bottom halves (אפילו עם קוד שונה) לא מתבצעים במקביל ממעבדים שונים • פגיעה חמורה במקביליות המערכת – מנגנון שמיועד להעלם תרגול9 – פסיקות ב-Linux

  29. ביצוע משימות ממתינות ב-Linux • בכל מעבד יחיד, המשימות הממתינות מתבצעות באופן סדרתי • אף משימה חדשה לא מתחילה להתבצע לפני סיום הקודמת • בודקים אם יש משימות ממתינות לביצוע בנקודות זמן שונות כגון: • בסיום do_IRQ() (כפי שראינו קודם) • כאשר מופעל חוט גרעין (kernel thread) מיוחד. חוט זה רץ בעדיפות נמוכה בכל מעבד ומבצע בלולאה אינסופית בדיקה של משימות ממתינות וקריאה ל-do_softirq() • ניצול הזמן הפנוי בכל מעבד לטיפול במשימות ממתינות • שם החוט: ksoftirqd_CPUn עבור מעבד מספר n • ניתן לראות חוט זה אם תבצעו פקודת "ps –ax" .... תרגול9 – פסיקות ב-Linux

  30. מחסנית הגרעין בטיפול בפסיקה (1) • בשקף הבא מתואר מבנה מחסנית הגרעין בזמן טיפול בפסיקה כלשהי (חריגה או חומרה) ב-Linux • סדר שמירת האיברים אחיד וקבוע בכל צורות הטיפול • כל האיברים נשמרים כשדות של 32 ביט, כולל תכולת segment registers • באופן זה ניתן ל"קפל" את מחסנית הגרעין באותה צורה בעת חזרה מטיפול בכל סוג פסיקה שהוא • קיפול המחסנית מבוצע ע"י המאקרו RESTORE_ALL, הנקרא מתוך קוד הסיום של כל שגרת טיפול בכל סוג פסיקה תרגול9 – פסיקות ב-Linux

  31. תרגול9 – פסיקות ב-Linux

  32. מחסנית הגרעין בטיפול בפסיקה (3) • החלק הגבוה של המחסנית (שמירת ss:esp, eflags ו-cs:eip) נשמר באופן אוטומטי ע"י המעבד • ss:esp נשמר רק אם הטיפול בפסיקה כרוך בהחלפת מחסניות • שאר האיברים מוכנסים למחסנית מייד בתחילת שגרת הפסיקה • תחילה נשמר האיבר הקרוי orig_eax, שהוא "שדה בקרה" המכיל מידע רלוונטי לפי סוג הטיפול, כמופיע בטבלה • בטיפול בפסיקת חומרה וקריאות מערכת, המאקרו SAVE_ALL שומר את ערכי שאר הרגיסטרים, כדי לשחזרם בסיום הפסיקה • בטיפול בחריגה, מבוצעת שמירת שאר ערכי הרגיסטרים ע"י השגרה error_code תרגול9 – פסיקות ב-Linux

  33. המאקרו RESTORE_ALL: popl %ebx .. popl %es addl 4, %esp iret כל שגרת טיפול בפסיקה יכולה להוסיף איברים למחסנית מעבר למבנה זה במהלך פעולתה, אך היא מחויבת לקפל את האיברים הנוספים בעצמה לפני הקריאה ל-RESTORE_ALL למשל: שגרת טיפול בחריגה מעבירה לשגרת הטיפול הפנימית שלה, הכתובה ב-C, פרמטרים במחסנית. פרמטרים אלו מקופלים בחזרה מהשגרה הפנימית לפני הקריאה ל-RESTORE_ALL מחסנית הגרעין בטיפול בפסיקה (4) קיפול ושחזור ערכי הרגיסטרים מלפני הפסיקה קיפול orig_eax קיפול שאר האיברים וחזרה תרגול9 – פסיקות ב-Linux

  34. החלפת הקשר בזמן טיפול בפסיקות • לעיתים, שגרת הטיפול בפסיקה מגיעה למסקנה שיש לבצע החלפת הקשר • למשל, טיפול בפסיקת שעון מגלה כי נגמר פרק הזמן המוקצב לתהליך • או אולי הפסיקה היא קריאת מערכת שמעבירה את התהליך למצב המתנה • ב-Linux לא ניתן לבצע החלפת הקשר בזמן טיפול בפסיקה אסינכרונית • במקום זאת, רק מסמנים כי נדרשת החלפת הקשר באמצעות הדלקת הדגל need_resched במתאר התהליך • בסיום הטיפול בפסיקה, לפני החזרה ל-User Mode, בודקים אם צריך להחליף הקשר • באופן דומה, גם הבדיקה אם לתהליך הגיע signal מתבצעת רק לפני החזרה ל-User Mode תרגול9 – פסיקות ב-Linux

  35. סיום טיפול בפסיקות (1) • כשטיפול בפסיקה מסתיים, יש כאמור לשחזר את ערכי הרגיסטרים מלפני הפסיקה, לבצע iretולחזור לתהליך שבזמן פעילותו התרחשה הפסיקה • אבל, לפני כן, יש לבצע מספר בדיקות • האם הפסיקה מקוננת – אם כן, לא מבצעים את הבדיקות הבאות ומסיימים • האם צריך להחליף הקשר – אם כן, קוראים ל-schedule() • האם יש signals ממתינים - יש לטפל בהם תחילה (פונקציה do_signal()) • סוף שגרת הטיפול הוא בקריאה לקוד הבא: • ל- ret_from_exception- עבור סיום טיפול בחריגה • ל-ret_from_intr – עבור סיום טיפול בפסיקת חומרה • ל-ret_from_sys_call – עבור סיום טיפול בקריאת מערכת • שגרות סיום אלו מבצעות את הבדיקות הנחוצות, ורק אז קוראות ל-RESTORE_ALL לסיום, כמתואר בתרשים בשקף הבא תרגול9 – פסיקות ב-Linux

  36. סיום טיפול בפסיקות (2) ret_from_exception: ret_from_intr: ret_from_sys_call: פסיקה מקוננת? לא האם יש צורך להחליף הקשר? schedule() כן כן לא האם יש signals ממתינים? לא RESTORE_ALL do_signal() כן תרגול9 – פסיקות ב-Linux

More Related