Re: ioremap problem

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dear Rene,

Thank you very much for your descriptive answer.
got to know a lot of things.

What I understood is passing vmalloc is a good way for
the time being but the best way seems to be changing
the offset in the include/asm/page.h  file.
Then one can get the advantage of whole 1G of physical
memory.

Thank you very very much.
Sumudu


----- Original Message ----- From: "Rene Herman" <rene.herman@xxxxxxxxxxxx>
To: "Sumudu Nishantha" <sumudun@xxxxxxxxx>
Cc: <kernelnewbies@xxxxxxxxxxxx>
Sent: Friday, November 23, 2007 1:49 AM
Subject: Re: ioremap problem


On 22-11-07 17:08, Rene Herman wrote:

I am new to this group as well as to the driver development.
I am developing a PCI driver with the following specification.
 CPU      : Intel celeron M 1.4GHz
memory   : 1GB
kernel   : kernel 2.6.15-r1
swap     : 4GB
 my driver works well with 512M RAM but it gives an error when I
use 1GB of RAM. Error occurs at ioremap() function.
    *ptr = ioremap(base,length)     length here is 128MB
The error asks to increase kernel memory space with vmalloc.
Then I gave vmalloc as a kernel parameter (vmalloc=256M)
in grub.conf. it went well in this way.
 Is this the way to overcome this problem or is it due to some other
problems?(old kernel etc.)
 I can't update the kernel since the driver is being developed for a
customer specific machine which is already used.

Basically, the best way to overcome it is start using a 64-bit architecture but I suppose that's not much of an option either then...

128M is quite a bit, and indeed too much for an untweaked kernel. See, the 4GB 32-bit address-space is shared between user- and kernel-space, and in the default arrangement, user-space gets the lower 3GB and kernel-space the top 1GB.

Inside that latter 1G, the kernel first directly maps physical memory and uses the remaining address-space between 3G+PHYS_MEM and 4G for vmalloc, ioremap and a few other specialized uses. So, with 512M of physical memory, the kernel has 512M of address-space left between 3.5G and 4G for vmalloc/ioremap purposes and everything works out fine with your 128M claim on it.

However, with 1GB of physical memory you see that isn't going to work. In fact, you see that without any other special arrangements there would not be _any_ address-space left for ioremap and that ofcourse won't do.

The kernel therefore reserves some amount of address-space, VMALLOC_RESERVE, for vmalloc/ioremap and limits the amount of permanently mapped memory (so called "lowmem") to 1G-VMALLOC_RESERVE and treats the rest as "highmem" which is mapped and unmapped as needed. And see, VMALLOC_RESERVE by default is 128M meaning your one 128M claim is just a little too big -- the area is needed by a few other uses as well as said.

There are a couple of possible solutions. You can first simply increase VMALLOC_RESERVE (to 256M, say) and recompile the kernel. You then automatically also increase the percentage of memory that is used as highmem and whether or not that's important is specific to your use. Highmem is a little slower at least and using highmem might require you to look at local code that might not be prepared to deal with non-permanently mapped memory at all (you need highmem to have all of the 1G visible now as well, but perhaps you hadn't noticed yet).

The second solution is adjusting the VM split down somewhat, from 3G/1G for user/kernel to say 2.75G/1.25G. You'd then not need highmem and still have 256M left for vmalloc/ioremap.

And in fact, in current kernels, that very split is selectable through the kernel config to allow people with 1G to use all of their memory without having to deal with highmem. If I remember correctly, in 2.6.15 you (only) need to adjust the two PAGE_OFFSET defines in include/asm/page.h (one for C, one for assembly) from 0xc0000000 to 0xb0000000 and recompile.

Note that given the config choice in later kernels, this should be fairly well tested on those later kernels at least but that you might still get into trouble if your use involves running things such as VMWARE that aren't prepared to deal with the non-standard split. If it breaks, you get to keep the pieces...

So VMALLOC_RESERVE++ or PAGE_OFFSET-- or/and best of all, make sure everyone knows 32-bit architectures stopped being a good idea once physical memory went over 768M or so.

Oh and I should add that passing the vmalloc command line option is ofcourse basically the same as increasing VMALLOC_RESERVE at compile time, so instead of doing that, you might as well keep passing it. The PAGE_OFFSET tweaks are the meat of the reply though.

Rene.


--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux