RE: [PATCH V4 10/12] misc: xilinx_sdfec: Add stats & status ioctls

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

 




> -----Original Message-----
> From: Greg KH [mailto:gregkh@xxxxxxxxxxxxxxxxxxx]
> Sent: Thursday 6 June 2019 15:12
> To: Dragan Cvetic <draganc@xxxxxxxxxx>
> Cc: arnd@xxxxxxxx; Michal Simek <michals@xxxxxxxxxx>; linux-arm-kernel@xxxxxxxxxxxxxxxxxxx; robh+dt@xxxxxxxxxx;
> mark.rutland@xxxxxxx; devicetree@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; Derek Kiernan <dkiernan@xxxxxxxxxx>
> Subject: Re: [PATCH V4 10/12] misc: xilinx_sdfec: Add stats & status ioctls
> 
> On Sat, May 25, 2019 at 12:37:23PM +0100, Dragan Cvetic wrote:
> > SD-FEC statistic data are:
> > - count of data interface errors (isr_err_count)
> > - count of Correctable ECC errors (cecc_count)
> > - count of Uncorrectable ECC errors (uecc_count)
> >
> > Add support:
> > 1. clear stats ioctl callback which clears collected
> > statistic data,
> > 2. get stats ioctl callback which reads a collected
> > statistic data,
> > 3. set default configuration ioctl callback,
> > 4. start ioctl callback enables SD-FEC HW,
> > 5. stop ioctl callback disables SD-FEC HW.
> >
> > In a failed state driver enables the following ioctls:
> > - get status
> > - get statistics
> > - clear stats
> > - set default SD-FEC device configuration
> >
> > Tested-by: Santhosh Dyavanapally <SDYAVANA@xxxxxxxxxx>
> > Tested by: Punnaiah Choudary Kalluri <punnaia@xxxxxxxxxx>
> > Tested-by: Derek Kiernan <derek.kiernan@xxxxxxxxxx>
> > Tested-by: Dragan Cvetic <dragan.cvetic@xxxxxxxxxx>
> > Signed-off-by: Derek Kiernan <derek.kiernan@xxxxxxxxxx>
> > Signed-off-by: Dragan Cvetic <dragan.cvetic@xxxxxxxxxx>
> > ---
> >  drivers/misc/xilinx_sdfec.c      | 121 +++++++++++++++++++++++++++++++++++++++
> >  include/uapi/misc/xilinx_sdfec.h |  75 ++++++++++++++++++++++++
> >  2 files changed, 196 insertions(+)
> >
> > diff --git a/drivers/misc/xilinx_sdfec.c b/drivers/misc/xilinx_sdfec.c
> > index 544e746..6e04492 100644
> > --- a/drivers/misc/xilinx_sdfec.c
> > +++ b/drivers/misc/xilinx_sdfec.c
> > @@ -189,6 +189,7 @@ struct xsdfec_clks {
> >   * @dev: pointer to device struct
> >   * @state: State of the SDFEC device
> >   * @config: Configuration of the SDFEC device
> > + * @intr_enabled: indicates IRQ enabled
> >   * @state_updated: indicates State updated by interrupt handler
> >   * @stats_updated: indicates Stats updated by interrupt handler
> >   * @isr_err_count: Count of ISR errors
> > @@ -207,6 +208,7 @@ struct xsdfec_dev {
> >  	struct device *dev;
> >  	enum xsdfec_state state;
> >  	struct xsdfec_config config;
> > +	bool intr_enabled;
> >  	bool state_updated;
> >  	bool stats_updated;
> >  	atomic_t isr_err_count;
> > @@ -290,6 +292,26 @@ static int xsdfec_dev_release(struct inode *iptr, struct file *fptr)
> >  	return 0;
> >  }
> >
> > +static int xsdfec_get_status(struct xsdfec_dev *xsdfec, void __user *arg)
> > +{
> > +	struct xsdfec_status status;
> > +	int err;
> > +
> > +	status.fec_id = xsdfec->config.fec_id;
> > +	spin_lock_irqsave(&xsdfec->irq_lock, xsdfec->flags);
> > +	status.state = xsdfec->state;
> > +	xsdfec->state_updated = false;
> > +	spin_unlock_irqrestore(&xsdfec->irq_lock, xsdfec->flags);
> > +	status.activity = (xsdfec_regread(xsdfec, XSDFEC_ACTIVE_ADDR) &
> > +			   XSDFEC_IS_ACTIVITY_SET);
> > +
> > +	err = copy_to_user(arg, &status, sizeof(status));
> > +	if (err)
> > +		err = -EFAULT;
> > +
> > +	return err;
> > +}
> > +
> >  static int xsdfec_get_config(struct xsdfec_dev *xsdfec, void __user *arg)
> >  {
> >  	int err;
> > @@ -850,6 +872,80 @@ static int xsdfec_cfg_axi_streams(struct xsdfec_dev *xsdfec)
> >  	return 0;
> >  }
> >
> > +static int xsdfec_start(struct xsdfec_dev *xsdfec)
> > +{
> > +	u32 regread;
> > +
> > +	regread = xsdfec_regread(xsdfec, XSDFEC_FEC_CODE_ADDR);
> > +	regread &= 0x1;
> > +	if (regread != xsdfec->config.code) {
> > +		dev_dbg(xsdfec->dev,
> > +			"%s SDFEC HW code does not match driver code, reg %d, code %d",
> > +			__func__, regread, xsdfec->config.code);
> > +		return -EINVAL;
> > +	}
> > +
> > +	/* Set AXIS enable */
> > +	xsdfec_regwrite(xsdfec, XSDFEC_AXIS_ENABLE_ADDR,
> > +			XSDFEC_AXIS_ENABLE_MASK);
> > +	/* Done */
> > +	xsdfec->state = XSDFEC_STARTED;
> > +	return 0;
> > +}
> > +
> > +static int xsdfec_stop(struct xsdfec_dev *xsdfec)
> > +{
> > +	u32 regread;
> > +
> > +	if (xsdfec->state != XSDFEC_STARTED)
> > +		dev_dbg(xsdfec->dev, "Device not started correctly");
> > +	/* Disable AXIS_ENABLE Input interfaces only */
> > +	regread = xsdfec_regread(xsdfec, XSDFEC_AXIS_ENABLE_ADDR);
> > +	regread &= (~XSDFEC_AXIS_IN_ENABLE_MASK);
> > +	xsdfec_regwrite(xsdfec, XSDFEC_AXIS_ENABLE_ADDR, regread);
> > +	/* Stop */
> > +	xsdfec->state = XSDFEC_STOPPED;
> > +	return 0;
> > +}
> > +
> > +static int xsdfec_clear_stats(struct xsdfec_dev *xsdfec)
> > +{
> > +	atomic_set(&xsdfec->isr_err_count, 0);
> > +	atomic_set(&xsdfec->uecc_count, 0);
> > +	atomic_set(&xsdfec->cecc_count, 0);
> 
> Atomics for counters?  Are you sure?  Don't we have some sort of sane
> counter api these days for stuff like this instead of abusing atomic
> variables?  What does the networking people use?  How often/fast do
> these change that you need to synchronize things?

Accepted.
No need to have them atomic. They are lock protected already.

> 
> > +
> > +	return 0;
> > +}
> > +
> > +static int xsdfec_get_stats(struct xsdfec_dev *xsdfec, void __user *arg)
> > +{
> > +	int err;
> > +	struct xsdfec_stats user_stats;
> > +
> > +	spin_lock_irqsave(&xsdfec->irq_lock, xsdfec->flags);
> > +	user_stats.isr_err_count = atomic_read(&xsdfec->isr_err_count);
> > +	user_stats.cecc_count = atomic_read(&xsdfec->cecc_count);
> > +	user_stats.uecc_count = atomic_read(&xsdfec->uecc_count);
> > +	xsdfec->stats_updated = false;
> > +	spin_unlock_irqrestore(&xsdfec->irq_lock, xsdfec->flags);
> 
> Wait, you just grabbed a lock, and then read atomic variables, why?  Why
> do these need to be atomic variables if you are already locking around
> them?  Unless you want to be "extra sure" they are safe?  :)

Accepted.
Absolutely no need for atomic variables.
 
> 
> Please fix up.
> 
> thanks,
> 
> greg k-h




[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux