Re: copy_from_user user space address mapping in the kernel page table.

2014-11-02 Thread mind entropy
On Mon, Nov 3, 2014 at 6:45 AM,   wrote:
> On Sun, 02 Nov 2014 19:57:44 +0530, mind entropy said:
>>   In the copy_from_user when the user passes the virtual address is
>> the address mapped in the kernel page tables?
>
> Actually, a large part of the reason for copy_from_user()'s existence is
> to deal with the possibility that the page is *not* mapped at the moment
> because it's been swapped out (at which point we need to schedule a read
> operation for whatever backing store the page had (filesystem, swap, or
> zero-page for a never-before-referenced page), wait for it to arrive,
> and then nail it down so it doesn't leave out from under us before
> we finish the copy from the page.

Got this part. Now the mapping will be done in the kernel page
table,correct? i.e. in the
swapper_pg_dir and this would be what the MMU will use to walk,
correct? In short when the memcpy is
being done the page table will be the kernel pgd right?


>
> And of course, it's even *more* fun when the copy crosses a page boundary,
> and one or both of the pages isn't resident
>
>>In the function there is
>> a source is a user virtual address(<3GB) and the destination is the
>
> Only for 32-bit kernels.  x86_64 has a different memory layout.

___
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies


copy_from_user user space address mapping in the kernel page table.

2014-11-02 Thread mind entropy
Hi,
  In the copy_from_user when the user passes the virtual address is
the address mapped in the kernel page tables? In the function there is
a source is a user virtual address(<3GB) and the destination is the
kernel virtual address(3GB - 4GB) and for the MMU to access the
physical page frame when in kernel space operating in behalf of the
process context there should be a mapping of the virtual address to
the page frame, correct?

  I am assuming the implementation would be to take the virtual
address and walk the page table to get to the physical page frame and
map the physical page frame in the kernel page table (i.e.
swapper_pgd). Is this correct? If not what would be the mechanism?

Thanks,
Gautam.

___
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies


On spin_lock_irq_save and disabling specific interrupts.

2014-11-01 Thread mind entropy
Hi,

 When I do spin_lock_irq it disables IRQ's which were enabled. What is
the reason for disabling all the irq's rather than disabling the
specific IRQ line which shares the resource? Wouldn't this be more
efficient and would not lose any interrupts especially if I have a
critical sensor ADC?

Thanks,
Gautam.

___
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies


Re: On Page table walk.

2014-10-06 Thread mind entropy
On Wed, Oct 1, 2014 at 7:17 PM, mind entropy  wrote:
>> --
>>
>> Message: 5
>> Date: Mon, 29 Sep 2014 23:05:44 +0530
>> From: mind entropy 
>> Subject: On Page table walk.
>> To: kernelnewbies 
>> Message-ID:
>> 
>> Content-Type: text/plain; charset=UTF-8
>>
>> Hi,
>>
>>   I am experimenting with page table walking. I run a user space
>> program and set the device attribute (of my sample device driver) in
>> the sysfs. (DEVICE_ATTR) which is the address of the variable in the
>> user space. I get the current->mm to get the current task memory
>> descriptor and use it to walk the pages. Once I get the pte address I
>> reboot and dump the memory at that point using u-boot. (md.b  1)
>> but I do not find the value present there.
>>
>> Sample code: (This is just for illustration and experimenting and does
>> not contain error checks etc.).
>>
>> 
>> ssize_t process_mem_test_attr_store(struct device *dev,
>> struct device_attribute *attr,
>> const char *buf,
>> size_t count)
>> {
>>
>> struct task_struct *current_task;
>> unsigned long addr_res;
>> struct vm_area_struct *vmarea_struct_addr;
>> pgd_t *pgd;
>> pmd_t *pmd;
>> pud_t *pud;
>> pte_t *ptep, pte;
>> struct page *page;
>> int kval;
>> int uval;
>>
>> DEFINE_SPINLOCK(test_lock);
>>
>> spin_lock_irq(&test_lock);
>>
>> current_task = current;
>>
>> if(current_task != NULL) {
>>
>> printk(KERN_ALERT "\nCurrent task pid: %d\n",
>> current_task->pid);
>>
>> printk(KERN_ALERT "mm: 0x%lx, active_mm 0x%lx\n",
>> current_task->mm,current_task->active_mm);
>> printk(KERN_ALERT "Page global directory : 0x%lx\n",
>> current_task->mm->pgd);
>> printk(KERN_ALERT "mmap base : 0x%lx",
>> current_task->mm->mmap_base);
>>
>> vmarea_struct_addr = current_task->mm->mmap;
>>
>> while(vmarea_struct_addr != NULL) {
>> printk(KERN_ALERT "vm_start : 0x%lx, vm_end : 0x%lx\n",
>> vmarea_struct_addr->vm_start,
>> vmarea_struct_addr->vm_end);
>>
>> vmarea_struct_addr = vmarea_struct_addr->vm_next;
>> }
>>
>>
>> } else {
>> printk(KERN_ALERT "Current task NULL\n");
>> }
>>
>> if(kstrtol(buf,10,&addr_res) != 0) {
>> printk(KERN_ALERT "Error converting to long\n");
>> return count;
>> }
>>
>> copy_from_user(&kval,(unsigned int *)addr_res,4);
>>
>> printk(KERN_ALERT "kval : %x\n",kval);
>> printk(KERN_ALERT "addr: %lx\n",addr_res);
>>
>> pgd = pgd_offset(current_task->mm,addr_res);
>>
>> if(pgd_none(*pgd) || pgd_bad(*pgd)) {
>> printk(KERN_ALERT "pgd bad\n");
>> return count;
>> } else {
>> printk(KERN_ALERT "pgd 0x%lx\n",pgd);
>> }
>>
>> pud = pud_offset(pgd,addr_res);
>>
>> if(pud_none(*pud) || pud_bad(*pud)) {
>> printk(KERN_ALERT "pud bad\n");
>> return count;
>> } else {
>> printk(KERN_ALERT "pud 0x%lx\n",pud);
>> }
>>
>> pmd = pmd_offset(pud,addr_res);
>>
>> if(pmd_none(*pmd) || pmd_bad(*pmd)) {
>> printk(KERN_ALERT "pmd bad\n");
>> return count;
>> } else {
>> printk(KERN_ALERT "pmd 0x%lx\n",pmd);
>> }
>>
>>
>> ptep = pte_offset_map(pmd,addr_res);
>> if(!ptep) {
>> printk(KERN_ALERT "ptep bad\n");
>> } else {
>> printk(KERN_ALERT "ptep 0x%lx\n",ptep);
>> }
>>
>> pte = *ptep;
>>
>>
>> if(pte_present(pte)) {
>> printk(KERN_ALERT "pte : 0x%lx\n",pte);
>> page = pte_page(pte);
>>
>> } else {
>> printk(KERN_ALERT "pte not present\n");
>> }
>

Re: On Page table walk.

2014-10-01 Thread mind entropy
> --
>
> Message: 5
> Date: Mon, 29 Sep 2014 23:05:44 +0530
> From: mind entropy 
> Subject: On Page table walk.
> To: kernelnewbies 
> Message-ID:
> 
> Content-Type: text/plain; charset=UTF-8
>
> Hi,
>
>   I am experimenting with page table walking. I run a user space
> program and set the device attribute (of my sample device driver) in
> the sysfs. (DEVICE_ATTR) which is the address of the variable in the
> user space. I get the current->mm to get the current task memory
> descriptor and use it to walk the pages. Once I get the pte address I
> reboot and dump the memory at that point using u-boot. (md.b  1)
> but I do not find the value present there.
>
> Sample code: (This is just for illustration and experimenting and does
> not contain error checks etc.).
>
> 
> ssize_t process_mem_test_attr_store(struct device *dev,
> struct device_attribute *attr,
> const char *buf,
> size_t count)
> {
>
> struct task_struct *current_task;
> unsigned long addr_res;
> struct vm_area_struct *vmarea_struct_addr;
> pgd_t *pgd;
> pmd_t *pmd;
> pud_t *pud;
> pte_t *ptep, pte;
> struct page *page;
> int kval;
> int uval;
>
> DEFINE_SPINLOCK(test_lock);
>
> spin_lock_irq(&test_lock);
>
> current_task = current;
>
> if(current_task != NULL) {
>
> printk(KERN_ALERT "\nCurrent task pid: %d\n",
> current_task->pid);
>
> printk(KERN_ALERT "mm: 0x%lx, active_mm 0x%lx\n",
> current_task->mm,current_task->active_mm);
> printk(KERN_ALERT "Page global directory : 0x%lx\n",
> current_task->mm->pgd);
> printk(KERN_ALERT "mmap base : 0x%lx",
> current_task->mm->mmap_base);
>
> vmarea_struct_addr = current_task->mm->mmap;
>
> while(vmarea_struct_addr != NULL) {
> printk(KERN_ALERT "vm_start : 0x%lx, vm_end : 0x%lx\n",
> vmarea_struct_addr->vm_start,
> vmarea_struct_addr->vm_end);
>
> vmarea_struct_addr = vmarea_struct_addr->vm_next;
> }
>
>
> } else {
> printk(KERN_ALERT "Current task NULL\n");
> }
>
> if(kstrtol(buf,10,&addr_res) != 0) {
> printk(KERN_ALERT "Error converting to long\n");
> return count;
> }
>
> copy_from_user(&kval,(unsigned int *)addr_res,4);
>
> printk(KERN_ALERT "kval : %x\n",kval);
> printk(KERN_ALERT "addr: %lx\n",addr_res);
>
> pgd = pgd_offset(current_task->mm,addr_res);
>
> if(pgd_none(*pgd) || pgd_bad(*pgd)) {
> printk(KERN_ALERT "pgd bad\n");
> return count;
> } else {
> printk(KERN_ALERT "pgd 0x%lx\n",pgd);
> }
>
> pud = pud_offset(pgd,addr_res);
>
> if(pud_none(*pud) || pud_bad(*pud)) {
> printk(KERN_ALERT "pud bad\n");
> return count;
> } else {
> printk(KERN_ALERT "pud 0x%lx\n",pud);
> }
>
> pmd = pmd_offset(pud,addr_res);
>
> if(pmd_none(*pmd) || pmd_bad(*pmd)) {
> printk(KERN_ALERT "pmd bad\n");
> return count;
> } else {
> printk(KERN_ALERT "pmd 0x%lx\n",pmd);
> }
>
>
> ptep = pte_offset_map(pmd,addr_res);
> if(!ptep) {
> printk(KERN_ALERT "ptep bad\n");
> } else {
> printk(KERN_ALERT "ptep 0x%lx\n",ptep);
> }
>
> pte = *ptep;
>
>
> if(pte_present(pte)) {
> printk(KERN_ALERT "pte : 0x%lx\n",pte);
> page = pte_page(pte);
>
> } else {
> printk(KERN_ALERT "pte not present\n");
> }
>
> printk(KERN_ALERT "pte with offset 0x%lx offset : 0x%lx\n",
> pte+((addr_res) & ((1< addr_res & ((1<
>
> while(1)
> ;
>
> printk(KERN_ALERT "After lock\n"); //Should not print this.
>
>
> return count;
> }
> 
>
> I use a spinlock to prevent the process from getting swapped. I
> disable the irq and make it spin on while(1); after which I reboot.

On Page table walk.

2014-09-29 Thread mind entropy
Hi,

  I am experimenting with page table walking. I run a user space
program and set the device attribute (of my sample device driver) in
the sysfs. (DEVICE_ATTR) which is the address of the variable in the
user space. I get the current->mm to get the current task memory
descriptor and use it to walk the pages. Once I get the pte address I
reboot and dump the memory at that point using u-boot. (md.b  1)
but I do not find the value present there.

Sample code: (This is just for illustration and experimenting and does
not contain error checks etc.).


ssize_t process_mem_test_attr_store(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t count)
{

struct task_struct *current_task;
unsigned long addr_res;
struct vm_area_struct *vmarea_struct_addr;
pgd_t *pgd;
pmd_t *pmd;
pud_t *pud;
pte_t *ptep, pte;
struct page *page;
int kval;
int uval;

DEFINE_SPINLOCK(test_lock);

spin_lock_irq(&test_lock);

current_task = current;

if(current_task != NULL) {

printk(KERN_ALERT "\nCurrent task pid: %d\n",
current_task->pid);

printk(KERN_ALERT "mm: 0x%lx, active_mm 0x%lx\n",
current_task->mm,current_task->active_mm);
printk(KERN_ALERT "Page global directory : 0x%lx\n",
current_task->mm->pgd);
printk(KERN_ALERT "mmap base : 0x%lx",
current_task->mm->mmap_base);

vmarea_struct_addr = current_task->mm->mmap;

while(vmarea_struct_addr != NULL) {
printk(KERN_ALERT "vm_start : 0x%lx, vm_end : 0x%lx\n",
vmarea_struct_addr->vm_start,
vmarea_struct_addr->vm_end);

vmarea_struct_addr = vmarea_struct_addr->vm_next;
}


} else {
printk(KERN_ALERT "Current task NULL\n");
}

if(kstrtol(buf,10,&addr_res) != 0) {
printk(KERN_ALERT "Error converting to long\n");
return count;
}

copy_from_user(&kval,(unsigned int *)addr_res,4);

printk(KERN_ALERT "kval : %x\n",kval);
printk(KERN_ALERT "addr: %lx\n",addr_res);

pgd = pgd_offset(current_task->mm,addr_res);

if(pgd_none(*pgd) || pgd_bad(*pgd)) {
printk(KERN_ALERT "pgd bad\n");
return count;
} else {
printk(KERN_ALERT "pgd 0x%lx\n",pgd);
}

pud = pud_offset(pgd,addr_res);

if(pud_none(*pud) || pud_bad(*pud)) {
printk(KERN_ALERT "pud bad\n");
return count;
} else {
printk(KERN_ALERT "pud 0x%lx\n",pud);
}

pmd = pmd_offset(pud,addr_res);

if(pmd_none(*pmd) || pmd_bad(*pmd)) {
printk(KERN_ALERT "pmd bad\n");
return count;
} else {
printk(KERN_ALERT "pmd 0x%lx\n",pmd);
}


ptep = pte_offset_map(pmd,addr_res);
if(!ptep) {
printk(KERN_ALERT "ptep bad\n");
} else {
printk(KERN_ALERT "ptep 0x%lx\n",ptep);
}

pte = *ptep;


if(pte_present(pte)) {
printk(KERN_ALERT "pte : 0x%lx\n",pte);
page = pte_page(pte);

} else {
printk(KERN_ALERT "pte not present\n");
}

printk(KERN_ALERT "pte with offset 0x%lx offset : 0x%lx\n",
pte+((addr_res) & ((1

Re: On virt_to_phys doubts.

2014-09-29 Thread mind entropy
Thanks. It set a byte in RAM and checked it using md.b in u-boot.

-Gautam.

On Sat, Sep 13, 2014 at 10:20 PM, Miles MH Chen  wrote:
> ok, now we can say the virt_to_phys returns a correct physical address.
> 0x32d01fe0. It is a physical address, not a simple offset in dram. Your 64Mb
> dram has physical address within 0x3000 ~ 0x3400.
>
> MH
>
> 2014/9/13 下午9:52 於 "mind entropy"  寫道:
>
>> On Sat, Sep 13, 2014 at 7:13 PM, Miles MH Chen 
>> wrote:
>> > Kernel physical addr : 0x32d01fe0
>> > Platform phys offset : 0x3000
>> > Page offset : 0xc0553fb4
>> >
>> > The page offset looks weird, since 32bit kernel has 2/2 or 3/1 or 1/3
>> > user/kernel virtual address  split. It is not reasonable to have
>> > 0xc0553fb4
>> > as page offset. You should c000 for 3/1 split.
>> >
>>
>> My fault. I had done "0x%llx" in printk. Now I just did a %x and it
>> shows as 0xc000.
>>
>> -Gautam.

___
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies


Re: On virt_to_phys doubts.

2014-09-13 Thread mind entropy
On Sat, Sep 13, 2014 at 7:13 PM, Miles MH Chen  wrote:
> Kernel physical addr : 0x32d01fe0
> Platform phys offset : 0x3000
> Page offset : 0xc0553fb4
>
> The page offset looks weird, since 32bit kernel has 2/2 or 3/1 or 1/3
> user/kernel virtual address  split. It is not reasonable to have 0xc0553fb4
> as page offset. You should c000 for 3/1 split.
>

My fault. I had done "0x%llx" in printk. Now I just did a %x and it
shows as 0xc000.

-Gautam.

___
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies


Re: On virt_to_phys doubts.

2014-09-13 Thread mind entropy
On Sat, Sep 13, 2014 at 2:01 PM, Miles MH Chen  wrote:
> Hi,
>
> Do you know the value of PHYS_OFFSET of your platform?
> PHYS_OFFSET defines the starting physical address of your DRAM.
>
> physical address = kmalloc'ed address - PAGE_OFFSET + PHYS_OFFSET
>
> MH
>
> On Sat, Sep 13, 2014 at 4:02 PM, mind entropy  wrote:
>>
>> Hi,
>>
>>   I want to know the physical address [just for debugging and info.Not
>> for DMA etc] of a particular virtual address allocated via kmalloc.
>>
>>I am running the below code on S3C2440 with 64MB of RAM. The
>> /proc/meminfo returns
>>
>> MemTotal:  59164 kB
>> MemFree:   35884 kB
>> MemAvailable:  47148 kB
>>
>>
>>   I run the following module for printing the addresses. [This module
>> is only for test. So excuse if I have cut corners].
>>
>> 
>>
>> #include 
>> #include 
>> #include 
>> #include 
>> #include 
>> #include 
>> #include 
>> #include 
>> #include 
>>
>> static int vm_mem_test_init(void)
>> {
>>
>> void *km;
>>
>> printk(KERN_ALERT "vm mem test init\n");
>>
>> km = kmalloc(1,GFP_KERNEL);
>>
>> if(km == NULL) {
>> printk(KERN_ALERT "Could not kmalloc\n");
>> return -1;
>> } else {
>> printk(KERN_ALERT "Allocated\n");
>> printk(KERN_ALERT "Virtual addr : %x\n",(unsigned int)km);
>> printk(KERN_ALERT "Kernel physical addr :
>> 0x%x\n",virt_to_phys(km));
>> kfree(km);
>> }
>>
>>   return 0;
>>
>> }
>>
>>
>> The output for the following is:
>>
>> Virtual addr : c2c080e0
>> Kernel physical addr : 0x32c080e0
>>
>> ---
>>
>> The kernel physical address is wrong as I only have 64MB. Should I be
>> doing a kernel page table walk to get the associated physical address?
>>
>> Thanks
>> Gautam.
>>
>> ___
>> Kernelnewbies mailing list
>> Kernelnewbies@kernelnewbies.org
>> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>
>

Miles,

  I tried printing it. The output is as follows:

Kernel physical addr : 0x32d01fe0
Platform phys offset : 0x3000
Page offset : 0xc0553fb4

The S3C2440 is an ARM9TDMI processor.


-Gautam.

___
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies


On virt_to_phys doubts.

2014-09-13 Thread mind entropy
Hi,

  I want to know the physical address [just for debugging and info.Not
for DMA etc] of a particular virtual address allocated via kmalloc.

   I am running the below code on S3C2440 with 64MB of RAM. The
/proc/meminfo returns

MemTotal:  59164 kB
MemFree:   35884 kB
MemAvailable:  47148 kB


  I run the following module for printing the addresses. [This module
is only for test. So excuse if I have cut corners].



#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

static int vm_mem_test_init(void)
{

void *km;

printk(KERN_ALERT "vm mem test init\n");

km = kmalloc(1,GFP_KERNEL);

if(km == NULL) {
printk(KERN_ALERT "Could not kmalloc\n");
return -1;
} else {
printk(KERN_ALERT "Allocated\n");
printk(KERN_ALERT "Virtual addr : %x\n",(unsigned int)km);
printk(KERN_ALERT "Kernel physical addr : 0x%x\n",virt_to_phys(km));
kfree(km);
}

  return 0;

}


The output for the following is:

Virtual addr : c2c080e0
Kernel physical addr : 0x32c080e0

---

The kernel physical address is wrong as I only have 64MB. Should I be
doing a kernel page table walk to get the associated physical address?

Thanks
Gautam.

___
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies


On platform device template.

2014-08-10 Thread mind entropy
Hi,

  I am testing out the platform driver and would like to know the
template for platform device register/unregister.

  The following code causes a crash whenever the device gets unregistered.

---
#include 
#include 
#include 
#include 
#include 
#include 

struct test_platform_data {
int x;
int y;
};

static struct test_platform_data test_pd = {
.x = 2,
.y = 3,
};

static struct platform_device test_platform_device = {
.name = "test-plat",
.id = -1,
.resource = NULL,
.num_resources = 0,
.dev = {
.platform_data = &test_pd,
}
};

static int __init platform_driver_test_init(void) {
int retval = 0;

printk(KERN_ALERT "Platform driver init\n");

retval = platform_device_register(&test_platform_device);

if(retval != 0) {
printk(KERN_ALERT "Could not register platform device\n");
return retval;
} else {
printk(KERN_ALERT "Registered platform device\n");
printk(KERN_ALERT "Unregistering\n");

platform_device_unregister(&test_platform_device);

}

return 0;
}

static void __exit platform_driver_test_exit(void) {
printk(KERN_ALERT "Platform driver exit\n");
}

module_init(platform_driver_test_init);
module_exit(platform_driver_test_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("TEST");
MODULE_DESCRIPTION("Platform driver test");

---

Should the platform device be created using platform_device_alloc(..)
and added using platform_device_add(..)  like the below code?



#include 
#include 
#include 
#include 
#include 
#include 

struct test_platform_data {
int x;
int y;
};

static struct test_platform_data test_pd = {
.x = 2,
.y = 3,
};


static struct platform_device *test_platform_device;

static int __init platform_driver_test_init(void) {
int retval = 0;

printk(KERN_ALERT "Platform driver init\n");

test_platform_device = platform_device_alloc("test-plat",-1);

if(test_platform_device == NULL) {
printk(KERN_ALERT "Could not allocate platform device\n");

return 0;
}

platform_device_add_data(test_platform_device,&test_pd,sizeof(test_pd));

retval = platform_device_add(test_platform_device);

if(retval != 0) {
printk(KERN_ALERT "Could not register platform device\n");
return retval;
} else {
printk(KERN_ALERT "Registered platform device\n");
printk(KERN_ALERT "Unregistering\n");

platform_device_unregister(test_platform_device);

}


return 0;
}

static void __exit platform_driver_test_exit(void) {
printk(KERN_ALERT "Platform driver exit\n");
}

module_init(platform_driver_test_init);
module_exit(platform_driver_test_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("TEST");
MODULE_DESCRIPTION("Platform driver test");




Thanks,
Gautam.

___
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies


On SPI stress testing on a mini2440 board.

2013-10-03 Thread mind entropy
Hi,

  I have a mini2440 board to which I have connected a TI MSP430 G2553
microcontroller. I am communicating via SPI from the mini2440 master
to the MSP430 microcontroller slave. I am having a problem though. I
have to put a chip select delay and hence I am waiting for 500 uS
using udelay. Sometimes the data seems to skip or cause glitches when
the load is high I think. I had connected 2 microcontrollers and it
works fine when I stress test it. In case of the mini2440 board after
quite some hours of continuous transfers I get glitches. Is udelay
consistent?

Thanks,
Gautam.

___
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies