Re: [PATCH] SQUASHME pmem: Micro optimization for pmem_direct_access

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

 



On Wed, 2014-09-10 at 19:50 +0300, Boaz Harrosh wrote:
> From: Boaz Harrosh <boaz@xxxxxxxxxxxxx>
> 
> Please note: This patch spans two patches in the set:
> 
> * The changes to pmem_lookup_pg_addr from [patch 1/4]
> * The removal to pmem_lookup_pfn and changes to pmem_direct_access
>   from [patch 4/4]
> 
> This is the hotpath I care about / pmem_direct_access()
> Easier on the eyes too
> Signed-off-by: Boaz Harrosh <boaz@xxxxxxxxxxxxx>
> ---
>  drivers/block/pmem.c | 20 ++++++--------------
>  1 file changed, 6 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/block/pmem.c b/drivers/block/pmem.c
> index 5eda95a..4a9d65e 100644
> --- a/drivers/block/pmem.c
> +++ b/drivers/block/pmem.c
> @@ -61,22 +61,12 @@ static int pmem_getgeo(struct block_device *bd, struct hd_geometry *geo)
>   */
>  static void *pmem_lookup_pg_addr(struct pmem_device *pmem, sector_t sector)
>  {
> -	size_t page_offset = sector >> PAGE_SECTORS_SHIFT;
> -	size_t offset = page_offset << PAGE_SHIFT;
> +	size_t offset = sector << SECTOR_SHIFT;

You just broke the "The return value will point to the beginning of the page
containing the given sector, not to the sector itself." part of the contract
spelled out in the comments.  This means that when you have an I/O that starts
at a sector that isn't page aligned, copy_to_pmem() or copy_from_pmem() will
get back a pointer to the *sector*, not the *page*, and the memcopy that takes
into account the offset will do the wrong thing.

>  	BUG_ON(offset >= pmem->size);
>  	return pmem->virt_addr + offset;
>  }
>  
> -/* sector must be page aligned */
> -static unsigned long pmem_lookup_pfn(struct pmem_device *pmem, sector_t sector)
> -{
> -	size_t page_offset = sector >> PAGE_SECTORS_SHIFT;
> -
> -	BUG_ON(sector & (PAGE_SECTORS - 1));
> -	return (pmem->phys_addr >> PAGE_SHIFT) + page_offset;
> -}
> -
>  /*
>   * sector is not required to be page aligned.
>   * n is at most a single page, but could be less.
> @@ -200,14 +190,16 @@ static long pmem_direct_access(struct block_device *bdev, sector_t sector,
>  			      void **kaddr, unsigned long *pfn, long size)
>  {
>  	struct pmem_device *pmem = bdev->bd_disk->private_data;
> +	size_t offset = sector << SECTOR_SHIFT;
>  
>  	if (!pmem)
>  		return -ENODEV;
>  
> -	*kaddr = pmem_lookup_pg_addr(pmem, sector);
> -	*pfn = pmem_lookup_pfn(pmem, sector);
> +	BUG_ON(offset >= pmem->size);

No need to add this - bounds checking is done in bdev_direct_access().

> +	*kaddr = pmem->virt_addr + offset;
> +	*pfn = (pmem->phys_addr + offset) >> PAGE_SHIFT;
>  
> -	return pmem->size - (sector * 512);
> +	return pmem->size - offset;
>  }
>  
>  static const struct block_device_operations pmem_fops = {


--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux