بیشتر مشکلات مربوط به پایین بودن کیفیت صدا و مشکل در دریافت فکس در کارتهای تلفنی به دلیل وجود overrun در کارت میباشد. دو دلیل که باعث overrun می شود shared IRQ و Disk activity میباشد. برای اینکه از وجود overrun در کارتهای خود مطمئن شوید در کارتهای sangoma شما میتوانید با زدن دستور watch -d -n 0.5 ifconfig به دنبال overrun ، در کارت سنگوما خود که به صورت w1g1 نشان داده میشود بگردید اگر مقدار overrun رو به افزایش بود، یعنی شما بر روی کارت overrun دارید.
توجه کنید مقداری overrun هنگام up شدن کارت به وجود میآید که مشکلی ندارد فقط مقدار آن نباید رو به افزایش باشد که شما میتوانید با چند بار زدن دستور ifconfig از افزایش آن مطمئن شوید.
برای کارتهای openvox نیز میتوانید بعد از اجرای دستور dmesg ، در خروجی آن به دنیال overrun بگردید همانند زیر:
?
اگر خروجی همانند زیر دیدید در واقع نشان دهنده overrun بر روی کارت openvox میباشد.
?
1 | dahdi: HDLC Receiver overrun on channel TE4/0/1/16 (master=TE4/0/1/16) |
برای بررسی این موارد ابتدا یک توضیح مختصری در رابطه با هر کدام از آنها میدهم .
Interrupt – IRQ
interrupt به روشی گفته میشود که از طریق آن سخت افزار میتواند با پردازنده ارتباط برقرار کند. برای مثال هنگامی که یک کارت شبکه بستهای را دریافت میکند، از طریق interrupt به پردازنده اطلاع میدهد تا پردازش بر روی آن بستهها صورت گیرد.
IRQ یک شمارهای است که برای مشخص کردن interrupt استفاده میشود. یک PC معمولی ۱۶ IRQ دارد (از شماره ۰ تا ۱۵) و بیشتر آنها توسط device های onboard مانند floppy ، کارت صدا و … گرفته شدهاند.
برای به دست آوردن لیست آنها در لینوکس، دستور زیر را وارد کنید .
?
در زیر نمونهای از خروجی دستور بالا را میبینید.
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | CPU0 CPU1 0: 42552 0 XT-PIC timer 1: 8 0 XT-PIC i8042 2: 0 0 XT-PIC cascade 5: 173 0 XT-PIC eth0 6: 5 0 XT-PIC floppy 7: 0 0 XT-PIC parport0 8: 0 0 XT-PIC rtc 9: 0 0 XT-PIC acpi, Ensoniq AudioPCI 10: 0 0 XT-PIC uhci_hcd:usb2 11: 6036 0 XT-PIC ehci_hcd:usb1, ioc0 12: 116 0 XT-PIC i8042 15: 208 0 XT-PIC ide1 NMI: 0 0 LOC: 65131 66270 ERR: 0 MIS: 0 |
APIC
apic در واقع راهی برای گذشتن از محدودیت ۱۶ IRQ میباشد. در سیستم های چند پردازندهای APIC به صورت پیش فرض فعال است.
دستور قبلی با اضافه کردن noapic در پارامترهای kernel در grub.conf اجرا شده بود که ما در نتیجه فقط تا شماره ۱۵ را در IRQ میبینیم خروجی دستور زیر بدون noapic در پارامتر های kernel میباشد که میبینیم شمارههای بالاتر نیز در IRQ دیده میشود.
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | CPU0 CPU1 0: 352717 0 IO-APIC-edge timer 1: 9 0 IO-APIC-edge i8042 6: 5 0 IO-APIC-edge floppy 7: 0 0 IO-APIC-edge parport0 8: 0 0 IO-APIC-edge rtc 9: 0 0 IO-APIC-level acpi 12: 53 0 IO-APIC-edge i8042 15: 1930 0 IO-APIC-edge ide1 51: 7782 0 IO-APIC-level ehci_hcd:usb1, ioc0 59: 0 0 IO-APIC-level uhci_hcd:usb2 67: 1205 0 IO-APIC-level eth0 75: 0 0 IO-APIC-level Ensoniq AudioPCI NMI: 0 0 LOC: 635562 635318 ERR: 0 MIS: 0 |
به طور کلی داشتن APIC میتواند گزینه مناسبی برای جلوگیری از interrupt sharing باشد.
برای پیدا کردن IRQ متناظر با کارت خود دستور lspci -v را اجرا کنید.
?
معمولا برای پیدا کردن کارتهای تلفنی خود میتوانید در آخر خروجی دستور، آن را پیدا کنید در زیر نمونهای از کارت سنگوما میباشد که بر روی IRQ ۱۹ قرار دارد.
?
1 2 3 4 | ۰۳:۰۱٫۰ Network controller: Sangoma Technologies Corp. A200/Remora FXO/FXS Analog AFT card Subsystem: Device a112:3713 Flags: bus master, medium devsel, latency 255, IRQ 19 Memory at fddf8000 (32-bit, non-prefetchable) [size=32K] |
برای پیدا کردن Interrupt sharing دستور زیر را اجرا کنید.
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | cat /proc/interrupts CPU0 CPU1 CPU2 CPU3 0: 123 1 24 2 IO-APIC-edge timer 1: 1 0 1 0 IO-APIC-edge i8042 3: 0 0 1 1 IO-APIC-edge 4: 0 1 0 0 IO-APIC-edge 7: 0 0 0 0 IO-APIC-edge parport0 8: 0 0 0 1 IO-APIC-edge rtc0 9: 0 0 0 0 IO-APIC-fasteoi acpi 12: 0 2 1 1 IO-APIC-edge i8042 14: 9176 6896 18477 5449 IO-APIC-edge ata_piix 15: 36146 9492 70544 8499 IO-APIC-edge ata_piix 16: 102726 17955 336 29 IO-APIC-fasteoi uhci_hcd:usb5 18: 0 0 0 0 IO-APIC-fasteoi uhci_hcd:usb4 19: 2652 2656 2712 21713805 IO-APIC-fasteoi uhci_hcd:usb3, wanpipe1, wanpipe2 23: 2 1 0 0 IO-APIC-fasteoi ehci_hcd:usb1, uhci_hcd:usb2 26: 318565 4208 60929 87446 PCI-MSI-edge i915 27: 151 142 109 111 PCI-MSI-edge snd_hda_intel 28: 13 16460 11 12647 PCI-MSI-edge eth0 NMI: 307 269 173 543 Non-maskable interrupts LOC: 6395114 6735099 7258826 1308457 Local timer interrupts SPU: 0 0 0 0 Spurious interrupts PMI: 307 269 173 543 Performance monitoring interrupts IWI: 0 0 0 0 IRQ work interrupts RES: 10055 8496 11959 11831 Rescheduling interrupts CAL: 10161 218 9802 238 Function call interrupts TLB: 6258 4324 3038 4931 TLB shootdowns TRM: 0 0 0 0 Thermal event interrupts THR: 0 0 0 0 Threshold APIC interrupts MCE: 0 0 0 0 Machine check exceptions MCP: 29 29 29 29 Machine check polls ERR: 0 MIS: 0 |
در مثال بالا میبینیم که کارتهای سنگوما با پورت usb یک IRQ دارند برای رفع این مسئله میتوانید در تنظیمات BIOS خود کارتهایی را که به آنها نیازی ندارید مانند کارت VGA و پورت های usb اضافه را disable کنید و یا slot pci کارت خود را جابهجا کنید.
برای به دست آوردن مقدار interrupt دستور زیر را اجرا کنید. در این دستور خروجی دستور cat /proc/interrupts هر یک ثانیه یک بار نمایش داده میشود.
?
1 | watch -n 1 'cat /proc/interrupts ' |
در این دستور تعداد interrupt مربوط به هر IRQ را در یک ثانیه نشان میدهد. برای کارتهای تلفنی شما باید در هر ثانیه ۱۰۰۰ interrupt داشته باشید.
اگر پردازنده تعداد زیادی interrupt در لحظه دریافت کند این باعث میشود که cpu شانس کمتری برای پردازش اطلاعات دریافتی از کارت تلفنی را داشته باشد.
چه اتفاقی میافتد اگر cpu در لحظه ۲ interrupt را دریافت کند؟
cpu بر اساس اولویت شماره IRQ آنها پاسخ خواهد داد.
?
1 | [۰ ۱ ۲ ۸ ۹ ۱۰ ۱۱ ۱۲ ۱۳ ۱۴ ۱۵ ۳ ۴ ۵ ۶ ۷] |
در لیست بالا ۰ بالاترین اولویت و ۷ پایین ترین اولویت را خواهد داشت
با توجه به این که اگر APIC در سیستم شما فعال میباشد IRQ گرفته شده در کارت PCI شما شمارهای غیر از اعداد بالا خواهد بود بنابراین برای به دست آوردن IRQ مناسب دستور lspci -vb را اجرا کنید تا IRQ دقیق را به دست آورید (دستور lspci با option -b باعث میشود IRQ متناظر از دید کارت نشان داده شود در حالی که با option -v شما IRQ داده شده از دید kernel را مشاهده میکنید)
هر چه IRQ شما بیشتر در سمت چپ لیست بالا قرار گیرد کارت تلفنی شما اولویت بیشتری نسبت به device های دیگر برای پردازش دیتا دارد.
در سیستم های چند پردازندهای اگر توجه کنید بعضی از core های cpu هیچ interrupt را دریافت نمیکنند، شما میتوانید با دادن مقدار به فایل smp_affinity مربوط به IRQ خود، تمامی interrupt های دریافتی از آن IRQ را بر روی core و یا core های دیگر بفرستید. به این صورت که در فایل proc/irq//[irq number]/smp_affinity/ عدد دلخواه خود را وارد کنید برای مثال:
?
1 | echo 0 > /proc/irq/19/smp_affinity |
دستور بالا تمامیinterrupt های دریافتی از IRQ ۱۹ را به پردازنده اول میفرستد درحالی که دستور زیر تمامی interrupt ها را به پردازنده دوم میفرستد
?
1 | echo 1 > /proc/irq/19/smp_affinity |
مشکلات Disk
ابتدا مطمئن شوید خروجی دستورات زیر بالاتر از ۴۰mb/sec است. اگر از هارد sata استفاده میکنید دستور زیر را اجرا کنید.
?
1 2 3 4 | hdparm -t /dev/sda /dev/sda: Timing buffered disk reads: 286 MB in 3.01 seconds = 94.97 MB/sec |
و اگر از هارد IDE استفاده میکنید دستور زیر را اجرا کنید.
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | hdparm -t /dev/hda /dev/hda: Timing buffered disk reads: 240 MB in 3.01 seconds = 79.73 MB/sec hdparm /dev/hda /dev/hda: multcount = 16 (on) IO_support = 0 (default 16-bit) unmaskirq = 0 (off) using_dma = 1 (on) keepsettings = 0 (off) readonly = 0 (off) readahead = 256 (on) geometry = 65535/16/63, sectors = 80026361856, start = 0 |
مطمئن شوید که using_dma برابر با ۱ است. اگر تمامی تستهای بالا با موفقیت انجام شد مطمئن شوید acpi در سیستم شما فعال نباشد. acpi باعث میشود تا از عملکرد کامل pci شما جلوگیری شود. برای این کار دستور زیر را اجرا کنید اگر خروجی عددی غیر از صفر بود آن گاه acpi در سیستم شما فعال است.
?
1 | cat /proc/interrupts | grep -c acpi |
برای غیر فعال کردن آن در فایل etc/grub.conf/ پارامتر زیر را به آخر خط kernel خود اضافه کنید.
?
1 2 3 4 | title Test Linux (3.5.3) root (hd0,0) kernel /vmlinuz-3.5.3 ro root=UUID=e553f7ad-bfbf-47a3-9eec-17d367f77b5d rhgb quiet acpi=off initrd /initramfs-3.5.3.img |
(توجه کنید ACPI و APIC شما را گمراه نکند)