Subject: Re: [PATCH] powerpc/iommu: remove default window before creating larger window

From: Nishanth Aravamudan <[email-masked]>
Date: Mon, 31 Oct 2011 15:47:40 -0700

Hi Ben,

Please don't take this patch :)

While, it does work around some issues I'm tracking down, it can lead
to worse ones if we are unable to configure the larger DMA window, or if
some functions in a PE don't use 64-bit DMA masks.

Thanks,
Nish

On 26.10.2011 [15:43:23 -0700], Nishanth Aravamudan wrote:
> The DDW feature relies on there being sufficient TCE space to allocate
> for the requested DMA window size. The default window uses up some of
> that space, though, and it is recommended to first remove the default
> window and then allocate the larger window advertised by firmware. Do
> this by abstracting out parts of remove_ddw into a function that does
> not assume an existing larger window has been created.
> 
> Signed-off-by: Nishanth Aravamudan <[email-masked]>
> ---
>  arch/powerpc/platforms/pseries/iommu.c |   35 +++++++++++++++++++++++--------
>  1 files changed, 26 insertions(+), 9 deletions(-)
> 
> Is there a better way to get the default window's LIOBN than to call
> of_parse_dma_window?
> 
> diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
> index 01faab9..afcc04c 100644
> --- a/arch/powerpc/platforms/pseries/iommu.c
> +++ b/arch/powerpc/platforms/pseries/iommu.c
> @@ -655,6 +655,21 @@ static int __init disable_ddw_setup(char *str)
>  
>  early_param("disable_ddw", disable_ddw_setup);
>  
> +static void __remove_ddw(struct device_node *np, const u32 *ddw_avail, u64 liobn)
> +{
> +	int ret;
> +
> +	ret = rtas_call(ddw_avail[2], 1, 1, NULL, liobn);
> +	if (ret)
> +		pr_warning("%s: failed to remove direct window: rtas returned "
> +			"%d to ibm,remove-pe-dma-window(%x) %llx\n",
> +			np->full_name, ret, ddw_avail[2], liobn);
> +	else
> +		pr_debug("%s: successfully removed direct window: rtas returned "
> +			"%d to ibm,remove-pe-dma-window(%x) %llx\n",
> +			np->full_name, ret, ddw_avail[2], liobn);
> +}
> +
>  static void remove_ddw(struct device_node *np)
>  {
>  	struct dynamic_dma_window_prop *dwp;
> @@ -684,15 +699,7 @@ static void remove_ddw(struct device_node *np)
>  		pr_debug("%s successfully cleared tces in window.\n",
>  			 np->full_name);
>  
> -	ret = rtas_call(ddw_avail[2], 1, 1, NULL, liobn);
> -	if (ret)
> -		pr_warning("%s: failed to remove direct window: rtas returned "
> -			"%d to ibm,remove-pe-dma-window(%x) %llx\n",
> -			np->full_name, ret, ddw_avail[2], liobn);
> -	else
> -		pr_debug("%s: successfully removed direct window: rtas returned "
> -			"%d to ibm,remove-pe-dma-window(%x) %llx\n",
> -			np->full_name, ret, ddw_avail[2], liobn);
> +	__remove_ddw(np, ddw_avail, liobn);
>  
>  delprop:
>  	ret = prom_remove_property(np, win64);
> @@ -843,6 +850,8 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
>  	struct direct_window *window;
>  	struct property *win64;
>  	struct dynamic_dma_window_prop *ddwprop;
> +	const void *dma_window = NULL;
> +	unsigned long liobn, offset, size;
>  
>  	mutex_lock(&direct_window_init_mutex);
>  
> @@ -918,6 +927,14 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
>  		goto out_free_prop;
>  	}
>  
> +	/*
> +	 * To maximize the resources available to the create RTAS call,
> +	 * delete the existing DMA window
> +	 */
> +	dma_window = of_get_property(pdn, "ibm,dma-window", NULL);
> +	of_parse_dma_window(pdn, dma_window, &liobn, &offset, &size);
> +	__remove_ddw(pdn, ddw_avail, liobn);
> +
>  	ret = create_ddw(dev, ddw_avail, &create, page_shift, len);
>  	if (ret != 0)
>  		goto out_free_prop;
> -- 
> 1.7.5.4
> 
> 
> -- 
> Nishanth Aravamudan <[email-masked]>
> IBM Linux Technology Center

-- 
Nishanth Aravamudan <[email-masked]>
IBM Linux Technology Center