Presentation is loading. Please wait.

Presentation is loading. Please wait.

מערכות הפעלה תרגול 9 – פסיקות ב-Linux. מערכות הפעלה - תרגול 92 (c) ארז חדד 2003 תוכן התרגול מבוא לפסיקות ב-Linux פסיקות ב-IA32:  סוגי הפסיקות  טבלת.

Similar presentations


Presentation on theme: "מערכות הפעלה תרגול 9 – פסיקות ב-Linux. מערכות הפעלה - תרגול 92 (c) ארז חדד 2003 תוכן התרגול מבוא לפסיקות ב-Linux פסיקות ב-IA32:  סוגי הפסיקות  טבלת."— Presentation transcript:

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

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

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

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

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

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

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

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

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

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

11 מערכות הפעלה - תרגול 911 (c) ארז חדד 2003 סוגי פסיקות ב-IA32 (4) פסיקות סינכרוניות – exceptions ("חריגות")  נוצרות ע"י המעבד כתוצאה מביצוע הוראה אחרונה בקוד ולא ע"י רכיבים חיצוניים  לא תלויות בדגל הפסיקות  שלושה סוגים של חריגות: 1. Faults – מציינות תקלות הניתנות לתיקון בביצוע ההוראה האחרונה בקוד  כתובת החזרה בסיום הטיפול היא זו של ההוראה שגרמה את התקלה, כדי שהיא תבוצע מחדש  דוגמה: חלוקה ב-0

12 מערכות הפעלה - תרגול 912 (c) ארז חדד 2003 סוגי פסיקות ב-IA32 (5) 2. Traps – נגרמות באופן מכוון ע"י ההוראה האחרונה בקוד, כדי להפעיל את קוד הטיפול בפסיקה  Traps משמשות בדרך-כלל כדי להודיע ל-debugger על התקדמות בביצוע הקוד המכיל את ה-trap  ההוראה לביצוע בסיום הטיפול היא זו שאחרי ההוראה שגרמה ל- trap  דוגמה: הוראת המכונה int3 יוצרת חריגה שמטרתה להודיע ל- debugger שביצוע הקוד הגיע להוראה הנוכחית 3. Aborts – מציינות תקלות חמורות בביצוע ההוראה האחרונה בקוד  דוגמה: מנגנון בדיקה אוטומטי של הזיכרון יכול לייצר חריגה מסוג Machine Check בעקבות גילוי שיבוש בתכולת הזיכרון

13 מערכות הפעלה - תרגול 913 (c) ארז חדד 2003 סוגי פסיקות ב-IA32 (6)  חריגות מתוכנתות (Programmed Exceptions) או "פסיקות תוכנה" (Software Interrupts) הן סוג מסוים של Traps המשמשות לביצוע קריאות מערכת, כפי שכבר ראינו בתרגולים קודמים כזכור, ב-Linux ההוראה int 0x80 משמשת לקריאות מערכת

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

15 מערכות הפעלה - תרגול 915 (c) ארז חדד 2003 Interrupt Descriptor Table (2) קיימים 3 סוגי רשומות ב-IDT: 1. Interrupt Gate – משמש עבור פסיקות חומרה  דגל ה-IF מכובה אוטומטית בגישה לטיפול דרך רשומה זו 2. Trap Gate – משמש עבור חריגות  אין שינוי ב-IF בגישה לטיפול בפסיקה דרך רשומה זו 3. Task Gate – מאפשר להגדיר תהליך שיזומן לטיפול בפסיקה  סוג זה אינו בשימוש ב-Linux, כי הגרעין מטפל בפסיקות

