How much delay can be achieved using jiffies in kernel - linux-kernel

I need to emulate MDC/MDIO bus using the bit-banging for MDC line. I need to get a clock with frequency of 1.5 Mhz, 1 Mhz will also do.
I am trying to use udelay and ndelay from linux/delay.h. I am working with kernel 2.6.32 and MPC8569E processor from freescale. ndelay is not giving me dealy in nanoseconds but microseconds, I saw it using a logic analyzer on the wires. So ndelay(1) and udelay(1) are effectively behaving the same, giving 1 microsecond delay.
Now In a bit-bang model the codes gonna be something like
par_io_data_set(2/*C port*/,30 /*MDIO pin*/,val /*value*/); //write data to the line MDIO line
//clock pulse for setting the data
ndelay(MDIO_DELAY);
par_io_data_set(2/*C port*/,31 /*MDC pin*/,1 /*value*/);
ndelay(MDIO_DELAY);
par_io_data_set(2/*C port*/,31 /*MDC pin*/,0 /*value*/);
Where I have defined MDIO_DELAY as 1. So I am able to get a clock of around 0.4MHz. I want to bitbang at 1.5 Mhz, but I can't just do so until I can't give delay in nanoseconds.
So I was looking at chapter 7 of ldd, jiffies. Well my HZ is 250, so the kernel interrupts for time every 1/250 secs i.e. 4milli secs right? So jiffies gonna be incremented every 4ms. So I can't expect jiffies to get a counter of the order of nano-seconds, right?
How do I get this job done?

Related

Can I disable the watchdog timer in windows 7?

I'm trying to disable all interrupts including NMI's on a single core in a processor and put that core into an infinite loop with a JMP instruction targeting itself (bytecode 0xEBFE) I tried this with the following machine code:
cli
in al, 0x70
mov bl, 0x80
or al, bl
out 0x70, al
jmp self (0xEBFE)
I assumed that disabling NMI interrupts would also disable the watchdog since according to this link the watchdog timer is an NMI interrupt, but what happened when I ran this code is after around 5 seconds my computer bugchecked with code 0x101 CLOCK_WATCHDOG_TIMEOUT. I'm wondering if windows notices that I've disabled NMI interrupts and then re-enables them before initiating the kernel panic. Does anyone know how to disable the watchdog timer in windows 7?
I don't think the NMIs are at fault here.
External NMIs are obsolete, they are hard to route in an SMP system. That watchdog timer is also obsolete, it was either a secondary PIT or a limited fourth channel of the primary PIT:
----------P00440047--------------------------
PORT 0044-0047 - Microchannel - PROGRAMMABLE INTERVAL TIMER 2
SeeAlso: PORT 0040h,PORT 0048h
0044 RW PIT counter 3 (PS/2)
used as fail-safe timer. generates an NMI on time out.
for user generated NMI see at 0462.
0047 -W PIT control word register counter 3 (PS/2, EISA)
bit 7-6 = 00 counter 3 select
= 01 reserved
= 10 reserved
= 11 reserved
bit 5-4 = 00 counter latch command counter 3
= 01 read/write counter bits 0-7 only
= 1x reserved
bit 3-0 = 00
----------P0048004B--------------------------
PORT 0048-004B - EISA - PROGRAMMABLE INTERVAL TIMER 2
Note: this second timer is also supported by many Intel chipsets
SeeAlso: PORT 0040h,PORT 0044h
0048 RW EISA PIT2 counter 3 (Watchdog Timer)
0049 ?? EISA 8254 timer 2, not used (counter 4)
004A RW EISA PIT2 counter 5 (CPU speed control)
004B -W EISA PIT2 control word
These hardware is gone, it's not present on modern systems. I've tested my machine and I don't have it.
Intel chipsets don't have it:
There is only the primary PIT.
Modern timers are the LAPIC timer and the HPET (Linux did even resort to using the PMC registers).
Windows does support an HW WDT, in fact Microsoft went as long as defining an ACPI extension: the WDAT table.
This WDT however can only reboot or shutdown the system, in hardware, without the intervention of the software.
// Configures the watchdog hardware to perform a reboot
// when it is fired.
//
#define WATCHDOG_ACTION_SET_REBOOT 0x11
//
// Determines if the watchdog hardware is configured to perform
// a system shutdown when fired.
//
#define WATCHDOG_ACTION_QUERY_SHUTDOWN 0x12
//
// Configures the watchdog hardware to perform a system shutdown
// when fired.
//
#define WATCHDOG_ACTION_SET_SHUTDOWN 0x13
Microsoft set quite a quit of requirement for this WDT since it must be setup as early as possible in the boot process, before the PnP enumeration (i.e. PCI(e) enumeration).
This is not the timer that bugchecked your system.
By the way, I don't have this timer (my system is missing the WDAT table) and I don't expect it to be found on client hardware.
The bugcheck 0x101 is due to a software WDT, it is raised inside a function in ntoskrnl.exe.
This function is called by KeUpdateRunTime and by another chain of calls starting in DriverEntry:
According to Windows Internals, KeUpdateRunTime is used to update the internal ticks counting of Windows.
I'd expect only a single logical processor to be put in charge of that, though I'm not sure of how exactly Windows housekeeps time.
I'd also expect this software WDT to be implemented in a master-slave fashion: each CPU increments its own counter and a designed CPU check the counters periodically (or any equivalent implementation).
This seems to be suggested by the wording of the documentation of the 0x101 bugcheck:
The CLOCK_WATCHDOG_TIMEOUT bug check has a value of 0x00000101. This indicates that an expected clock interrupt on a secondary processor, in a multi-processor system, was not received within the allocated interval.
Again, I'm not an expert on this part of Windows (The user MdRm, probably is) and this may be utterly wrong, but if it isn't you probably are better of following Alex's advice and boot with one less logical CPU.
You can then execute code on that CPU with an INIT-SIPI-SIPI sequence as described on the Intel's manual but you must be careful because the issuing processor is using paging while the sleeping one is not yet (the processor will start up in real-mode).
Initialising a CPU may be a little cumbersome but not too much after all.
Stealing it may result in other problems besides the WDT, for example if Windows has routed an interrupt to that processor only.
I don't know if there is driver API to unregister a logical processor, I found nothing looking at the exports of hal.dll and ntoskrnl.exe.

implementation of dirty_expire_centisecs

I'm trying to understand the behavior of dirty_expire_centisecs parameter on servers with 2.6 and 3.0 kernels.
Kernel documentation says (vm.txt/dirty_expire_centisecs)
"Data which has been dirty in-memory for longer than this interval will be written out next time a flusher thread wakes up."
which implies, dirty data that has been in memory for shorter than this interval will not be written.
According to my testing, behavior of dirty_expire_centisecs is as follows: when writeback timer fires before the expire timer, then no pages will be flushed, else all pages will be flushed.
If background_bytes limit reaches, it flushes all or portion depending on the rate, independent of both timers.
My testing tells me at low write rates (less than 1MB per sec), dirty_background_bytes trigger will flush all dirty pages and at slightly higher data rates (higher than 2MB per sec), it flushes only a portion of the dirty data, independent of expiry value.
This is different from what is said in the vm.txt. It make sense not to flush the most recent data. To me, observed behavior is not logical and practically useless. What do you guys think ?
My test setup:
Server with 16GB of RAM running Suse 11 SP1, SP2 and RedHat 6.2 (multi boot setup)
vm.dirty_bytes = 50000000 // 50MB <br>
vm.dirty_background_bytes = 30000000 // 30MB <br>
vm.dirty_writeback_centisecs = 1000 // 10 seconds <br>
vm.dirty_expire_centisecs = 1500 // 15 seconds <br>
with a file writing tool where I can control the write()'s per sec rate and size.
I asked this question on the linux-kernel mailing list and got an answer from Jan Kara. The timestamp that expiration is based on is the modtime of the inode of the file. Thus, multiple pages dirtied in the same file will all be written when the expiration time occurs because they're all associated with the same inode.
http://lkml.indiana.edu/hypermail/linux/kernel/1309.1/01585.html

Clock frequency of the CPU & measuring time elapses

I wanted to know how much time "1ms sleep" takes.
Ran this quest in kernel module:
rdtscl(aj);
msleep(1);
rdtscl(b);
printk(KERN_INFO "Difference = %lu", (b-a));// Number of clock cycles consumed
Output i got:
Difference = 13479219
Output for cat /proc/cpuinfo
cpu MHz : 1197.000
With that, I calculated the delay, which i got 11.26 milli second.
Why am i not getting it around 1 ms ?
UPDATE:
The Processor frequency in cat /proc/cpuinfo sholud be got from the following line:
model name : Intel(R) Core(TM) i3 CPU 540 # 3.07GHz
=> the Processor frequency is 3.07 GHz. Dont know what is the meaning of this line "cpu MHz : 1197.000" though.
Thanks
The process resolution depends on the HZ value configured on the system that you had run the test code. The HZ value can be 100 or 1000, if its 100 then the scheduler will wake up only once in 10 ms. Mostly in desktop systems, in the recent distributions, it will be set to 1000. (You can check in the config file in /boot in Fedora). The scheduler will schedule only based on that, so if the scheduler wakes up once in every 10 ms, then there is no way of getting resolutions lesser than 10 ms. Or you need to use HR timers in the kernel.
kernel-3.4.5 (u3-1 *)$ cat /boot/config-3.6.10-4.fc18.x86_64 | grep HZ
CONFIG_NO_HZ=y
# CONFIG_RCU_FAST_NO_HZ is not set
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
# CONFIG_HZ_300 is not set
CONFIG_HZ_1000=y
CONFIG_HZ=1000
If you really want the delay but without sleeping, then you can use mdelay, which will just loop for the specified amount of time and return.

Writing to Micro SD from SHARC 21469 idle and speed issues.

I can properly read/write to a 2GB Kingston Micro SD using single pin SPI, but after writing using the WRITE_MULTIPLE_BLOCK command to write several blocks, the card goes into idle mode. I know this because when I try send a command to write more data, the card returns an 'in idle state' flag. I created a work around that pulls the card from idle after each write but this severely reduces the bandwidth. Does anyone know why this happens?
Also, the maximum SPI Baud I have obtained is 1Mbs. When I set the SPI clk to >1MHz the commands do not work properly. If I send commands at a baud of < 1Mbs then send the data at >1Mbs, the data is corrupted. Is there a reason I have not been able to get the 25MHz specification speed as listed in the SDCARD.org spec on p2?
https://www.sdcard.org/developers/tech/sdio/sdio_spec/Simplified_SDIO_Card_Spec.pdf
I got SPI Speeds less than 1 MBit/s when I tried to use the wrong SPI clock polarity once. Double check this, and this is also a possible candidate as a source for you "idle" error.

clock_getres and Kernel 2.6

i'm using ubuntu 11.04 now and using v2lin to port my program from vxWorks tolinux. I have problem with clock_getres().
with this code:
struct timespec res;
clock_getres(CLOCK_REALTIME, &res);
i have res.tv_nsec = 1 , which is somehow not correct.
Like this guy showed: http://forum.kernelnewbies.org/read.php?6,377,423 , there is difference between kernel 2.4 and 2.6.
So what should be the correct value for the clock resolution in kernel 2.6
Thanks
According to "include/linux/hrtimer.h" file from kernel sources, clock_getres() will always return 1ns (one nanosecond) for high-resolution timers (if there are such timers in the system). This value is hardcoded and it means: "Timer's value will be rounded to it"
http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/include/linux/hrtimer.h
269 /*
270 * The resolution of the clocks. The resolution value is returned in
271 * the clock_getres() system call to give application programmers an
272 * idea of the (in)accuracy of timers. Timer values are rounded up to
273 * this resolution values.
274 */
275 # define HIGH_RES_NSEC 1
276 # define KTIME_HIGH_RES (ktime_t) { .tv64 = HIGH_RES_NSEC }
277 # define MONOTONIC_RES_NSEC HIGH_RES_NSEC
278 # define KTIME_MONOTONIC_RES KTIME_HIGH_RES
For low-resolution timers (and for MONOTONIC and REALTIME clocks if there is no hrtimer hardware), linux will return 1/HZ (typical HZ is from 100 to 1000; so value will be from 1 to 10 ms):
http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/include/linux/ktime.h#L321
321 #define LOW_RES_NSEC TICK_NSEC
322 #define KTIME_LOW_RES (ktime_t){ .tv64 = LOW_RES_NSEC }
Values from low-resolution timers may be rounded to such low precision (effectively they are like jiffles, the linux kernel "ticks").
PS: This post http://forum.kernelnewbies.org/read.php?6,377,423 as I can understand, compares 2.4 linux without hrtimers enabled (implemented) with 2.6 kernel with hrtimers available. So all values are correct.
Try to get it from procfs.
cat /proc/timer_list
Why do you think it is incorrect?
For example, on modern x86 CPUs the kernel uses the TSC to provide high resolution clocks - any CPU running at higher than 1Ghz has a TSC that ticks over faster than a tick per nanosecond, so nanosecond resolution is quite common.

Resources