Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "מערכות הפעלה תרגול9 – פסיקות ב-Linux."— Presentation transcript:

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

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

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

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

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

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

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

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

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

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

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

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

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

14 דוגמאות של רשומות בטבלת ה-IDT
DPL כתובת שגרת הטיפול seg:offs סוג הרשומה (gate) כניסה divide_error trap 3 int3 general_protection 13 timer interrupt 32 disk 43 system_call 128 להפעלה מקוד משתמש לא להפעלה מקוד משתמש (c) ארז חדד 2003 תרגול9 – פסיקות ב-Linux

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

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

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

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

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

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

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

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

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

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

31 מצביע למחסנית התהליך ב-User Mode (אם התבצעה החלפת מחסניות) ss
חריגה פסיקת חומרה קריאת מערכת האיבר במחסנית מצביע למחסנית התהליך ב-User Mode (אם התבצעה החלפת מחסניות) ss esp ערך רגיסטר הדגלים eflags כתובת חזרה לאחר הפסיקה cs eip hardware error code (או 0 אם אין) הופך ל: (-1) מספר הפסיקה פחות 256 מספר קריאת המערכת orig_eax ערכי הרגיסטרים מלפני הפסיקה כפי שנשמרו ע"י השגרה error_code ערכי הרגיסטרים מלפני הפסיקה כפי שנשמרו ע"י המאקרו SAVE_ALL (עבור קריאות מערכת, שדה eax מכיל בסיום את הערך המוחזר) es ds eax ebp edi esi edx ecx ebx (c) ארז חדד 2003 תרגול9 – פסיקות ב-Linux

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

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

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

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

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


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

Similar presentations


Ads by Google