[patch 1/2] clean up tce build functions

Anton Blanchard anton at samba.org
Mon Aug 30 15:44:32 EST 2004


Hi Dave,

> The tce_build* functions currently take a virtual address as an
> unsigned long.  Each implementation also does its own page alignment
> of that address.
>
> Create a global tce_build() for all platforms, do the page alignment
> there.  Also, change the type of uaddr to be an 'unsigned char*' so
> that we can do arithmetic on it, but it is still a pointer to
> differentiate it from the 'unsigned long' usually used for physical
> addresses.
>
> Create sglist_vaddr() and sglist_size_pages() to hide some of the
> nasty casting that goes on.  Note that this will perform the
> sglist_vaddr() operation an extra time.  We could get around it by
> computing it once and passing it into sglist_size_pages() but, unless
> this is a hot path, it's probably not worth it.
>
> The patch does add more lines of code than it removes, but that's due
> to adding some helper functions.  The common path has a bunch of
> casts, masks, and shifts removed.

Olof has some stuff pending in this area (to support the multiple TCE
entry interface in the hypervisor). Id prefer to hold off until that
is merged.

Anton

> Tested on pSeries, but not iSeries or pmac.
>
> Signed-off-by: Dave Hansen <haveblue at us.ibm.com>
> ---
>
>  memhotplug-dave/arch/ppc64/kernel/iSeries_iommu.c |    2 -
>  memhotplug-dave/arch/ppc64/kernel/iommu.c         |   30 +++++++++++++++-------
>  memhotplug-dave/arch/ppc64/kernel/pSeries_iommu.c |    2 -
>  memhotplug-dave/arch/ppc64/kernel/pSeries_lpar.c  |    4 +-
>  memhotplug-dave/arch/ppc64/kernel/pmac_iommu.c    |    2 -
>  memhotplug-dave/include/asm-ppc64/machdep.h       |   10 ++++++-
>  6 files changed, 35 insertions(+), 15 deletions(-)
>
> diff -puN arch/ppc64/kernel/iommu.c~A7-ppc64-tce-build-vaddr arch/ppc64/kernel/iommu.c
> --- memhotplug/arch/ppc64/kernel/iommu.c~A7-ppc64-tce-build-vaddr	2004-08-23 11:25:19.000000000 -0700
> +++ memhotplug-dave/arch/ppc64/kernel/iommu.c	2004-08-23 11:25:19.000000000 -0700
> @@ -159,8 +159,7 @@ static dma_addr_t iommu_alloc(struct iom
>  	ret = entry << PAGE_SHIFT;	/* Set the return dma address */
>
>  	/* Put the TCEs in the HW table */
> -	ppc_md.tce_build(tbl, entry, npages, (unsigned long)page & PAGE_MASK,
> -			 direction);
> +	tce_build(tbl, entry, npages, page, direction);
>
>
>  	/* Flush/invalidate TLB caches if necessary */
> @@ -225,6 +224,21 @@ static void iommu_free(struct iommu_tabl
>  	spin_unlock_irqrestore(&(tbl->it_lock), flags);
>  }
>
> +static inline void *sglist_vaddr(struct scatterlist *s)
> +{
> +	return (void *)((unsigned long)page_address(s->page) + s->offset);
> +}
> +
> +static inline unsigned long sglist_size_pages(struct scatterlist *s)
> +{
> +	unsigned long vaddr, len;
> +
> +	vaddr = (unsigned long)sglist_vaddr(s);
> +	len = PAGE_ALIGN(vaddr + s->length) - (vaddr & PAGE_MASK);
> +
> +	return len >> PAGE_SHIFT;
> +}
> +
>  int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
>  		struct scatterlist *sglist, int nelems,
>  		enum dma_data_direction direction)
> @@ -252,7 +266,7 @@ int iommu_map_sg(struct device *dev, str
>  	spin_lock_irqsave(&(tbl->it_lock), flags);
>
>  	for (s = outs; nelems; nelems--, s++) {
> -		unsigned long vaddr, npages, entry, slen;
> +		unsigned long npages, entry, slen;
>
>  		slen = s->length;
>  		/* Sanity check */
> @@ -261,9 +275,7 @@ int iommu_map_sg(struct device *dev, str
>  			continue;
>  		}
>  		/* Allocate iommu entries for that segment */
> -		vaddr = (unsigned long)page_address(s->page) + s->offset;
> -		npages = PAGE_ALIGN(vaddr + slen) - (vaddr & PAGE_MASK);
> -		npages >>= PAGE_SHIFT;
> +		npages = sglist_size_pages(s);
>  		entry = iommu_range_alloc(tbl, npages, &handle);
>
>  		DBG("  - vaddr: %lx, size: %lx\n", vaddr, slen);
> @@ -271,8 +283,8 @@ int iommu_map_sg(struct device *dev, str
>  		/* Handle failure */
>  		if (unlikely(entry == DMA_ERROR_CODE)) {
>  			if (printk_ratelimit())
> -				printk(KERN_INFO "iommu_alloc failed, tbl %p vaddr %lx"
> -				       " npages %lx\n", tbl, vaddr, npages);
> +				printk(KERN_INFO "iommu_alloc failed, tbl %p vaddr %p"
> +				       " npages %lx\n", tbl, sglist_vaddr(s), npages);
>  			goto failure;
>  		}
>
> @@ -285,7 +297,7 @@ int iommu_map_sg(struct device *dev, str
>  			    npages, entry, dma_addr);
>
>  		/* Insert into HW table */
> -		ppc_md.tce_build(tbl, entry, npages, vaddr & PAGE_MASK, direction);
> +		tce_build(tbl, entry, npages, sglist_vaddr(s), direction);
>
>  		/* If we are in an open segment, try merging */
>  		if (segstart != s) {
> diff -puN arch/ppc64/kernel/iSeries_iommu.c~A7-ppc64-tce-build-vaddr arch/ppc64/kernel/iSeries_iommu.c
> --- memhotplug/arch/ppc64/kernel/iSeries_iommu.c~A7-ppc64-tce-build-vaddr	2004-08-23 11:25:19.000000000 -0700
> +++ memhotplug-dave/arch/ppc64/kernel/iSeries_iommu.c	2004-08-23 11:25:19.000000000 -0700
> @@ -54,7 +54,7 @@ extern struct list_head iSeries_Global_D
>
>
>  static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages,
> -		unsigned long uaddr, enum dma_data_direction direction)
> +		unsigned char *uaddr, enum dma_data_direction direction)
>  {
>  	u64 rc;
>  	union tce_entry tce;
> diff -puN arch/ppc64/kernel/pSeries_iommu.c~A7-ppc64-tce-build-vaddr arch/ppc64/kernel/pSeries_iommu.c
> --- memhotplug/arch/ppc64/kernel/pSeries_iommu.c~A7-ppc64-tce-build-vaddr	2004-08-23 11:25:19.000000000 -0700
> +++ memhotplug-dave/arch/ppc64/kernel/pSeries_iommu.c	2004-08-23 11:25:19.000000000 -0700
> @@ -46,7 +46,7 @@
>
>
>  static void tce_build_pSeries(struct iommu_table *tbl, long index,
> -			      long npages, unsigned long uaddr,
> +			      long npages, unsigned char *uaddr,
>  			      enum dma_data_direction direction)
>  {
>  	union tce_entry t;
> diff -puN arch/ppc64/kernel/pmac_iommu.c~A7-ppc64-tce-build-vaddr arch/ppc64/kernel/pmac_iommu.c
> --- memhotplug/arch/ppc64/kernel/pmac_iommu.c~A7-ppc64-tce-build-vaddr	2004-08-23 11:25:19.000000000 -0700
> +++ memhotplug-dave/arch/ppc64/kernel/pmac_iommu.c	2004-08-23 11:25:19.000000000 -0700
> @@ -141,7 +141,7 @@ static void dart_flush(struct iommu_tabl
>  }
>
>  static void dart_build_pmac(struct iommu_table *tbl, long index,
> -			    long npages, unsigned long uaddr,
> +			    long npages, unsigned char *uaddr,
>  			    enum dma_data_direction direction)
>  {
>  	unsigned int *dp;
> diff -puN arch/ppc64/kernel/pSeries_lpar.c~A7-ppc64-tce-build-vaddr arch/ppc64/kernel/pSeries_lpar.c
> --- memhotplug/arch/ppc64/kernel/pSeries_lpar.c~A7-ppc64-tce-build-vaddr	2004-08-23 11:25:19.000000000 -0700
> +++ memhotplug-dave/arch/ppc64/kernel/pSeries_lpar.c	2004-08-23 11:25:19.000000000 -0700
> @@ -131,8 +131,8 @@ long plpar_put_term_char(unsigned long t
>  }
>
>  static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
> -		long npages, unsigned long uaddr,
> -		enum dma_data_direction direction)
> +				long npages, unsigned char *uaddr,
> +				enum dma_data_direction direction)
>  {
>  	u64 rc;
>  	union tce_entry tce;
> diff -puN include/asm-ppc64/machdep.h~A7-ppc64-tce-build-vaddr include/asm-ppc64/machdep.h
> --- memhotplug/include/asm-ppc64/machdep.h~A7-ppc64-tce-build-vaddr	2004-08-23 11:25:19.000000000 -0700
> +++ memhotplug-dave/include/asm-ppc64/machdep.h	2004-08-23 11:25:19.000000000 -0700
> @@ -60,7 +60,7 @@ struct machdep_calls {
>  	void		(*tce_build)(struct iommu_table * tbl,
>  				     long index,
>  				     long npages,
> -				     unsigned long uaddr,
> +				     unsigned char *uaddr,
>  				     enum dma_data_direction direction);
>  	void		(*tce_free)(struct iommu_table *tbl,
>  				    long index,
> @@ -132,6 +132,14 @@ void ppc64_attention_msg(unsigned int sr
>  /* Print a dump progress message. */
>  void ppc64_dump_msg(unsigned int src, const char *msg);
>
> +static inline void tce_build(struct iommu_table * tbl, long index, long npages,
> +			     void *uaddr, enum dma_data_direction direction)
> +{
> +	unsigned char *page_addr = (unsigned char *)((unsigned long)uaddr & PAGE_MASK);
> +
> +	ppc_md.tce_build(tbl, index, npages, page_addr, direction);
> +}
> +
>  static inline void log_error(char *buf, unsigned int err_type, int fatal)
>  {
>  	if (ppc_md.log_error)
> diff -L A8-ppc64-pfn_to_kaddr -puN /dev/null /dev/null
> _

** Sent via the linuxppc64-dev mail list. See http://lists.linuxppc.org/





More information about the Linuxppc64-dev mailing list