16 מערכות הפעלה - תרגול 916 (c) ארז חדד 2003 Interrupt Descriptor Table (3) כל רשומה ב-IDT מכילה:  ציון סוג הרשומה  כתובת (segment:offset) של שגרת הטיפול  DPL– ערך CPL מקסימלי הנדרש כדי להריץ את שגרת הטיפול נרצה שקוד המשתמש יוכל, באמצעות פסיקות תוכנה, לגרום לפסיקות מסוימות (קריאות מערכת, debugging) אבל לא יוכל להפעיל שגרות פסיקה המיועדות לדברים אחרים (כגון טיפול בדיסק וכו') לכן, רשומה של וקטור פסיקה המיועדת להפעלה מקוד משתמש תקבל DPL=3, ורשומות שאינן מיועדות לכך תקבלנה DPL=0

17 מערכות הפעלה - תרגול 917 (c) ארז חדד 2003 Interrupt Descriptor Table (4) DPLכתובת שגרת הטיפול seg:offs סוג הרשומה (gate) כניסה 0divide_errortrap0 3int3trap3 0general_protectiontrap13 0timerinterrupt32 0diskinterrupt43 3system_calltrap128 דוגמאות של רשומות בטבלת ה-IDT

18 מערכות הפעלה - תרגול 918 (c) ארז חדד 2003 טיפול בפסיקה ב-IA32 (1) המעבד מוצא את הכניסה המתאימה לוקטור הפסיקה ב- IDT וקורא את הרשומה שבה מבוצעות בדיקות הרשאות:  עבור פסיקות תוכנה בלבד – השוואת ה-CPL עם ה-DPL של הרשומה ב-IDT. אם ה-CPL גבוה יותר, נגרמת חריגה – General Protection Fault הרעיון – למנוע מקוד משתמש להריץ שגרות טיפול בפסיקה של גרעין מערכת ההפעלה שאינן מיועדות לשימושו באמצעות פסיקות תוכנה, כפי שראינו בשקף הקודם אם נגרמה חריגה, היא מטופלת במקום הפסיקה המקורית

19 מערכות הפעלה - תרגול 919 (c) ארז חדד 2003 טיפול בפסיקה ב-IA32 (2) אם הפסיקה קרתה ב-User Mode ושגרת הטיפול היא בגרעין (כפי שקורה ב-Linux) מתבצעת החלפת מחסניות כחלק מהמעבר ל- Kernel Mode  מצביע בסיס מחסנית הגרעין של התהליך הנוכחי נקרא מתוך ה-TSS ונטען ל-ss:esp  הערך הישן של ss:esp (מצביע לראש מחסנית התהליך ב-User Mode) נשמר במחסנית הגרעין הערכים הבאים נשמרים במחסנית הגרעין:  ערך רגיסטר הדגלים eflags  מצביע חזרה לקוד המקורי מלפני הפסיקה cs:eip בד"כ, של ההוראה הבאה לביצוע; עבור fault, של ההוראה שגרמה לפסיקה  עבור חריגות מסוימות נשמר קוד שגיאה - hardware error code: למשל, עבור פסיקה 16 (שגיאת floating point) נשמר קוד של סוג השגיאה

20 מערכות הפעלה - תרגול 920 (c) ארז חדד 2003 טיפול בפסיקה ב-IA32 (3) כתובת שגרת הטיפול בפסיקה נטענת מהרשומה ב-IDT לתוך cs:eip  בזה מעודכן גם ה-CPL. אם הפסיקה קרתה ב-User Mode, כאן הושלם המעבר ל-Kernel Mode מתבצעת שגרת הטיפול בפסיקה שגרת הטיפול צריכה להסתיים בהוראת iretהמבצעת כדלקמן:  טוענת מהמחסנית את ערכי cs:eip ו-eflags  מחליפה מחסניות בחזרה אם צריך לחזור ל-User Mode ע"י טעינת ss:esp מהערך השמור במחסנית הגרעין  אם נשמר גם hardware error code, שגרת הטיפול בפסיקה צריכה לשלוף ערך זה מהמחסנית לפני הקריאה ל-iretd

21 מערכות הפעלה - תרגול 921 (c) ארז חדד 2003 אתחול ה-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

22 מערכות הפעלה - תרגול 922 (c) ארז חדד 2003 אתחול ה-IDT ב-Linux (2) לאחר האתחול הראשוני, מבוצע מעבר נוסף על ה-IDT המעדכן את הכניסות המתאימות לטיפול בחריגות ובפסיקות מהחומרה המותקנת  במהלך פעולת המערכת ייתכן עדכון נוסף של הטבלה עקב התקנת drivers עדכון כניסה משתמש באחת הפונקציות הבאות, המוגדרות בקובץ הגרעין arch/i386/kernel/traps.c: set_intr_gate(n, addr)  כותבת interrupt gate בכניסה n בטבלה, עם DPL=0 וכתובת שגרת טיפול kcs:addr (kcs מציין את ה-code segment של הגרעין)  מיועדת לטיפול בפסיקות חומרה

23 מערכות הפעלה - תרגול 923 (c) ארז חדד 2003 אתחול ה-IDT ב-Linux (3) 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  משמשת לטיפול בחריגות

24 מערכות הפעלה - תרגול 924 (c) ארז חדד 2003 אתחול ה-IDT ב-Linux (4) הפונקציה 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);

25 מערכות הפעלה - תרגול 925 (c) ארז חדד 2003 טיפול בחריגות ב-Linux (1) שגרות הטיפול בחריגות divide_error, overflow וכו' המופיעות בשקף הקודם כתובות באסמבלר  קובץ גרעין arch/i386/kernel/entry.S כל שגרה שכזאת שומרת את ערכי הרגיסטרים מלפני החריגה ואז מפעילה שגרת טיפול פנימית הכתובה ב-C  שם השגרה הפנימית הוא תחילית "do_" בתוספת שם שגרת הטיפול. לדוגמה: השגרה הפנימית של overflow היא do_overflow() בכניסה לשגרת הטיפול קיים במחסנית ה-hardware error code. קוד האסמבלר מעביר קוד זה יחד עם מצביע לרגיסטרים השמורים במחסנית כפרמטרים לשגרה הפנימית  עבור חריגות שאינן מייצרות קוד שגיאה, מועבר 0  הטיפוס של הפרמטר המצביע לרגיסטרים הוא struct pt_regs *, כזכור מתרגולים קודמים

26 מערכות הפעלה - תרגול 926 (c) ארז חדד 2003 טיפול בחריגות ב-Linux (2) קוד טיפוסי של שגרת טיפול בחריגה: handler_name: pushl $0/* only if no error code */ pushl $do_handler_name /* C handler function */ jmp error_code השגרה error_code שולפת את שני הערכים שנדחפו למחסנית לעיל ודוחפת למחסנית (-1) ואחריו כל הרגיסטרים מלפני הפסיקה (בדומה ל-SAVE_ALL), כמוצג בתרשים מבנה המחסנית בהמשך

27 מערכות הפעלה - תרגול 927 (c) ארז חדד 2003 טיפול בחריגות ב-Linux (3) לאחר שמירת הרגיסטרים, error_code טוענת את ds ו- es להצביע למרחב הזיכרון של הגרעין בהמשך, error_code דוחפת מחדש את ה-hardware error code, אחריו מצביע לתחילת הרגיסטרים השמורים, וקוראת לפונקציה do_handler_name() לאחר החזרה מהשגרה הפנימית, error_code מורידה את הפרמטרים של השגרה הפנימית מהמחסנית וקוראת ל-ret_from_exception לסיום הטיפול

28 מערכות הפעלה - תרגול 928 (c) ארז חדד 2003 טיפול בחריגות ב-Linux (4) שגרות הטיפול הפנימיות בחריגות כגוןdo_overflow, מוגדרות בקובץ הגרעין arch/i386/kernel/traps.c  ההגדרה באמצעות המאקרו DO_ERROR ודומיו מרבית השגרות הללו שולחות signal לתהליך הנוכחי כדי שיטפל בתקלה שנגרמה  סוג ה-signal נקבע על-פי סוג החריגה המטופלת  לדוגמה: עבור floating point exception נשלח SIGFPE  שליחת ה-signal באמצעות פונקציה כדוגמת force_sig() המוגדרת בקובץ הגרעין kernel/signal.c: force_sig(sig_number, current); לפני החזרה ל-User Mode, התהליך יגלה שיש signal הממתין לו, ויפנה לטפל ב-signal זה.

29 מערכות הפעלה - תרגול 929 (c) ארז חדד 2003 טיפול בפסיקות חומרה ב-Linux (1) Linux מנהלת כל פסיקת חומרה דרך מתאר קו ה-IRQ הגורם לפסיקה זו (IRQ Descriptor) המתאר מכיל מידע ופונקציות לטיפול בפסיקת החומרה  status: מצב הפסיקה (בטיפול, ממתינה וכו')  handler: מצביע למספר פונקציות לטיפול ב-APIC בנוגע לפסיקה זו, כפי שנראה בהמשך  action: מצביע לשרשרת ISRs שיופעלו לטיפול בפסיקה, בהתאם להתקנים המחוברים לפסיקת חומרה זו תמיכה ב-IRQ Sharing  ועוד.. כל מתארי ה-IRQ (טיפוס irq_desc_t) מאוחסנים במערך אחד בשם irq_desc בגודל NR_IRQS (בד"כ 224) כניסות  קובץ גרעין include/linux/irq.h

30 מערכות הפעלה - תרגול 930 (c) ארז חדד 2003 טיפול בפסיקות חומרה ב-Linux (2) 0223 status handler action.... ack() end().... handler() flags name dev_id next irq_desc irq_desc_t irqaction hw_interrupt_type irqaction handler() flags name dev_id next

31 מערכות הפעלה - תרגול 931 (c) ארז חדד 2003 טיפול בפסיקות חומרה ב-Linux (3) אתחול ה-IDT לפסיקות חומרה – הפונקציה init_IRQ():  קובץ גרעין arch/i386/kernel/i8259.c for(i = 0; i < NR_IRQS; i++) if (i + 32 != 128) set_intr_gate(i + 32, interrupt[i]); פסיקת חומרה יכולה להיות כל ערך בתחום 32-255  פרט ל-128 (ששמורה לקריאות מערכת) כל כניסה interrupt[n] מצביעה לקוד מהצורה הבאה:  שימו לב – הקוד הזה נפרש NR_IRQS פעמים! IRQn_interrupt: pushl $n-256 call common_interrupt

32 מערכות הפעלה - תרגול 932 (c) ארז חדד 2003 טיפול בפסיקות חומרה ב-Linux (4) הטיפול בכל פסיקות החומרה עובר דרך מנגנון מרכזי אחד המתחיל ב-common_interrupt, כאשר האבחנה בין הפסיקות היא באמצעות הערך הנשמר במחסנית מיד בתחילת שגרת הפסיקה השגרה common_interrupt: common_interrupt: SAVE_ALL/* save registers */ call do_IRQ/* handle interrupt */ jmp ret_from_intr/* resume execution */

33 מערכות הפעלה - תרגול 933 (c) ארז חדד 2003 טיפול בפסיקות חומרה ב-Linux (5) המאקרו SAVE_ALL, הזכור מהתרגול על קריאות מערכת, נפרש לקוד הבא:  לאחר SAVE_ALL מתקבל במחסנית מבנה כמוצג בתרשים בהמשך התרגול.. pushl %es pushl %ds pushl %eax pushl %ebp pushl %edi pushl %esi pushl %edx pushl %ecx pushl %ebx movl $__KERNEL_DS, %edx movl %edx, %ds movl %edx, %es שמירת ערכי כל הרגיסטרים מלפני הפסיקה על-מנת לשחזרם בסיום הטיפול בפסיקה טעינת הרגיסטרים ds ו-es להצביע על איזור הזיכרון של הגרעין

34 מערכות הפעלה - תרגול 934 (c) ארז חדד 2003 הפונקציה do_IRQ() (1) הפונקציה 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 טיפול בפסיקות חומרה ב-Linux

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

36 מערכות הפעלה - תרגול 936 (c) ארז חדד 2003 הפונקציה do_IRQ() (3) הקוד העיקרי של do_IRQ(): int irq = regs.orig_eax & 0xff;.. irq_desc[irq].handler->ack(irq);.. handle_IRQ_event(irq, &regs, irq_desc[irq].action);.. irq_desc[irq].handler->end(irq);.. if (softirq_pending(smp_processor_id()) do_softirq(); שליפת סוג הפסיקה המטופלת שליחת אישור סלקטיבי ל-APIC אפשור סוג הפסיקה המטופלת ב-APIC ביצוע משימות ממתינות (פרטים בהמשך) טיפול בפסיקות חומרה ב-Linux

37 מערכות הפעלה - תרגול 937 (c) ארז חדד 2003 הפעלת ה-ISRs (1) כל ISR מיועד בדרך-כלל לטפל בהתקן מסוים בתגובה לפסיקת חומרה מסוימת:  ISR עבור המקלדת קורא את קוד המקש שנלחץ  ISR עבור כרטיס הרשת קורא נתונים שהתקבלו מהרשת כל ISR מופעל מרשומת irqaction המכילה כדלקמן:  handler() – מצביע ל-ISR עצמו  flags – דגלים המגדירים תכונות של ה-ISR הדגל החשוב ביותר – SA_INTERRUPT – האם ניתן לאפשר פסיקות בזמן ביצוע ה-ISR  name – שם "אנושי" של ההתקן עבור המתכננים והמשתמשים במערכת ניתן לראות את שמות ההתקנים והפסיקות המקושרות אליהם ע"י הפקודה cat /proc/interrupts  dev_id – מזהה של ההתקן המועבר ל-ISR בהפעלתו  next – מצביע לרשומת ה-irqaction הבאה בשרשרת טיפול בפסיקות חומרה ב-Linux

38 מערכות הפעלה - תרגול 938 (c) ארז חדד 2003 הפעלת ה-ISRs (2) הפונקציה handle_IRQ_event() מבצעת בעיקר:  מאפשרת פסיקות במעבד אלא אם מוגדר שלא בדגל SA_INTERRUPT בודקת רק את הדגלים של ה-ISR הראשון בשרשרת  מפעילה את ה-ISRs שבשרשרת בזה אחר זה: do { action->handler(irq, action->dev_id, regs); action = action->next; } while (action); כל ISR יכול לטפל בהתקנים שונים ובפסיקות חומרה שונות (מקבל irq ו-dev_id כפרמטר) בד"כ ISRs אינם משתמשים בפרמטרים המועברים אליהם – מדוע?  חוסמת את הפסיקות מחדש בסיום טיפול בפסיקות חומרה ב-Linux

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

40 מערכות הפעלה - תרגול 940 (c) ארז חדד 2003 חלוקת הטיפול בפסיקות חומרה (2) הפתרון: חלוקה קוד הטיפול לשלוש דרגות דחיפות  critical: פעולות שהכרחי לבצען בפסיקות חסומות פעולות אלו מתבצעות במהירות דוגמא: עבודה עם ה-APIC דוגמה נוספת: ה-ISR של השעון קורא ומסנכרן ערכי שעוני חומרה במחשב בסדרות של פעולות. פסיקה שתקרה במהלך ה-ISR עלולה ליצור עיכוב שישבש ערכי השעון או יגרום לשני שעונים לצאת מסנכרון  noncritical: פעולות שיש לבצען מיד במסגרת הפסיקה, אך אין צורך בחסימת הפסיקות

41 מערכות הפעלה - תרגול 941 (c) ארז חדד 2003 חלוקת הטיפול בפסיקות חומרה (3) דוגמה: ה-ISR של המקלדת מעתיק את קוד המקש שנלחץ לחוצץ של מערכת ההפעלה. קוד ISR זה חייב להתבצע במסגרת הפסיקה הנוכחית (כדי לא לאבד את ההקשה הנוכחית) אבל אינו מצריך חסימת פסיקות  noncritical deferred: משימות שיש צורך לבצען בעקבות הפסיקה, אך אין צורך לבצען מיד עם הפסיקה, אלא מתי-שהוא בהמשך לאחר שיסתיים הטיפול המיידי בפסיקה לדוגמה: המשימה של העברת נתוני הקשות מקלדת שהצטברו מחוצץ מערכת ההפעלה לתהליך המפעיל את המסוף המתאים. בעקבות טיפול בפסיקת מקלדת, משימה זו מוכנסת לַמאגר של "משימות ממתינות" (deferrable functions) כדי שתבוצע בעתיד, כפי שנראה בהמשך

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

43 מערכות הפעלה - תרגול 943 (c) ארז חדד 2003 משימות ממתינות (2) ה-softirqs אגורים במערך (softirq_vec)  רק 4 הכניסות הראשונות בשימוש  כניסה 0 – HI_SOFTIRQ – היא המשימה של ביצוע tasklets בעלי עדיפות גבוהה  כניסות 1 ו-2 – NET_TX_SOFTIRQ, NET_RX_SOFTIRQ – משימות שליחה וקבלת חבילות ברשת  כניסה 3 – TASKLET_SOFTIRQ – משימת ביצוע tasklets בעלי עדיפות רגילה ה-tasklets מחולקים לשני מאגרים: עדיפות גבוהה ועדיפות רגילה  בכל מאגר, ה-tasklets מחולקים לפי הקצאה למעבדים

44 מערכות הפעלה - תרגול 944 (c) ארז חדד 2003 משימות ממתינות (3) ה-bottom halves מופיעים כ-tasklets בעלי עדיפות גבוהה אשר פונקצית הביצוע שלהם מתבצעת רק אם הם מצליחים להשיג מנעול גלובלי מנגנון הטיפול במשימות ממתינות מצוי בקבצי גרעין הבאים:  kernel/softirq.c  include/linux/interrupt.h  include/linux/irq_cpustat.h

45 מערכות הפעלה - תרגול 945 (c) ארז חדד 2003 משימות ממתינות (4) ISRs מסמנים משימות ממתינות להפעלה (activation)  softirqs: קריאה ל-[ _ _ ]cpu_raise_softirq()  tasklets: קריאה ל-tasklet_schedule() (עבור עדיפות רגילה) ו-tasklet_hi_schedule() (עבור עדיפות גבוהה) פונקציות אלו קוראות ל-cpu_raise_softirq() בסיום פעולתן  bottom halves: קריאה ל-mark_bh()...שמתורגמת לקריאה ל-tasklet_hi_schedule() כל tasklet מוקצה לביצוע ע"י המעבד שסימן אותו להפעלה  עלול להוות בעיה, אם המעבד עמוס מדי

46 מערכות הפעלה - תרגול 946 (c) ארז חדד 2003 משימות ממתינות (5) Linux בודקת אם יש משימות ממתינות לביצוע בנקודות זמן שונות כגון:  בסיום do_IRQ() (כפי שראינו קודם)  כאשר מופעל חוט גרעין מיוחד (נראה בהמשך)  ועוד הבדיקה מבוצעת עבור מעבד ספציפי באמצעות הקריאה לפונקציה softirq_pending(cpu) אם יש משימות ממתינות עבור המעבד, מופעלת הפונקציה do_softirq() לביצוען

47 מערכות הפעלה - תרגול 947 (c) ארז חדד 2003 הפונקציה do_softirq()(1) פונקציה זו נקראת על-מנת לבצע משימות ממתינות בביצוע הפונקציה, עוברים על המערך softirq_vec ומבצעים את ה-softirqs המסומנות להפעלה בזו אחר זו לפי סדר הכניסות  כניסה 0 (tasklets בעדיפות גבוהה) מבוצעת לפני כולן  הפונקציה מאפשרת פסיקות לפני תחילת ביצוע המשימות ה-softirqs האחראיות לביצוע tasklets הן הפונקציות tasklet_hi_action() (עדיפות גבוהה) ו- tasklet_action() (עדיפות רגילה)  ביצוע tasklet מותנה בהשגת spin lock השייך לאותו tasklet למניעת ביצוע במקביל במעבדים שונים – אחרת, ביצוע ה- tasklet נדחה להפעלה הבאה של do_softirq() משימות ממתינות

48 מערכות הפעלה - תרגול 948 (c) ארז חדד 2003 הפונקציה do_softirq() (2) בעיה: מכיוון שהפסיקות מאופשרות, במהלך ריצת do_softirq() יכולות להצטרף משימות ממתינות נוספות. מתי יש לטפל בהן?  פתרון 1: נחכה לקריאה הבאה ל-do_softirq() חסרון: בעומס פסיקות נמוך במערכת, ההפעלה הבאה של do_softirq() תהיה לאחר הטיפול בפסיקת השעון הבאה – תדירות הפעלה איטית מדי עבור softirqs מסוימים, כגון אלו של העברת נתונים ברשת  פתרון 2: בסיום מעבר על ה-softirqs, יש לבדוק אם יש softirqs נוספים ואם כן לבצע מעבר נוסף במסגרת ההפעלה הנוכחית של do_softirq() משימות ממתינות

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

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

51 מערכות הפעלה - תרגול 951 (c) ארז חדד 2003 חריגהפסיקת חומרהקריאת מערכתהאיבר במחסנית מצביע למחסנית התהליך ב-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

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

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

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

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

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


Download ppt "מערכות הפעלה תרגול 9 – פסיקות ב-Linux. מערכות הפעלה - תרגול 92 (c) ארז חדד 2003 תוכן התרגול מבוא לפסיקות ב-Linux פסיקות ב-IA32:  סוגי הפסיקות  טבלת."

Similar presentations


Ads by Google