Re: [PATCH v2] dmaengine: ioatdma: Add intr_coalesce sysfs entry

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

 



On Wed, Jul 19, 2017 at 07:25:41PM -0400, Ujjal Singh wrote:
> We observed performance increase with DMA copy from memory
> to MMIO by changing the interrupt coalescing value to 0.
> The previous set value was projected on the C5xxx Xeon
> platform and no longer holds true. Removing hard coded
> value and providing a tune-able in sysfs in order to allow
> user to tune this on a per channel basis. By default this
> value will be set to 0.
> Example of sysfs variable importing for interrupt coalescing
> value from command line:
> echo 5> /sys/devices/pci0000:00/0000:00:04.0/dma/dma0chan0/
> quickdata/intr_coalesce
> 
> Reported-by: Nithin Sujir <nsujir@xxxxxxxxxx>
> Signed-off-by: Ujjal Singh <ujjal.singh@xxxxxxxxx>
> ---
> V2: Addressed Dave's comments:
> > Removed definition INTR_DELAY_REG_LIMIT in hw.h and used 
> > existing definition IOAT_INTRDELAY_MASK instead to check
> > interrupt delay limit in sysfs.c
> 
> Vinod's comment about ABI doc will come in a different patch
> to add ABI doc for ioatdma.

Sure, but we should send that first and add ABI documentation for this new
file in current patch or part of this series

> 
>  drivers/dma/ioat/dma.c   |   10 +++++++---
>  drivers/dma/ioat/dma.h   |    3 +++
>  drivers/dma/ioat/sysfs.c |   42 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 52 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
> index a371b07..f70cc74 100644
> --- a/drivers/dma/ioat/dma.c
> +++ b/drivers/dma/ioat/dma.c
> @@ -644,9 +644,13 @@ static void __cleanup(struct ioatdma_chan *ioat_chan, dma_addr_t phys_complete)
>  		mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT);
>  	}
>  
> -	/* 5 microsecond delay per pending descriptor */
> -	writew(min((5 * (active - i)), IOAT_INTRDELAY_MASK),
> -	       ioat_chan->ioat_dma->reg_base + IOAT_INTRDELAY_OFFSET);
> +	/* microsecond delay by sysfs variable  per pending descriptor */
> +	if (ioat_chan->intr_coalesce != ioat_chan->prev_intr_coalesce) {
> +		writew(min((ioat_chan->intr_coalesce * (active - i)),
> +		       IOAT_INTRDELAY_MASK),
> +		       ioat_chan->ioat_dma->reg_base + IOAT_INTRDELAY_OFFSET);
> +		ioat_chan->prev_intr_coalesce = ioat_chan->intr_coalesce;
> +	}
>  }
>  
>  static void ioat_cleanup(struct ioatdma_chan *ioat_chan)
> diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h
> index a9bc1a1..56200ee 100644
> --- a/drivers/dma/ioat/dma.h
> +++ b/drivers/dma/ioat/dma.h
> @@ -142,11 +142,14 @@ struct ioatdma_chan {
>  	spinlock_t prep_lock;
>  	struct ioat_descs descs[2];
>  	int desc_chunks;
> +	int intr_coalesce;
> +	int prev_intr_coalesce;
>  };
>  
>  struct ioat_sysfs_entry {
>  	struct attribute attr;
>  	ssize_t (*show)(struct dma_chan *, char *);
> +	ssize_t (*store)(struct dma_chan *, const char *, size_t);
>  };
>  
>  /**
> diff --git a/drivers/dma/ioat/sysfs.c b/drivers/dma/ioat/sysfs.c
> index cb4a857..3ac677f 100644
> --- a/drivers/dma/ioat/sysfs.c
> +++ b/drivers/dma/ioat/sysfs.c
> @@ -64,8 +64,24 @@ ioat_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
>  	return entry->show(&ioat_chan->dma_chan, page);
>  }
>  
> +static ssize_t
> +ioat_attr_store(struct kobject *kobj, struct attribute *attr,
> +const char *page, size_t count)
> +{
> +	struct ioat_sysfs_entry *entry;
> +	struct ioatdma_chan *ioat_chan;
> +
> +	entry = container_of(attr, struct ioat_sysfs_entry, attr);
> +	ioat_chan = container_of(kobj, struct ioatdma_chan, kobj);
> +
> +	if (!entry->store)
> +		return -EIO;
> +	return entry->store(&ioat_chan->dma_chan, page, count);
> +}
> +
>  const struct sysfs_ops ioat_sysfs_ops = {
>  	.show	= ioat_attr_show,
> +	.store  = ioat_attr_store,
>  };
>  
>  void ioat_kobject_add(struct ioatdma_device *ioat_dma, struct kobj_type *type)
> @@ -121,11 +137,37 @@ static ssize_t ring_active_show(struct dma_chan *c, char *page)
>  }
>  static struct ioat_sysfs_entry ring_active_attr = __ATTR_RO(ring_active);
>  
> +static ssize_t intr_coalesce_show(struct dma_chan *c, char *page)
> +{
> +	struct ioatdma_chan *ioat_chan = to_ioat_chan(c);
> +
> +	return sprintf(page, "%d\n", ioat_chan->intr_coalesce);
> +}
> +
> +static ssize_t intr_coalesce_store(struct dma_chan *c, const char *page,
> +size_t count)
> +{
> +	int intr_coalesce = 0;
> +	struct ioatdma_chan *ioat_chan = to_ioat_chan(c);
> +
> +	if (sscanf(page, "%du", &intr_coalesce) != -1) {
> +		if ((intr_coalesce < 0) ||
> +		    (intr_coalesce > IOAT_INTRDELAY_MASK))
> +			return -EINVAL;
> +		ioat_chan->intr_coalesce = intr_coalesce;
> +	}
> +
> +	return count;
> +}
> +
> +static struct ioat_sysfs_entry intr_coalesce_attr = __ATTR_RW(intr_coalesce);
> +
>  static struct attribute *ioat_attrs[] = {
>  	&ring_size_attr.attr,
>  	&ring_active_attr.attr,
>  	&ioat_cap_attr.attr,
>  	&ioat_version_attr.attr,
> +	&intr_coalesce_attr.attr,
>  	NULL,
>  };
>  
> 

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



[Index of Archives]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux PCI]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux