370 likes | 616 Views
מערכות הפעלה. תרגול 9 – פסיקות ב- Linux. תוכן התרגול. מבוא לפסיקות ב- Linux פסיקות ב- IA32 : סוגי הפסיקות טבלת הפסיקות ( IDT ) טיפול בפסיקות אתחול ה- IDT ב- Linux טיפול בפסיקות ב- Linux : טיפול בחריגות טיפול בפסיקות חומרה משימות ממתינות סיום הטיפול. מבוא לפסיקות ב- Linux (1).
E N D
מערכות הפעלה תרגול9 – פסיקות ב-Linux
תוכן התרגול • מבוא לפסיקות ב-Linux • פסיקות ב-IA32: • סוגי הפסיקות • טבלת הפסיקות (IDT) • טיפול בפסיקות • אתחול ה-IDT ב-Linux • טיפול בפסיקות ב-Linux: • טיפול בחריגות • טיפול בפסיקות חומרה • משימות ממתינות • סיום הטיפול תרגול9 – פסיקות ב-Linux
מבוא לפסיקות ב-Linux (1) • פסיקה היא אות חשמלי הנשלח למעבד לציון אירוע הדורש את טיפולו המיידי • גורם למעבד להפסיק לבצע את הקוד הנוכחי ולעבור לבצע קוד מיוחד לטיפול בפסיקה • בהרצאה קוד הטיפול בפסיקה נקראInterrupt Service Routine. • ב-Linux יש למונח זה משמעות אחרת, כפי שנראה בהמשך. • התקני חומרה שולחים פסיקות למעבד כדי לקבל טיפול • לדוגמה: לחיצת מקש במקלדת גורמת למקלדת לשלוח פסיקה למעבד על-מנת שיקרא את המידע על המקש שנלחץ תרגול9 – פסיקות ב-Linux
מבוא לפסיקות ב-Linux (2) • המעבד יכול לשלוח לעצמו פסיקות כתוצאה מביצוע קוד כדי לדווח על תקלה בביצוע או בכוונה כדרך לביצוע של הקוד המיועד לטיפול בפסיקה • לדוגמה: פקודת חלוקה ב-0 גורמת לפסיקה • במערכות IA32 יש 256 סוגי פסיקות • ממוספרים 0-255 • מספר הפסיקה נקרא גם וקטור הפסיקה (interrupt vector) • במערכת מרובת מעבדים, מעבדים שולחים פסיקות זה לזה כאמצעי תקשורת • למשל לצורך חלוקת תהליכים ביניהם תרגול9 – פסיקות ב-Linux
מבוא לפסיקות ב-Linux (3) • המעבד בודק אם יש פסיקות ממתינות לטיפול בין ביצוע של כל שתי הוראות עוקבות בקוד • פסיקה אינה קוטעת ביצוע של הוראת מכונה בסיסית • לאחר סיום הטיפול בפסיקה, המעבד יכול להמשיך בביצוע הקוד המקורי (כתובת החזרה נשמרת לפני הקפיצה לשגרת הטיפול) • פסיקה יכולה להשלח למעבד באופן אסינכרוני, בלי קשר למצב המעבד כרגע • קינון (nesting)- פסיקות עשויות להגיע בזמן שהמעבד מטפל בפסיקה קודמת • במערכת מרובת מעבדים, מספר מעבדים יכולים לטפל בפסיקות שונות בו-זמנית תרגול9 – פסיקות ב-Linux
מבוא לפסיקות ב-Linux (4) • הטיפול בפסיקות ב-Linux הוא בתחום אחריותו של הגרעין בלבד • בתגובה על פסיקה מבוצע מסלול בקרה בגרעין (Kernel Control Path) • הגרעין חייב לסנכרן את הגישה למבני הנתונים שלו כדי להגן עליהם מפני מסלולי בקרה מקוננים או מקבילים (במעבדים שונים) • פסיקה מטופלת תמיד בהקשר הביצוע של התהליך הנוכחי • גם אם לתהליך אין קשר לפסיקה שקרתה • טיפול בפסיקה מצריך מעבר ל-Kernel Mode כולל החלפת מחסניות לפי הצורך עבור התהליך הנוכחי • בפסיקה מקוננת אין החלפת מחסניות כי המעבד כבר נמצא ב-Kernel Mode תרגול9 – פסיקות ב-Linux
פסיקות ב-IA32: Interrupts • נשלחות אל המעבד באופן אסינכרוניע"י התקני חומרה חיצוניים • חלקן ניתנות לחסימה (masking) ע"י דגל ה-Interrupt Flag (IF), ברגיסטר הדגלים • פסיקה חסומה אינה מטופלת עד שהחסימה מוסרת • פקודות המכונה cli ו-sti חוסמות ומסירות את החסימה ע"י כיבוי והדלקת הדגל IF • במהלך טיפול בפסיקת חומרה מבוצעת חסימה באופן אוטומטי • פסיקות מסוימות לא ניתנות לחסימה • נקראות NMI – Non-Maskable Interrupts • משמשות לדיווח על בעיות חומרה קריטיות, כגון נפילת מתח תרגול9 – פסיקות ב-Linux
פסיקות ב-IA32: Interrupts (2) • מועברות אל המעבד באמצעות בקר פסיקות מתוכנת נפרד לכל מעבד ([Advanced] Programmable InterruptController – [A]PIC) שעון מעבד IRQ0 APIC מדפסת IRQ7 כרטיס קול IRQ11 דיסק תרגול9 – פסיקות ב-Linux
פסיקות ב-IA32: Interrupts (3) • כל התקן חומרה המבקש לשלוח פסיקה שולח אות IRQ (Interrupt ReQuest) לאחד מקווי הכניסה של בקר הפסיקות אליו ההתקן מחובר • ישנם 16-24 קווי כניסה ממוספרים IRQ0-IRQ15/IRQ23 • אפשר לחבר כמה התקנים לאותו קו (IRQ Sharing) טיפול בפסיקת חומרה מחייב בדיקת כל ההתקנים שיכלו לגרום לה • כאשר בקר הפסיקות מבחין בבקשה מהתקן חומרה, הוא מעביר אות פסיקה למעבד אליו הוא מחובר • מספר הפסיקה הנוצרת עבור קו IRQn ניתן לבחירה. • בדרך כלל, n+32 תרגול9 – פסיקות ב-Linux
פסיקות ב-IA32: exceptions • פסיקות סינכרוניות (חריגות), אשר נוצרות ע"י המעבד כתוצאה מביצוע הוראה אחרונה בקוד ולא ע"י רכיבים חיצוניים • אינן תלויות בדגל הפסיקות • שלושה סוגים של חריגות: • Faults – מציינות תקלות הניתנות לתיקון בביצוע ההוראה האחרונה בקוד • דוגמה: חלוקה ב-0 • כתובת החזרה בסיום הטיפול היא זו של ההוראה שגרמה את התקלה, כדי לבצע אותה מחדש • Traps – נגרמות באופן מכוון ע"י ההוראה האחרונה בקוד, כדי להפעיל את קוד הטיפול בפסיקה • משמש בד"כ בהקשר של debuggers, למשל למימוש breakpoint • כתובת החזרה בסיום הטיפול היא זו שאחרי ההוראה שגרמה ל-trap • Aborts – מציינות תקלות חמורות בביצוע ההוראה האחרונה בקוד • דוגמה: מנגנון בדיקה אוטומטי של הזיכרון יכול לייצר חריגה מסוג Machine Check בעקבות גילוי שיבוש בתכולת הזיכרון תרגול9 – פסיקות ב-Linux
programmed exceptions • חריגות מתוכנתות (programmed exceptions) או פסיקות תוכנה (software interrupts) הן סוג של traps המשמשות לביצוע קריאות מערכת • כפי שכבר ראינו בתרגולים קודמים • כזכור, ב-Linux ההוראה int 0x80 משמשת לקריאות מערכת תרגול9 – פסיקות ב-Linux
Interrupt Descriptor Table (1) • הקישור ב-IA32 בין וקטור פסיקה לשגרת הטיפול בפסיקה מבוצע דרך טבלה הקרויה Interrupt Descriptor Table (IDT) • רגיסטר מיוחד, idtr, מצביע לטבלת ה-IDT • נטען ע"י מערכת ההפעלה בזמן האתחול, בפקודת מכונה lidt • ב-IDT יש רשומה עבור כל וקטור פסיקה • סה"כ 256 רשומות • כל רשומה בגודל 8 בתים • כל רשומה נקראת interrupt descriptor תרגול9 – פסיקות ב-Linux
רשומה מכילה: ציון סוג הרשומה כתובת שגרת הטיפול (segment:offset) DPL– ערך CPLמקסימלי להרצת שגרת הטיפול קוד המשתמש יוכל לגרום לפסיקות מסוימות (קריאות מערכת, debugging), באמצעות פסיקות תוכנה אבל לא פסיקות אחרות (כגון טיפול בדיסק) 3 סוגי רשומות ב-IDT: Interrupt Gate: לפסיקות חומרה דגל ה-IF מכובה אוטומטית בגישה לטיפול דרך רשומה זו Trap Gate: לחריגות אין שינוי ב-IF בגישה לטיפול בפסיקה דרך רשומה זו Task Gate: מגדיר תהליך שיזומן לטיפול בפסיקה סוג זה אינו בשימוש ב-Linux, כי הגרעין מטפל בפסיקות Interrupt Descriptor Table (2) תרגול9 – פסיקות ב-Linux
דוגמאות של רשומות בטבלת ה-IDT להפעלה מקוד משתמש לא להפעלה מקוד משתמש תרגול9 – פסיקות ב-Linux
אתחול ה-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
אתחול ה-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
אתחול ה-IDT ב-Linux (3) • הפונקציה trap_init(), המוגדרת בקובץ הגרעין arch/i386/kernel/traps.c, מכילה חלק מהאתחול המשני של טבלת ה-IDT. להלן חלק מהפונקציה: set_trap_gate(0, ÷_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
טיפול בחריגות ב-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
טיפול בחריגות ב-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
טיפול בפסיקות חומרה ב-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
הפונקציה 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
טיפול ב-APIC טיפול בפסיקות חומרה ב-Linux • כאשר קורית פסיקת חומרה, ה-APIC מודיע על הפסיקה למעבד • "ננעל" ואינו מודיע על פסיקות נוספות עד שיקבל אישור מהמעבד • טכניקה מקובלת (ובפרט ב-Linux) לטיפול ב-APIC בפסיקת חומרה היא לשלוח לו בהקדם אישור להודיע על פסיקות חדשות פרט לכאלה מהסוג המטופל כרגע • באופן זה, ברגע שיאופשרו פסיקות במעבד, ניתן יהיה לטפל "במקביל" (מסלולי בקרה אחרים) בפסיקות חומרה נוספות • מצד שני, נמנע re-entrancy לקוד הטיפול באותו סוג פסיקה • בסיום הטיפול בפסיקה, יש לאפשר ל-APIC להודיע גם על פסיקה מהסוג שטופל תרגול9 – פסיקות ב-Linux
הפונקציה do_IRQ() (2) טיפול בפסיקות חומרה ב-Linux • סדר הפעולות של do_IRQ(): • שליפת סוג הפסיקה המטופלת • שליחת אישור סלקטיבי ל-APIC • הפעלת שגרות טיפול בפסיקה ע"י handle_IRQ_event(…) • ISR – Interrupt Service Routine (פרטים בהמשך) • אפשור סוג הפסיקה המטופלת ב-APIC • ביצוע משימות ממתינות (פרטים בהמשך) תרגול9 – פסיקות ב-Linux
הפעלת ה-ISRs (1) טיפול בפסיקות חומרה ב-Linux • כל ISR מיועד בדרך-כלל לטפל בהתקן מסוים בתגובה לפסיקת חומרה מסוימת: • ISR עבור המקלדת קורא את קוד המקש שנלחץ • ISR עבור כרטיס הרשת קורא נתונים שהתקבלו מהרשת • אחד הפרמטרים ש-Handle_IRQ_event() מקבלת הוא רשימה מקושרת של ISRs עבור טיפול בפסיקה שהתקבלה. • לכל אחד מה-ISRs מצוינים דגלים לגבי אופן פעולתו • השגרה handle_IRQ_event() מפעילה את כל ה-ISRs הרשומים עבור הפסיקה הנוכחית בזה אחר זה. • בדיקת כל ההתקנים שיכלו לגרום לפסיקה תרגול9 – פסיקות ב-Linux
הפעלת ה-ISRs (2) טיפול בפסיקות חומרה ב-Linux • הפונקציה handle_IRQ_event() מבצעת בעיקר: • מאפשרת פסיקות במעבד אלא אם מוגדר שלא בדגל SA_INTERRUPT • בודקת רק את הדגלים של ה-ISR הראשון בשרשרת • מפעילה את ה-ISRs שבשרשרת בזה אחר זה • חוסמת את הפסיקות מחדש בסיום תרגול9 – פסיקות ב-Linux
חלוקת הטיפול בפסיקות חומרה • טיפול בפסיקות חומרה מסוימות עשויות לדרוש זמן רב • כזכור, הפסיקות במעבד חסומות (IF כבוי) בתחילת הטיפול בפסיקת חומרה • ביצוע שגרת טיפול במלואה בפסיקות חסומות עלול לגרום לעיכוב הטיפול בפסיקות אחרות • פגיעה בביצועים • אובדן פסיקות ואובדן נתונים אפשרי (למשל: הקשות מקלדת) • לכן, מנסים לצמצם למינימום את הפעילות הנעשית בפסיקות חסומות תרגול9 – פסיקות ב-Linux
דרגות דחיפות בטיפול בפסיקות חומרה • critical: פעולות שהכרחי לבצען בפסיקות חסומות–פעולות אלו מתבצעות במהירות • דוגמא: עבודה עם ה-APIC • דוגמא: ה-ISR של השעון קורא ומסנכרן ערכי שעוני חומרה במחשב בסדרות של פעולות. פסיקה שתקרה במהלך ה-ISR עלולה ליצור עיכוב שישבש ערכי השעון או יגרום לשני שעונים לצאת מסנכרון • noncritical: פעולות שיש לבצען מיד במסגרת הפסיקה, אך אין צורך בחסימת הפסיקות • דוגמא: העתקת קוד המקש שנלחץ לחוצץ של מערכת ההפעלה ב-ISR של המקלדת: חייב להתבצע במסגרת הפסיקה הנוכחית (כדי לא לאבד את ההקשה הנוכחית) אבל אינו מצריך חסימת פסיקות • noncritical deferred: משימות שיש צורך לבצען בעקבות הפסיקה, אך לא באופן מיידי, אלא כשיסתיים הטיפול המיידי בפסיקה • דוגמא: העברת נתוני הקשות מקלדת שהצטברו בחוצץ מערכת ההפעלה לתהליך המפעיל את המסוף המתאים. • משימות אלה מוכנסות לַמאגר של משימות ממתינות (deferrable functions) לביצוע בעתיד תרגול9 – פסיקות ב-Linux
סוגי משימות ממתינות ב-Linux • Softirq: מנגנון בסיסי, מממש את הסוגים האחרים • פונקציה המתבצעת ב-softirq יכולה להיות מופעלת במקביל משני מעבדים שונים (re-entrant) • Tasklet: המנגנון המומלץ, לשימוש רגיל • קוד של tasklet מוגן מפני הפעלה במקביל ממעבדים שונים ולכן איננו צריך להיות re-entrant • Bottom Halves: tasklets בעדיפות גבוהה • כל ה-bottom halves מהווים קטע קריטי יחיד, כלומר, שני bottom halves (אפילו עם קוד שונה) לא מתבצעים במקביל ממעבדים שונים • פגיעה חמורה במקביליות המערכת – מנגנון שמיועד להעלם תרגול9 – פסיקות ב-Linux
ביצוע משימות ממתינות ב-Linux • בכל מעבד יחיד, המשימות הממתינות מתבצעות באופן סדרתי • אף משימה חדשה לא מתחילה להתבצע לפני סיום הקודמת • בודקים אם יש משימות ממתינות לביצוע בנקודות זמן שונות כגון: • בסיום do_IRQ() (כפי שראינו קודם) • כאשר מופעל חוט גרעין (kernel thread) מיוחד. חוט זה רץ בעדיפות נמוכה בכל מעבד ומבצע בלולאה אינסופית בדיקה של משימות ממתינות וקריאה ל-do_softirq() • ניצול הזמן הפנוי בכל מעבד לטיפול במשימות ממתינות • שם החוט: ksoftirqd_CPUn עבור מעבד מספר n • ניתן לראות חוט זה אם תבצעו פקודת "ps –ax" .... תרגול9 – פסיקות ב-Linux
מחסנית הגרעין בטיפול בפסיקה (1) • בשקף הבא מתואר מבנה מחסנית הגרעין בזמן טיפול בפסיקה כלשהי (חריגה או חומרה) ב-Linux • סדר שמירת האיברים אחיד וקבוע בכל צורות הטיפול • כל האיברים נשמרים כשדות של 32 ביט, כולל תכולת segment registers • באופן זה ניתן ל"קפל" את מחסנית הגרעין באותה צורה בעת חזרה מטיפול בכל סוג פסיקה שהוא • קיפול המחסנית מבוצע ע"י המאקרו RESTORE_ALL, הנקרא מתוך קוד הסיום של כל שגרת טיפול בכל סוג פסיקה תרגול9 – פסיקות ב-Linux
מחסנית הגרעין בטיפול בפסיקה (3) • החלק הגבוה של המחסנית (שמירת ss:esp, eflags ו-cs:eip) נשמר באופן אוטומטי ע"י המעבד • ss:esp נשמר רק אם הטיפול בפסיקה כרוך בהחלפת מחסניות • שאר האיברים מוכנסים למחסנית מייד בתחילת שגרת הפסיקה • תחילה נשמר האיבר הקרוי orig_eax, שהוא "שדה בקרה" המכיל מידע רלוונטי לפי סוג הטיפול, כמופיע בטבלה • בטיפול בפסיקת חומרה וקריאות מערכת, המאקרו SAVE_ALL שומר את ערכי שאר הרגיסטרים, כדי לשחזרם בסיום הפסיקה • בטיפול בחריגה, מבוצעת שמירת שאר ערכי הרגיסטרים ע"י השגרה error_code תרגול9 – פסיקות ב-Linux
המאקרו RESTORE_ALL: popl %ebx .. popl %es addl 4, %esp iret כל שגרת טיפול בפסיקה יכולה להוסיף איברים למחסנית מעבר למבנה זה במהלך פעולתה, אך היא מחויבת לקפל את האיברים הנוספים בעצמה לפני הקריאה ל-RESTORE_ALL למשל: שגרת טיפול בחריגה מעבירה לשגרת הטיפול הפנימית שלה, הכתובה ב-C, פרמטרים במחסנית. פרמטרים אלו מקופלים בחזרה מהשגרה הפנימית לפני הקריאה ל-RESTORE_ALL מחסנית הגרעין בטיפול בפסיקה (4) קיפול ושחזור ערכי הרגיסטרים מלפני הפסיקה קיפול orig_eax קיפול שאר האיברים וחזרה תרגול9 – פסיקות ב-Linux
החלפת הקשר בזמן טיפול בפסיקות • לעיתים, שגרת הטיפול בפסיקה מגיעה למסקנה שיש לבצע החלפת הקשר • למשל, טיפול בפסיקת שעון מגלה כי נגמר פרק הזמן המוקצב לתהליך • או אולי הפסיקה היא קריאת מערכת שמעבירה את התהליך למצב המתנה • ב-Linux לא ניתן לבצע החלפת הקשר בזמן טיפול בפסיקה אסינכרונית • במקום זאת, רק מסמנים כי נדרשת החלפת הקשר באמצעות הדלקת הדגל need_resched במתאר התהליך • בסיום הטיפול בפסיקה, לפני החזרה ל-User Mode, בודקים אם צריך להחליף הקשר • באופן דומה, גם הבדיקה אם לתהליך הגיע signal מתבצעת רק לפני החזרה ל-User Mode תרגול9 – פסיקות ב-Linux
סיום טיפול בפסיקות (1) • כשטיפול בפסיקה מסתיים, יש כאמור לשחזר את ערכי הרגיסטרים מלפני הפסיקה, לבצע iretולחזור לתהליך שבזמן פעילותו התרחשה הפסיקה • אבל, לפני כן, יש לבצע מספר בדיקות • האם הפסיקה מקוננת – אם כן, לא מבצעים את הבדיקות הבאות ומסיימים • האם צריך להחליף הקשר – אם כן, קוראים ל-schedule() • האם יש signals ממתינים - יש לטפל בהם תחילה (פונקציה do_signal()) • סוף שגרת הטיפול הוא בקריאה לקוד הבא: • ל- ret_from_exception- עבור סיום טיפול בחריגה • ל-ret_from_intr – עבור סיום טיפול בפסיקת חומרה • ל-ret_from_sys_call – עבור סיום טיפול בקריאת מערכת • שגרות סיום אלו מבצעות את הבדיקות הנחוצות, ורק אז קוראות ל-RESTORE_ALL לסיום, כמתואר בתרשים בשקף הבא תרגול9 – פסיקות ב-Linux
סיום טיפול בפסיקות (2) ret_from_exception: ret_from_intr: ret_from_sys_call: פסיקה מקוננת? לא האם יש צורך להחליף הקשר? schedule() כן כן לא האם יש signals ממתינים? לא RESTORE_ALL do_signal() כן תרגול9 – פסיקות ב-Linux