MAP_NR(x)

From: Russell King (rmk@arm.linux.org.uk)
Date: Sat May 06 2000 - 18:58:15 EST


Hi,

I'm currently in the process of integrating some discontig memory support
into the ARM architecture, and I've been looking at the change to MAP_NR()
for to achieve this.

The resulting arithmetic appears to be overly complex for MAP_NR(x):

        (((x) - ((x) & const) >> const) +
         ((&node_data[((x) - const) >> const]->node_mem_map) - cont) / const)

whereas the old contiguous version was:

        (((x) - const) >> const)

(I've replaced all the constants with "const" for readability). Obviously
the discontiguous version requires a lot of alu ops to calculate!

Now, MAP_NR is used in essentially one of two ways in the arch/*/mm/* and
mm/* code:

        mem_map + MAP_NR(x)
        MAP_NR(x) > max_mapnr

What I'd like to propose is to get rid of MAP_NR and instead have a macro
that returned a pointer to the relevent mem_map entry itself. Therefore,
your typical contiguous MAP_ENT(x) macro would be:

        (mem_map + (((x) - const) >> const))

ie,

#define MAP_ENT(addr) (mem_map + ((__pa(addr) - PHYS_OFFSET) >> PAGE_SHIFT))

For the discontiguous case, MAP_ENT(x) would be:

        ((&node_data[((x) - const) >> const]->node_mem_map) +
          (((x) & const) >> const))

ie,

#define MAP_ENT(addr) \
        (ADDR_TO_MAPBASE((addr)) + (((addr) & (NODE_MAX_MEM_SIZE - 1)) >> PAGE_SHIFT))

This means that we are no longer dependent on the alignment of the node page
maps (I hope - I haven't been through all the references yet), with the exception
of the test with MAP_NR(x) > max_mapnr.

I believe that this test is bogus. If you have the following mem_map
(p = page, h = hole):

<node0 ><node1 ><node2 >
pppphhhhpppphhhhpppp

Surely you want to trap out the holes in this test? If so, then the current code
is going a rather long way about achieving something that is not really effective.
I therefore propose a "MAP_ADDR_VALID(x)" macro.

In the contiguous case, it would simply be:

#define MAP_ADDR_VALID(addr) (MAP_ENT(addr) - mem_map < max_mapnr)

For the discontiguous case:

#define MAP_ADDR_VALID(addr) \
        ((addr) < NODE_DATA(KVADDR_TO_NID((addr))->node_max_kaddr)

node_max_addr would replace node_start_mapnr, which is only ever initialised and
never subsequently referenced.

I've probably missed something major which throws this idea out, so
comments and/or suggestions welcome. Flames to /dev/null please.

Should this be copied to the linux-mm list as well?
   _____
  |_____| ------------------------------------------------- ---+---+-
  | | Russell King rmk@arm.linux.org.uk --- ---
  | | | | http://www.arm.linux.org.uk/~rmk/aboutme.html / / |
  | +-+-+ --- -+-
  / | THE developer of ARM Linux |+| /|\
 / | | | --- |
    +-+-+ ------------------------------------------------- /\\\ |

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun May 07 2000 - 21:00:20 EST