title: What does mmap actually return?
body: <p>I'm a little confused as to how to define the address an mmap call actually returns probably because I saw a piece of code where this address is converted to <code>uint64_t</code> and used as a physical address.
  If it is a virtual address, and we need a physical address can it be found out using a formula where a modulo with the pagesize etc is involved after opening proc/self/map. Just being abstract with it.</p>
  
  <p>Does it matter how we treat this address with or without hugepages?</p>
  
  <p>Also, if what kind of address is suitable for being classified as a DMA-ABLE address. Going over through code samples, in kernel we use <code>pci_alloc_consistent</code> and <code>pci_map_single</code> to find the dma addresses. Suppose in a userspace application, I wish to dma TO/FROM device and allocate a portion of memory via malloc or mmap for its tx and rx rings and I want the physical address associated with this address. Should I just use type conversion <code>uint64_t(addr)</code>  or write a function to convert this virtual address to physical address equivalent to a dma handle returned by pci alloc consistent.</p>
  
  <p>Adding a sample from Open Source DPDK Code</p>
  
  <pre><code>    mcfg = rte_eal_get_configuration()-&gt;mem_config;
  
  /* hugetlbfs can be disabled */
  if (internal_config.no_hugetlbfs) {
      addr = mmap(NULL, internal_config.memory, PROT_READ | PROT_WRITE,
              MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
      if (addr == MAP_FAILED) {
          RTE_LOG(ERR, EAL, "%s: mmap() failed: %s\n", __func__,
                  strerror(errno));
          return -1;
      }
      mcfg-&gt;memseg[0].phys_addr = (phys_addr_t)(uintptr_t)addr;  -----???
      mcfg-&gt;memseg[0].addr = addr;
      mcfg-&gt;memseg[0].len = internal_config.memory;
      mcfg-&gt;memseg[0].socket_id = SOCKET_ID_ANY;
      return 0;
  }
  </code></pre>
  
  <p>In the other case it would convert the address mmaped from hugepages to a physical address via this.</p>
  
  <pre><code>    /*
   * Get physical address of any mapped virtual address in the current process.
   */
  phys_addr_t
  rte_mem_virt2phy(const void *virtaddr)
  {
      int fd;
      uint64_t page, physaddr;
      unsigned long virt_pfn;
      int page_size;
      off_t offset;
  
      /* standard page size */
      page_size = getpagesize();
  
      fd = open("/proc/self/pagemap", O_RDONLY);
      if (fd &lt; 0) {
          RTE_LOG(ERR, EAL, "%s(): cannot open /proc/self/pagemap: %s\n",
              __func__, strerror(errno));
          return RTE_BAD_PHYS_ADDR;
      }
  
      virt_pfn = (unsigned long)virtaddr / page_size;
      offset = sizeof(uint64_t) * virt_pfn;
      if (lseek(fd, offset, SEEK_SET) == (off_t) -1) {
          RTE_LOG(ERR, EAL, "%s(): seek error in /proc/self/pagemap: %s\n",
                  __func__, strerror(errno));
          close(fd);
          return RTE_BAD_PHYS_ADDR;
      }
      if (read(fd, &amp;page, sizeof(uint64_t)) &lt; 0) {
          RTE_LOG(ERR, EAL, "%s(): cannot read /proc/self/pagemap: %s\n",
                  __func__, strerror(errno));
          close(fd);
          return RTE_BAD_PHYS_ADDR;
      }
  
      /*
       * the pfn (page frame number) are bits 0-54 (see
       * pagemap.txt in linux Documentation)
       */
      physaddr = ((page &amp; 0x7fffffffffffffULL) * page_size)
          + ((unsigned long)virtaddr % page_size);
      close(fd);
      return physaddr;
  }
  </code></pre>