MAP_NR(x)

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

  • Next message: Lawrence Manning: "bonnie and 2.3.99-pre6-7+classzone24"

    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 : Sat May 06 2000 - 20:03:07 EDT