Re: [RFC PATCH] mm, oom: introduce vm.sacrifice_hugepage_on_oom

2021-02-16 Thread Michal Hocko
On Tue 16-02-21 14:30:15, Mike Kravetz wrote:
[...]
> However, this is an 'opt in' feature.  So, I would not expect anyone who
> carefully plans the size of their hugetlb pool to enable such a feature.
> If there is a use case where hugetlb pages are used in a non-essential
> application, this might be of use.

I would really like to hear about the specific usecase. Because it
smells more like a misconfiguration. What would be non-essential hugetlb
pages? This is not a resource to be pre-allocated just in case, right?

-- 
Michal Hocko
SUSE Labs


Re: [RFC PATCH] mm, oom: introduce vm.sacrifice_hugepage_on_oom

2021-02-16 Thread Michal Hocko
On Tue 16-02-21 13:53:12, David Rientjes wrote:
> On Tue, 16 Feb 2021, Michal Hocko wrote:
[...]
> > Overall, I am not really happy about this feature even when above is
> > fixed, but let's hear more the actual problem first.
> 
> Shouldn't this behavior be possible as an oomd plugin instead, perhaps 
> triggered by psi?  I'm not sure if oomd is intended only to kill something 
> (oomkilld? lol) or if it can be made to do sysadmin level behavior, such 
> as shrinking the hugetlb pool, to solve the oom condition.

It should be under control of an admin who knows what the pool is
preallocated for and whether a decrease (e.g. a temporal one) is
tolerable.
 
> If so, it seems like we want to do this at the absolute last minute.  In 
> other words, reclaim has failed to free memory by other means so we would 
> like to shrink the hugetlb pool.  (It's the reason why it's implemented as 
> a predecessor to oom as opposed to part of reclaim in general.)
> 
> Do we have the ability to suppress the oom killer until oomd has a chance 
> to react in this scenario?

We don't and I do not think we want to bind the kernel oom behavior to
any userspace process. We have extensively discussed things like this in
the past IIRC.

-- 
Michal Hocko
SUSE Labs


Re: [Intel-gfx] [PATCH v2] drm/i915/gen9bc: Handle TGP PCH during suspend/resume

2021-02-16 Thread Imre Deak
On Tue, Feb 16, 2021 at 09:36:01PM -0500, Lyude Paul wrote:
> On Tue, 2021-02-16 at 20:08 +0200, Imre Deak wrote:
> > Hi,
> > 
> > thanks for respinning this patchset, some comments below.
> > 
> > On Fri, Feb 12, 2021 at 01:50:53PM -0500, Lyude Paul wrote:
> > > From: Tejas Upadhyay 
> > > 
> > > For Legacy S3 suspend/resume GEN9 BC needs to enable and
> > > setup TGP PCH.
> > > 
> > > v2:
> > > * Move Wa_14010685332 into it's own function - vsyrjala
> > > * Add TODO comment about figuring out if we can move this workaround - 
> > > imre
> > > 
> > > Cc: Matt Roper 
> > > Signed-off-by: Tejas Upadhyay 
> > > 
> > > Signed-off-by: Lyude Paul 
> > > ---
> > >  drivers/gpu/drm/i915/i915_irq.c | 53 ++---
> > >  1 file changed, 36 insertions(+), 17 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/i915_irq.c
> > > b/drivers/gpu/drm/i915/i915_irq.c
> > > index 98145a7f28a4..7d912aa950ee 100644
> > > --- a/drivers/gpu/drm/i915/i915_irq.c
> > > +++ b/drivers/gpu/drm/i915/i915_irq.c
> > > @@ -3040,6 +3040,19 @@ static void valleyview_irq_reset(struct
> > > drm_i915_private *dev_priv)
> > > spin_unlock_irq(_priv->irq_lock);
> > >  }
> > >  
> > > +static void cnp_irq_post_reset(struct drm_i915_private *dev_priv)
> > 
> > Maybe a better name is cnp_display_clock_wa.
> > 
> > > +{
> > > +   struct intel_uncore *uncore = _priv->uncore;
> > > +
> > > +   /*
> > > +    * Wa_14010685332:cnp/cmp,tgp,adp
> > 
> > Bspec says this WA applies ICL onwards and it's not PCH specific, for
> > instance I haven't found the GEN9/CNP/CMP WA entries for it. Please also
> > add a 'clarify platforms where this applies' todo item.
> > 
> > > +    * TODO: Figure out if this workaround can be applied in the s0ix
> > > suspend/resume handlers as
> > > +    * on earlier platforms and whether the workaround is also needed
> > > for runtime suspend/resume
> > > +    */
> > > +   intel_uncore_rmw(uncore, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS,
> > > SBCLK_RUN_REFCLK_DIS);
> > > +   intel_uncore_rmw(uncore, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS, 0);
> > > +}
> > > +
> > >  static void gen8_irq_reset(struct drm_i915_private *dev_priv)
> > >  {
> > > struct intel_uncore *uncore = _priv->uncore;
> > > @@ -3061,8 +3074,14 @@ static void gen8_irq_reset(struct drm_i915_private
> > > *dev_priv)
> > > GEN3_IRQ_RESET(uncore, GEN8_DE_MISC_);
> > > GEN3_IRQ_RESET(uncore, GEN8_PCU_);
> > >  
> > > -   if (HAS_PCH_SPLIT(dev_priv))
> > > +   if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
> > 
> > It was mentioned already earlier, why is this check necessary and can't we
> > just call ibx_irq_reset() for all PCHs?
> > 
> > > +   GEN3_IRQ_RESET(uncore, SDE);
> > > +   else if (HAS_PCH_SPLIT(dev_priv))
> > > ibx_irq_reset(dev_priv);
> > > +
> > > +   if (INTEL_PCH_TYPE(dev_priv) == PCH_CNP ||
> > > +   (INTEL_PCH_TYPE(dev_priv) >= PCH_TGP && 
> > > INTEL_PCH_TYPE(dev_priv)
> > > < PCH_DG1))
> > 
> > The check could be also moved to the helper.
> > 
> > > +   cnp_irq_post_reset(dev_priv);
> > >  }
> > >  
> > >  static void gen11_display_irq_reset(struct drm_i915_private *dev_priv)
> > > @@ -3104,15 +3123,9 @@ static void gen11_display_irq_reset(struct
> > > drm_i915_private *dev_priv)
> > > if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
> > > GEN3_IRQ_RESET(uncore, SDE);
> > >  
> > > -   /* Wa_14010685332:cnp/cmp,tgp,adp */
> > > if (INTEL_PCH_TYPE(dev_priv) == PCH_CNP ||
> > > -   (INTEL_PCH_TYPE(dev_priv) >= PCH_TGP &&
> > > -    INTEL_PCH_TYPE(dev_priv) < PCH_DG1)) {
> > > -   intel_uncore_rmw(uncore, SOUTH_CHICKEN1,
> > > -    SBCLK_RUN_REFCLK_DIS,
> > > SBCLK_RUN_REFCLK_DIS);
> > > -   intel_uncore_rmw(uncore, SOUTH_CHICKEN1,
> > > -    SBCLK_RUN_REFCLK_DIS, 0);
> > > -   }
> > > +   (INTEL_PCH_TYPE(dev_priv) >= PCH_TGP && 
> > > INTEL_PCH_TYPE(dev_priv)
> > > < PCH_DG1))
> > > +   cnp_irq_post_reset(dev_priv);
> > >  }
> > >  
> > >  static void gen11_irq_reset(struct drm_i915_private *dev_priv)
> > > @@ -3474,6 +3487,9 @@ static void spt_hpd_irq_setup(struct 
> > > drm_i915_private
> > > *dev_priv)
> > > ibx_display_interrupt_update(dev_priv, hotplug_irqs, 
> > > enabled_irqs);
> > >  
> > > spt_hpd_detection_setup(dev_priv);
> > > +
> > > +   if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
> > > +   icp_hpd_irq_setup(dev_priv);
> > 
> > This doesn't look correct, icp_hpd_irq_setup() redoes the interrupt
> > setup done already earlier in this function and
> > spt_hpd_detection_setup() is probably also not correct on ICP+. Looks
> > like for ICP+ we need to call icp_hpd_irq_setup() instead of
> > spt_hpd_irq_setup(), but haven't checked in detail.
> 
> Could you please check :)? I don't work at Intel so you have far more access 

[PATCH v2 bpf-next] bpf: fix a warning message in mark_ptr_not_null_reg()

2021-02-16 Thread Dan Carpenter
The WARN_ON() argument is a condition, not an error message.  So this
code will print a stack trace but will not print the warning message.
Fix that and also change it to only WARN_ONCE().

Fixes: 4ddb74165ae5 ("bpf: Extract nullable reg type conversion into a helper 
function")
Signed-off-by: Dan Carpenter 
---
v2:  Use WARN_ONCE().

 kernel/bpf/verifier.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 1dda9d81f12c..3d34ba492d46 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1120,7 +1120,7 @@ static void mark_ptr_not_null_reg(struct bpf_reg_state 
*reg)
reg->type = PTR_TO_RDWR_BUF;
break;
default:
-   WARN_ON("unknown nullable register type");
+   WARN_ONCE(1, "unknown nullable register type");
}
 }
 
-- 
2.30.0



Re: [PATCH v5 1/5] dt-bindings: aspeed-lpc: Remove LPC partitioning

2021-02-16 Thread Joel Stanley
Hi Chaiwei,

On Wed, 17 Feb 2021 at 07:40, ChiaWei Wang  wrote:
>
> Hi All,
>
> Do you have update on this patch series?
> Aspeed has subsequent LPC module upstream plan.
> We hope that the following patches can be on the basis of the fixed LPC 
> layout.

Andrew has expressed his support for your changes. I will take time to
closely review your proposal this week.

We will set the goal of having this rework merged for the next merge window.

Cheers,

Joel


> Thanks.
>
> Chiawei
>
> > -Original Message-
> > From: Andrew Jeffery 
> > Sent: Wednesday, January 27, 2021 8:25 AM
> > To: Lee Jones 
> > Subject: Re: [PATCH v5 1/5] dt-bindings: aspeed-lpc: Remove LPC partitioning
> >
> >
> >
> > On Thu, 14 Jan 2021, at 23:46, Chia-Wei, Wang wrote:
> > > The LPC controller has no concept of the BMC and the Host partitions.
> > > This patch fixes the documentation by removing the description on LPC
> > > partitions. The register offsets illustrated in the DTS node examples
> > > are also fixed to adapt to the LPC DTS change.
> > >
> > > Signed-off-by: Chia-Wei, Wang 
> >
> > Any thoughts Lee? If you ack it would you be happy for the patch to go 
> > through
> > the Aspeed tree?
> >
> > Andrew


RE: [PATCH v5 1/5] dt-bindings: aspeed-lpc: Remove LPC partitioning

2021-02-16 Thread ChiaWei Wang
Hi All,

Do you have update on this patch series?
Aspeed has subsequent LPC module upstream plan.
We hope that the following patches can be on the basis of the fixed LPC layout.
Thanks.

Chiawei

> -Original Message-
> From: Andrew Jeffery 
> Sent: Wednesday, January 27, 2021 8:25 AM
> To: Lee Jones 
> Subject: Re: [PATCH v5 1/5] dt-bindings: aspeed-lpc: Remove LPC partitioning
> 
> 
> 
> On Thu, 14 Jan 2021, at 23:46, Chia-Wei, Wang wrote:
> > The LPC controller has no concept of the BMC and the Host partitions.
> > This patch fixes the documentation by removing the description on LPC
> > partitions. The register offsets illustrated in the DTS node examples
> > are also fixed to adapt to the LPC DTS change.
> >
> > Signed-off-by: Chia-Wei, Wang 
> 
> Any thoughts Lee? If you ack it would you be happy for the patch to go through
> the Aspeed tree?
> 
> Andrew


[PATCH][RESEND] iio: dac: ad5686: Add support for AD5673R/AD5677R

2021-02-16 Thread Alexandru Ardelean
From: Mircea Caprioru 

The AD5673R/AD5677R are low power, 16-channel, 12-/16-bit buffered voltage
output digital-to-analog converters (DACs). They include a 2.5 V internal
reference (enabled by default).

These devices are very similar to AD5674R/AD5679R, except that they
have an i2c interface.

Signed-off-by: Mircea Caprioru 
Signed-off-by: Alexandru Ardelean 
---

Forgot to include the linux-iio list in the first send.

 drivers/iio/dac/Kconfig  |  5 +++--
 drivers/iio/dac/ad5686.c | 12 
 drivers/iio/dac/ad5686.h |  2 ++
 drivers/iio/dac/ad5696-i2c.c |  6 --
 4 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
index cea07b4cced1..75e1f2b48638 100644
--- a/drivers/iio/dac/Kconfig
+++ b/drivers/iio/dac/Kconfig
@@ -142,8 +142,9 @@ config AD5696_I2C
select AD5686
help
  Say yes here to build support for Analog Devices AD5311R, AD5338R,
- AD5671R, AD5675R, AD5691R, AD5692R, AD5693, AD5693R, AD5694, AD5694R,
- AD5695R, AD5696, and AD5696R Digital to Analog converters.
+ AD5671R, AD5673R, AD5675R, AD5677R, AD5691R, AD5692R, AD5693, AD5693R,
+ AD5694, AD5694R, AD5695R, AD5696, and AD5696R Digital to Analog
+ converters.
 
  To compile this driver as a module, choose M here: the module will be
  called ad5696.
diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c
index 7d6792ac1020..99a95282ac57 100644
--- a/drivers/iio/dac/ad5686.c
+++ b/drivers/iio/dac/ad5686.c
@@ -301,6 +301,12 @@ static const struct ad5686_chip_info 
ad5686_chip_info_tbl[] = {
.num_channels = 8,
.regmap_type = AD5686_REGMAP,
},
+   [ID_AD5673R] = {
+   .channels = ad5674r_channels,
+   .int_vref_mv = 2500,
+   .num_channels = 16,
+   .regmap_type = AD5686_REGMAP,
+   },
[ID_AD5674R] = {
.channels = ad5674r_channels,
.int_vref_mv = 2500,
@@ -324,6 +330,12 @@ static const struct ad5686_chip_info 
ad5686_chip_info_tbl[] = {
.num_channels = 8,
.regmap_type = AD5686_REGMAP,
},
+   [ID_AD5677R] = {
+   .channels = ad5679r_channels,
+   .int_vref_mv = 2500,
+   .num_channels = 16,
+   .regmap_type = AD5686_REGMAP,
+   },
[ID_AD5679R] = {
.channels = ad5679r_channels,
.int_vref_mv = 2500,
diff --git a/drivers/iio/dac/ad5686.h b/drivers/iio/dac/ad5686.h
index d9c8ba413fe9..f89a6f92b427 100644
--- a/drivers/iio/dac/ad5686.h
+++ b/drivers/iio/dac/ad5686.h
@@ -55,10 +55,12 @@ enum ad5686_supported_device_ids {
ID_AD5338R,
ID_AD5671R,
ID_AD5672R,
+   ID_AD5673R,
ID_AD5674R,
ID_AD5675R,
ID_AD5676,
ID_AD5676R,
+   ID_AD5677R,
ID_AD5679R,
ID_AD5681R,
ID_AD5682R,
diff --git a/drivers/iio/dac/ad5696-i2c.c b/drivers/iio/dac/ad5696-i2c.c
index a39eda7c02d2..24a6a4a5a2e0 100644
--- a/drivers/iio/dac/ad5696-i2c.c
+++ b/drivers/iio/dac/ad5696-i2c.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * AD5671R, AD5675R, AD5691R, AD5692R, AD5693, AD5693R,
- * AD5694, AD5694R, AD5695R, AD5696, AD5696R
+ * AD5338R, AD5671R, AD5673R, AD5675R, AD5677R, AD5691R, AD5692R, AD5693,
+ * AD5693R, AD5694, AD5694R, AD5695R, AD5696, AD5696R
  * Digital to analog converters driver
  *
  * Copyright 2018 Analog Devices Inc.
@@ -74,7 +74,9 @@ static const struct i2c_device_id ad5686_i2c_id[] = {
{"ad5311r", ID_AD5311R},
{"ad5338r", ID_AD5338R},
{"ad5671r", ID_AD5671R},
+   {"ad5673r", ID_AD5673R},
{"ad5675r", ID_AD5675R},
+   {"ad5677r", ID_AD5677R},
{"ad5691r", ID_AD5691R},
{"ad5692r", ID_AD5692R},
{"ad5693", ID_AD5693},
-- 
2.17.1



[PATCH v4 6/6] tools: iio: add example for high-speed buffer support

2021-02-16 Thread Alexandru Ardelean
Following a recent update to the IIO buffer infrastructure, this change
adds a basic example on how to access an IIO buffer via the new mmap()
interface.

The ioctl() for the high-speed mode needs to be enabled right from the
start, before setting any parameters via sysfs (length, enable, etc), to
make sure that the mmap mode is used and not the fileio mode.

Signed-off-by: Alexandru Ardelean 
---
 tools/iio/iio_generic_buffer.c | 185 +++--
 1 file changed, 179 insertions(+), 6 deletions(-)

diff --git a/tools/iio/iio_generic_buffer.c b/tools/iio/iio_generic_buffer.c
index 2491c54a5e4f..e7c327fa6091 100644
--- a/tools/iio/iio_generic_buffer.c
+++ b/tools/iio/iio_generic_buffer.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include "iio_utils.h"
 
@@ -239,6 +240,133 @@ static int enable_disable_all_channels(char 
*dev_dir_name, int buffer_idx, int e
return 0;
 }
 
+struct mmap_block {
+   struct iio_buffer_block block;
+   void *addr;
+};
+
+static struct mmap_block *enable_high_speed(int buf_fd, unsigned int 
block_size,
+   int nblocks)
+{
+   struct iio_buffer_block_alloc_req req = { 0 };
+   struct mmap_block *mmaps = NULL;
+   int mmaps_cnt = 0;
+   int i, ret;
+
+   /**
+* Validate we can do high-speed by issuing BLOCK_FREE ioctl.
+* If using just BLOCK_ALLOC it's distinguish between ENOSYS
+* and other error types.
+*/
+   ret = ioctl(buf_fd, IIO_BUFFER_BLOCK_FREE_IOCTL, 0);
+   if (ret < 0) {
+   errno = ENOSYS;
+   return NULL;
+   }
+
+   /* for now, this */
+   req.id = 0;
+   req.type = 0;
+   req.size = block_size;
+   req.count = nblocks;
+
+   ret = ioctl(buf_fd, IIO_BUFFER_BLOCK_ALLOC_IOCTL, );
+   if (ret < 0)
+   return NULL;
+
+   if (req.count == 0) {
+   errno = ENOMEM;
+   return NULL;
+   }
+
+   if (req.count < nblocks) {
+   fprintf(stderr, "Requested %d blocks, got %d\n",
+   nblocks, req.count);
+   errno = ENOMEM;
+   return NULL;
+   }
+
+   mmaps = calloc(req.count, sizeof(*mmaps));
+   if (!mmaps) {
+   errno = ENOMEM;
+   return NULL;
+   }
+
+   for (i = 0; i < req.count; i++) {
+   mmaps[i].block.id = i;
+   ret = ioctl(buf_fd, IIO_BUFFER_BLOCK_QUERY_IOCTL, 
[i].block);
+   if (ret < 0)
+   goto error;
+
+   ret = ioctl(buf_fd, IIO_BUFFER_BLOCK_ENQUEUE_IOCTL, 
[i].block);
+   if (ret < 0)
+   goto error;
+
+   mmaps[i].addr = mmap(0, mmaps[i].block.size,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ buf_fd, mmaps[i].block.data.offset);
+
+   if (mmaps[i].addr == MAP_FAILED)
+   goto error;
+
+   mmaps_cnt++;
+   }
+
+   return mmaps;
+
+error:
+   for (i = 0; i < mmaps_cnt; i++)
+   munmap(mmaps[i].addr, mmaps[i].block.size);
+   free(mmaps);
+   ioctl(buf_fd, IIO_BUFFER_BLOCK_FREE_IOCTL, 0);
+   return NULL;
+}
+
+static int read_high_speed(int buf_fd, char *data, unsigned int block_size,
+  struct mmap_block *mmaps, unsigned int mmaps_cnt)
+{
+   struct iio_buffer_block block;
+   int ret;
+
+   /**
+* This is where some buffer-pool management can do wonders,
+* but for the sake of this sample-code, we're just going to
+* copy the data and re-enqueue it back
+*/
+   memset(, 0, sizeof(block));
+   ret = ioctl(buf_fd, IIO_BUFFER_BLOCK_DEQUEUE_IOCTL, );
+   if (ret < 0)
+   return ret;
+
+   /* check for weird conditions */
+   if (block.bytes_used > block_size) {
+   fprintf(stderr,
+   "Got a bigger block (%u) than expected (%u)\n",
+   block.bytes_used, block_size);
+   return -EFBIG;
+   }
+
+   if (block.bytes_used < block_size) {
+   /**
+* This can be normal, with some real-world data
+* terminating abruptly. But log it.
+*/
+   fprintf(stderr,
+   "Got a smaller block (%u) than expected (%u)\n",
+   block.bytes_used, block_size);
+   }
+
+   /* memcpy() the data, we lose some more performance here :p */
+   memcpy(data, mmaps[block.id].addr, block.bytes_used);
+
+   /* and re-queue this back */
+   ret = ioctl(buf_fd, IIO_BUFFER_BLOCK_ENQUEUE_IOCTL, 
[block.id].block);
+   if (ret < 0)
+   return ret;
+
+   return block.bytes_used;
+}
+
 static void print_usage(void)
 {
fprintf(stderr, "Usage: generic_buffer 

[PATCH v4 5/6] iio: buffer-dma: Add mmap support

2021-02-16 Thread Alexandru Ardelean
From: Lars-Peter Clausen 

Add support for the new mmap interface to IIO DMA buffer. This interface
allows to directly map the backing memory of a block to userspace. This is
especially advantageous for high-speed devices where the extra copy from
kernel space to userspace of the data incurs a significant overhead.

In addition this interface allows more fine grained control over how many
blocks are allocated and their size.

Signed-off-by: Lars-Peter Clausen 
Signed-off-by: Alexandru Ardelean 
---
 drivers/iio/buffer/industrialio-buffer-dma.c  | 279 +-
 .../buffer/industrialio-buffer-dmaengine.c|  22 +-
 include/linux/iio/buffer-dma.h|  22 +-
 3 files changed, 306 insertions(+), 17 deletions(-)

diff --git a/drivers/iio/buffer/industrialio-buffer-dma.c 
b/drivers/iio/buffer/industrialio-buffer-dma.c
index 858af7eea53e..e187c1640b17 100644
--- a/drivers/iio/buffer/industrialio-buffer-dma.c
+++ b/drivers/iio/buffer/industrialio-buffer-dma.c
@@ -90,6 +90,9 @@
  * callback is called from within the custom callback.
  */
 
+static unsigned int iio_dma_buffer_max_block_size = SZ_16M;
+module_param_named(max_block_size, iio_dma_buffer_max_block_size, uint, 0644);
+
 static void iio_buffer_block_release(struct kref *kref)
 {
struct iio_dma_buffer_block *block = container_of(kref,
@@ -97,7 +100,7 @@ static void iio_buffer_block_release(struct kref *kref)
 
WARN_ON(block->state != IIO_BLOCK_STATE_DEAD);
 
-   dma_free_coherent(block->queue->dev, PAGE_ALIGN(block->size),
+   dma_free_coherent(block->queue->dev, PAGE_ALIGN(block->block.size),
block->vaddr, block->phys_addr);
 
iio_buffer_put(>queue->buffer);
@@ -178,7 +181,7 @@ static struct iio_dma_buffer_block 
*iio_dma_buffer_alloc_block(
return NULL;
}
 
-   block->size = size;
+   block->block.size = size;
block->state = IIO_BLOCK_STATE_DEQUEUED;
block->queue = queue;
INIT_LIST_HEAD(>head);
@@ -243,7 +246,7 @@ void iio_dma_buffer_block_list_abort(struct 
iio_dma_buffer_queue *queue,
spin_lock_irqsave(>list_lock, flags);
list_for_each_entry_safe(block, _block, list, head) {
list_del(>head);
-   block->bytes_used = 0;
+   block->block.bytes_used = 0;
_iio_dma_buffer_block_done(block);
iio_buffer_block_put_atomic(block);
}
@@ -296,6 +299,10 @@ int iio_dma_buffer_request_update(struct iio_buffer 
*buffer)
 
mutex_lock(>lock);
 
+   /* If in mmap mode dont do anything */
+   if (queue->num_blocks)
+   goto out_unlock;
+
/* Allocations are page aligned */
if (PAGE_ALIGN(queue->fileio.block_size) == PAGE_ALIGN(size))
try_reuse = true;
@@ -330,7 +337,7 @@ int iio_dma_buffer_request_update(struct iio_buffer *buffer)
iio_buffer_block_put(block);
block = NULL;
} else {
-   block->size = size;
+   block->block.size = size;
}
} else {
block = NULL;
@@ -345,6 +352,8 @@ int iio_dma_buffer_request_update(struct iio_buffer *buffer)
queue->fileio.blocks[i] = block;
}
 
+   block->block.id = i;
+
block->state = IIO_BLOCK_STATE_QUEUED;
list_add_tail(>head, >incoming);
}
@@ -428,6 +437,7 @@ int iio_dma_buffer_enable(struct iio_buffer *buffer,
struct iio_dma_buffer_block *block, *_block;
 
mutex_lock(>lock);
+   queue->fileio.enabled = !queue->num_blocks;
queue->active = true;
list_for_each_entry_safe(block, _block, >incoming, head) {
list_del(>head);
@@ -453,6 +463,7 @@ int iio_dma_buffer_disable(struct iio_buffer *buffer,
struct iio_dma_buffer_queue *queue = iio_buffer_to_queue(buffer);
 
mutex_lock(>lock);
+   queue->fileio.enabled = false;
queue->active = false;
 
if (queue->ops && queue->ops->abort)
@@ -514,6 +525,11 @@ int iio_dma_buffer_read(struct iio_buffer *buffer, size_t 
n,
 
mutex_lock(>lock);
 
+   if (!queue->fileio.enabled) {
+   ret = -EBUSY;
+   goto out_unlock;
+   }
+
if (!queue->fileio.active_block) {
block = iio_dma_buffer_dequeue(queue);
if (block == NULL) {
@@ -527,8 +543,8 @@ int iio_dma_buffer_read(struct iio_buffer *buffer, size_t n,
}
 
n = rounddown(n, buffer->bytes_per_datum);
-   if (n > block->bytes_used - queue->fileio.pos)
-   n = block->bytes_used - queue->fileio.pos;
+   if (n > block->block.bytes_used - queue->fileio.pos)
+   n = block->block.bytes_used - queue->fileio.pos;
 
if (copy_to_user(user_buffer, block->vaddr 

[PATCH v4 4/6] iio: buffer-dma: reduce the type of block.size to u32

2021-02-16 Thread Alexandru Ardelean
The type of the 'size' parameter in the block struct is size_t which is
64 bit wide on 64 bit archs.
When the mmap interface gets introduced, we will use a 32 bit field in the
block descriptor for the block size, which will cause some compiler-checks
to fail.

32 bits (4 GB) block sizes should be enough. The idea is to allocate more
blocks if the size of a block grows to 4 GB.

Signed-off-by: Alexandru Ardelean 
---
 drivers/iio/buffer/industrialio-buffer-dmaengine.c | 6 +++---
 include/linux/iio/buffer-dma.h | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c 
b/drivers/iio/buffer/industrialio-buffer-dmaengine.c
index d76179878ff9..19fbe5d9ef5b 100644
--- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c
+++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c
@@ -35,8 +35,8 @@ struct dmaengine_buffer {
struct dma_chan *chan;
struct list_head active;
 
-   size_t align;
-   size_t max_size;
+   u32 align;
+   u32 max_size;
 };
 
 static struct dmaengine_buffer *iio_buffer_to_dmaengine_buffer(
@@ -136,7 +136,7 @@ static ssize_t iio_dmaengine_buffer_get_length_align(struct 
device *dev,
struct dmaengine_buffer *dmaengine_buffer =
iio_buffer_to_dmaengine_buffer(buffer);
 
-   return sprintf(buf, "%zu\n", dmaengine_buffer->align);
+   return sprintf(buf, "%u\n", dmaengine_buffer->align);
 }
 
 static IIO_DEVICE_ATTR(length_align_bytes, 0444,
diff --git a/include/linux/iio/buffer-dma.h b/include/linux/iio/buffer-dma.h
index 6564bdcdac66..9de27d23e791 100644
--- a/include/linux/iio/buffer-dma.h
+++ b/include/linux/iio/buffer-dma.h
@@ -55,7 +55,7 @@ struct iio_dma_buffer_block {
 */
void *vaddr;
dma_addr_t phys_addr;
-   size_t size;
+   u32 size;
struct iio_dma_buffer_queue *queue;
 
/* Must not be accessed outside the core. */
-- 
2.17.1



[PATCH v4 3/6] iio: buffer-dma: split iio_dma_buffer_fileio_free() function

2021-02-16 Thread Alexandru Ardelean
A part of the logic in the iio_dma_buffer_exit() is required for the change
to add mmap support to IIO buffers.
This change splits the logic into a separate function, which will be
re-used later.

Signed-off-by: Alexandru Ardelean 
---
 drivers/iio/buffer/industrialio-buffer-dma.c | 45 +++-
 1 file changed, 25 insertions(+), 20 deletions(-)

diff --git a/drivers/iio/buffer/industrialio-buffer-dma.c 
b/drivers/iio/buffer/industrialio-buffer-dma.c
index d348af8b9705..858af7eea53e 100644
--- a/drivers/iio/buffer/industrialio-buffer-dma.c
+++ b/drivers/iio/buffer/industrialio-buffer-dma.c
@@ -356,6 +356,30 @@ int iio_dma_buffer_request_update(struct iio_buffer 
*buffer)
 }
 EXPORT_SYMBOL_GPL(iio_dma_buffer_request_update);
 
+static void iio_dma_buffer_fileio_free(struct iio_dma_buffer_queue *queue)
+{
+   unsigned int i;
+
+   spin_lock_irq(>list_lock);
+   for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) {
+   if (!queue->fileio.blocks[i])
+   continue;
+   queue->fileio.blocks[i]->state = IIO_BLOCK_STATE_DEAD;
+   }
+   INIT_LIST_HEAD(>outgoing);
+   spin_unlock_irq(>list_lock);
+
+   INIT_LIST_HEAD(>incoming);
+
+   for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) {
+   if (!queue->fileio.blocks[i])
+   continue;
+   iio_buffer_block_put(queue->fileio.blocks[i]);
+   queue->fileio.blocks[i] = NULL;
+   }
+   queue->fileio.active_block = NULL;
+}
+
 static void iio_dma_buffer_submit_block(struct iio_dma_buffer_queue *queue,
struct iio_dma_buffer_block *block)
 {
@@ -635,28 +659,9 @@ EXPORT_SYMBOL_GPL(iio_dma_buffer_init);
  */
 void iio_dma_buffer_exit(struct iio_dma_buffer_queue *queue)
 {
-   unsigned int i;
-
mutex_lock(>lock);
 
-   spin_lock_irq(>list_lock);
-   for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) {
-   if (!queue->fileio.blocks[i])
-   continue;
-   queue->fileio.blocks[i]->state = IIO_BLOCK_STATE_DEAD;
-   }
-   INIT_LIST_HEAD(>outgoing);
-   spin_unlock_irq(>list_lock);
-
-   INIT_LIST_HEAD(>incoming);
-
-   for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) {
-   if (!queue->fileio.blocks[i])
-   continue;
-   iio_buffer_block_put(queue->fileio.blocks[i]);
-   queue->fileio.blocks[i] = NULL;
-   }
-   queue->fileio.active_block = NULL;
+   iio_dma_buffer_fileio_free(queue);
queue->ops = NULL;
 
mutex_unlock(>lock);
-- 
2.17.1



[PATCH v4 2/6] Documentation: iio: add doc for high-speed buffer API

2021-02-16 Thread Alexandru Ardelean
This change takes the comment from the commit that introduces the IIO
high-speed buffer API, and formats it into rst format.

Signed-off-by: Alexandru Ardelean 
---
 Documentation/iio/iio_high_speed_buffers.rst | 100 +++
 Documentation/iio/index.rst  |   2 +
 include/uapi/linux/iio/buffer.h  |   5 +
 3 files changed, 107 insertions(+)
 create mode 100644 Documentation/iio/iio_high_speed_buffers.rst

diff --git a/Documentation/iio/iio_high_speed_buffers.rst 
b/Documentation/iio/iio_high_speed_buffers.rst
new file mode 100644
index ..f326e68efe49
--- /dev/null
+++ b/Documentation/iio/iio_high_speed_buffers.rst
@@ -0,0 +1,100 @@
+===
+Industrial IO High-Speed Buffer API
+===
+
+1. Overview
+===
+
+Industrial IO supports access to buffers via an mmap interface. The
+advantage of the mmap based interface compared to the read() based
+interface is that it avoids an extra copy of the data between kernel and
+userspace. This is particular useful for high-speed devices which produce
+several megabytes or even gigabytes of data per second.
+
+The data for the mmap interface is managed at the granularity of so called
+blocks. A block is a contiguous region of memory (at the moment both
+physically and virtually contiguous). Reducing the granularity from byte
+level to block level is done to reduce the userspace-kernelspace
+synchronization overhead since performing syscalls for each byte at a
+data-rate of a few megabytes is not feasible.
+
+This of course leads to a slightly increased latency. For this reason an
+application can choose the size of the blocks as well as how many blocks it
+allocates. E.g. two blocks would be a traditional double buffering scheme.
+But using a higher number might be necessary to avoid underflow/overflow
+situations in the presence of scheduling latencies.
+
+A block can either be owned by kernel space or userspace. When owned by
+userspace it is safe to access the data in the block and process it. When
+owned by kernel space the block can be in one of 3 states:
+
+* It can be in the incoming queue where all blocks submitted from userspace
+  are placed and are waiting to be processed by the kernel driver.
+* It can be currently being processed by the kernel driver, this means it is
+  actively placing capturing data in it (usually using DMA).
+* Or it can be in the outgoing queue where all blocks that have been
+  processed by the kernel are placed. Userspace can dequeue the blocks as
+  necessary.
+
+2. Interface
+
+
+As part of the interface 5 IOCTLs are used to manage the blocks and exchange
+them between userspace and kernelspace. The IOCTLs can be accessed through
+a open file descriptor to a IIO device.
+
+* **IIO_BUFFER_BLOCK_ALLOC_IOCTL(struct iio_buffer_block_alloc_req *)**:
+Allocates new blocks. Can be called multiple times if necessary. A newly
+allocated block is initially owned by userspace.
+
+* **IIO_BUFFER_BLOCK_FREE_IOCTL(void)**:
+   Frees all previously allocated blocks. If the backing memory of a block is
+   still in use by a kernel driver (i.e. active DMA transfer) it will be
+   freed once the kernel driver has released it.
+
+* **IIO_BUFFER_BLOCK_QUERY_IOCTL(struct iio_buffer_block *)**:
+   Queries information about a block. The id of the block about which
+   information is to be queried needs to be set by userspace.
+
+* **IIO_BUFFER_BLOCK_ENQUEUE_IOCTL(struct iio_buffer_block *)**:
+   Places a block on the incoming queue. This transfers ownership of the
+   block from userspace to kernelspace. Userspace must populate the id field
+   of the block to indicate which block to enqueue.
+
+* **IIO_BUFFER_BLOCK_DEQUEUE_IOCTL(struct iio_buffer_block *)**:
+   Removes the first block from the outgoing queue. This transfers ownership
+   of the block from kernelspace to userspace. Kernelspace will populate all
+   fields of the block. If the queue is empty and the file descriptor is set
+   to blocking the IOCTL will block until a new block is available on the
+   outgoing queue.
+
+3. Usage
+
+
+To access the data stored in a block by userspace the block must be mapped
+to the process's memory. This is done by calling mmap() on the IIO device
+file descriptor. Each block has a unique offset assigned to it which should
+be passed to the mmap interface. E.g.
+
+  mmap(0, block.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
+   block.offset);
+
+A typical workflow for the new interface is:
+
+  BLOCK_ALLOC
+
+  foreach block
+ BLOCK_QUERY block
+mmap block.data.offset
+BLOCK_ENQUEUE block
+
+  enable buffer
+
+  while !done
+   BLOCK_DEQUEUE block
+   process data
+   BLOCK_ENQUEUE block
+
+  disable buffer
+
+  BLOCK_FREE
diff --git a/Documentation/iio/index.rst b/Documentation/iio/index.rst
index 58b7a4ebac51..aaba78770b47 100644
--- a/Documentation/iio/index.rst
+++ 

[PATCH v4 1/6] iio: core: Add mmap interface infrastructure

2021-02-16 Thread Alexandru Ardelean
From: Lars-Peter Clausen 

Add the necessary infrastructure to the IIO core to support an mmap based
interface to access the capture data.

The advantage of the mmap based interface compared to the read() based
interface is that it avoids an extra copy of the data between kernel and
userspace. This is particular useful for high-speed devices which produce
several megabytes or even gigabytes of data per second.

The data for the mmap interface is managed at the granularity of so called
blocks. A block is a contiguous region of memory (at the moment both
physically and virtually contiguous). Reducing the granularity from byte
level to block level is done to reduce the userspace-kernelspace
synchronization overhead since performing syscalls for each byte at a
data-rate of a few megabytes is not feasible.

This of course leads to a slightly increased latency. For this reason an
application can choose the size of the blocks as well as how many blocks it
allocates. E.g. two blocks would be a traditional double buffering scheme.
But using a higher number might be necessary to avoid underflow/overflow
situations in the presence of scheduling latencies.

A block can either be owned by kernel space or userspace. When owned by
userspace it save to access the data in the block and process it. When
owned by kernel space the block can be in one of 3 states.

It can be in the incoming queue where all blocks submitted from userspace
are placed and are waiting to be processed by the kernel driver.

It can be currently being processed by the kernel driver, this means it is
actively placing capturing data in it (usually using DMA).

Or it can be in the outgoing queue where all blocks that have been
processed by the kernel are placed. Userspace can dequeue the blocks as
necessary.

As part of the interface 5 new IOCTLs to manage the blocks and exchange
them between userspace and kernelspace. The IOCTLs can be accessed through
a open file descriptor to a IIO device.

IIO_BUFFER_BLOCK_ALLOC_IOCTL(struct iio_buffer_block_alloc_req *):
 Allocates new blocks. Can be called multiple times if necessary. A newly
 allocated block is initially owned by userspace.

IIO_BUFFER_BLOCK_FREE_IOCTL(void):
 Frees all previously allocated blocks. If the backing memory of a block is
 still in use by a kernel driver (i.e. active DMA transfer) it will be
 freed once the kernel driver has released it.

IIO_BUFFER_BLOCK_QUERY_IOCTL(struct iio_buffer_block *):
 Queries information about a block. The id of the block about which
 information is to be queried needs to be set by userspace.

IIO_BUFFER_BLOCK_ENQUEUE_IOCTL(struct iio_buffer_block *):
 Places a block on the incoming queue. This transfers ownership of the
 block from userspace to kernelspace. Userspace must populate the id field
 of the block to indicate which block to enqueue.

IIO_BUFFER_BLOCK_DEQUEUE_IOCTL(struct iio_buffer_block *):
 Removes the first block from the outgoing queue. This transfers ownership
 of the block from kernelspace to userspace. Kernelspace will populate all
 fields of the block. If the queue is empty and the file descriptor is set
 to blocking the IOCTL will block until a new block is available on the
 outgoing queue.

To access the data stored in a block by userspace the block must be mapped
to the process's memory. This is done by calling mmap() on the IIO device
file descriptor. Each block has a unique offset assigned to it which should
be passed to the mmap interface. E.g.

  mmap(0, block.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
   block.offset);

A typical workflow for the new interface is:

  BLOCK_ALLOC

  foreach block
 BLOCK_QUERY block
 mmap block.data.offset
 BLOCK_ENQUEUE block

  enable buffer

  while !done
BLOCK_DEQUEUE block
process data
BLOCK_ENQUEUE block

  disable buffer

  BLOCK_FREE

Signed-off-by: Lars-Peter Clausen 
Signed-off-by: Alexandru Ardelean 
---
 drivers/iio/industrialio-buffer.c | 158 ++
 include/linux/iio/buffer-dma.h|   5 -
 include/linux/iio/buffer_impl.h   |  23 +
 include/uapi/linux/iio/buffer.h   |  46 +
 4 files changed, 227 insertions(+), 5 deletions(-)

diff --git a/drivers/iio/industrialio-buffer.c 
b/drivers/iio/industrialio-buffer.c
index 4848932d4394..5d641f8adfbd 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -1371,6 +1372,12 @@ static void 
iio_buffer_unregister_legacy_sysfs_groups(struct iio_dev *indio_dev)
kfree(iio_dev_opaque->legacy_scan_el_group.attrs);
 }
 
+static void iio_buffer_free_blocks(struct iio_buffer *buffer)
+{
+   if (buffer->access->free_blocks)
+   buffer->access->free_blocks(buffer);
+}
+
 static int iio_buffer_chrdev_release(struct inode *inode, struct file *filep)
 {
struct iio_dev_buffer_pair *ib = filep->private_data;
@@ -1381,16 

[PATCH v4 0/6] iio: core: Add mmap interface infrastructure

2021-02-16 Thread Alexandru Ardelean
Changelog v3 -> v4:
* 
https://lore.kernel.org/linux-iio/20210215143234.3248-5-alexandru.ardel...@analog.com/T/
* added patch 'iio: buffer-dma: reduce the type of block.size to u32'
  - resolves error on 64 bit archs; 32 bit block size should be enough
* in patch 'iio: buffer-dma: Add mmap support'
  - added 'linux/types.h' include in uapi buffer.h header; an error
shows up when building with 'make allmodconfig'
* in patch 'tools: iio: add example for high-speed buffer support'
  - calling ioctl(BOCK_FREE) only if use_high_speed is true

Changelog v2 -> v3:
* 
https://lore.kernel.org/linux-iio/20210212101143.18993-1-alexandru.ardel...@analog.com/T/#u
* added 'Documentation: iio: add doc for high-speed buffer API'
* add 'iio: buffer-dma: split iio_dma_buffer_fileio_free() function'
* patch 'iio: buffer-dma: Add mmap support'
   - unwind free on error path in iio_dma_buffer_alloc_blocks()
   - removed double mm.h include
* patch 'tools: iio: add example for high-speed buffer support'
   - call IIO_BUFFER_BLOCK_FREE_IOCTL on the error path of the
 enable_high_speed() function

Changelog v1 -> v2:
* 
https://lore.kernel.org/linux-iio/20210211123353.78963-1-alexandru.ardel...@analog.com/T/#t
* removed IIO_BUFFER_BLOCK_FLAG_CYCLIC flag; will be added in a later
  patch
* removed extra line in tools/iio/iio_generic_buffer.c
* patch 'iio: core: Add mmap interface infrastructure'
  added docstrings for new hooks (alloc_blocks, mmap, etc)

This is basically Lars' work adapted from branch:
  https://github.com/larsclausen/linux/commits/iio-high-speed-5.10
[hopefully i got the stuff correctly from that branch]

What is different, is that this one is adapted on top of the multibuffer
support (currently at v5) discussed here:
  
https://lore.kernel.org/linux-iio/20210211122452.78106-1-alexandru.ardel...@analog.com/T/#t

Also, adapted an example for high-speed/mmap support in
'tools/iio/iio_generic_buffer.c'

The example is adapted from libiio:
  https://github.com/analogdevicesinc/libiio/blob/master/local.c#L51
but will all the ioctl()s organized after the one that are reserved
(hopefully) for IIO

Tested that mmap() works.
Moved (artifically) valid buffer0 as buffer2 and the operation still
works.

Alexandru Ardelean (4):
  Documentation: iio: add doc for high-speed buffer API
  iio: buffer-dma: split iio_dma_buffer_fileio_free() function
  iio: buffer-dma: reduce the type of block.size to u32
  tools: iio: add example for high-speed buffer support

Lars-Peter Clausen (2):
  iio: core: Add mmap interface infrastructure
  iio: buffer-dma: Add mmap support

 Documentation/iio/iio_high_speed_buffers.rst  | 100 ++
 Documentation/iio/index.rst   |   2 +
 drivers/iio/buffer/industrialio-buffer-dma.c  | 324 --
 .../buffer/industrialio-buffer-dmaengine.c|  28 +-
 drivers/iio/industrialio-buffer.c | 158 +
 include/linux/iio/buffer-dma.h|  27 +-
 include/linux/iio/buffer_impl.h   |  23 ++
 include/uapi/linux/iio/buffer.h   |  51 +++
 tools/iio/iio_generic_buffer.c| 185 +-
 9 files changed, 847 insertions(+), 51 deletions(-)
 create mode 100644 Documentation/iio/iio_high_speed_buffers.rst

-- 
2.17.1



[PATCH 4/4] ipmi: kcs_bmc: Simplify state machine

2021-02-16 Thread William A. Kennington III
This makes a few changes, notably:

  - Removes the mutex primitive as it is not needed in the file
operation path. The read path had multiple spinlock acquisitions
with state changes that don't appear safe to reordering,
specifically around forced aborts.

  - Removes multiple per-channel allocated data buffers, opting to only
store the necessary data for the currently in flight transaction.
Since only 1 data buffer can really be used at a given time, we
don't need the previous 2-3.

  - Reduces the number of states in the KCS state machine. There are
some states, like the second abort state, that effectively duplicate
others.

  - Cleans up the initialization and register setting logic to include
bits that were missed previously.

Signed-off-by: William A. Kennington III 
---
 drivers/char/ipmi/kcs_bmc.c | 301 ++--
 drivers/char/ipmi/kcs_bmc.h |  49 ++
 2 files changed, 132 insertions(+), 218 deletions(-)

diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c
index 16a378d79db9..f2fa43a516da 100644
--- a/drivers/char/ipmi/kcs_bmc.c
+++ b/drivers/char/ipmi/kcs_bmc.c
@@ -11,21 +11,14 @@
 #include 
 #include 
 #include 
-#include 
-#include 
 
 #include "kcs_bmc.h"
 
 #define DEVICE_NAME "ipmi-kcs"
 
-#define KCS_MSG_BUFSIZ1000
-
-#define KCS_ZERO_DATA 0
-
-
 /* IPMI 2.0 - Table 9-1, KCS Interface Status Register Bits */
 #define KCS_STATUS_STATE(state) (state << 6)
-#define KCS_STATUS_STATE_MASK   GENMASK(7, 6)
+#define KCS_STATUS_STATE_MASK   GENMASK(7, 4)
 #define KCS_STATUS_CMD_DAT  BIT(3)
 #define KCS_STATUS_SMS_ATN  BIT(2)
 #define KCS_STATUS_IBF  BIT(1)
@@ -33,19 +26,19 @@
 
 /* IPMI 2.0 - Table 9-2, KCS Interface State Bits */
 enum kcs_states {
-   IDLE_STATE  = 0,
-   READ_STATE  = 1,
-   WRITE_STATE = 2,
-   ERROR_STATE = 3,
+   KCS_STATE_IDLE  = 0,
+   KCS_STATE_READ  = 1,
+   KCS_STATE_WRITE = 2,
+   KCS_STATE_ERROR = 3,
 };
 
 /* IPMI 2.0 - Table 9-3, KCS Interface Control Codes */
 #define KCS_CMD_GET_STATUS_ABORT  0x60
 #define KCS_CMD_WRITE_START   0x61
 #define KCS_CMD_WRITE_END 0x62
-#define KCS_CMD_READ_BYTE 0x68
+#define KCS_DATA_READ_BYTE0x68
 
-static void update_status_bits(struct kcs_bmc *kcs_bmc, u8 mask, u8 val)
+static void kcs_update_status_bits(struct kcs_bmc *kcs_bmc, u8 mask, u8 val)
 {
u8 tmp = kcs_bmc->read_status(kcs_bmc);
tmp &= ~mask;
@@ -53,95 +46,70 @@ static void update_status_bits(struct kcs_bmc *kcs_bmc, u8 
mask, u8 val)
kcs_bmc->write_status(kcs_bmc, tmp);
 }
 
-static inline void set_state(struct kcs_bmc *kcs_bmc, u8 state)
+static void kcs_set_state(struct kcs_bmc *kcs_bmc, enum kcs_states state)
 {
-   update_status_bits(kcs_bmc, KCS_STATUS_STATE_MASK,
+   kcs_update_status_bits(kcs_bmc, KCS_STATUS_STATE_MASK,
KCS_STATUS_STATE(state));
 }
 
-static void kcs_force_abort(struct kcs_bmc *kcs_bmc)
+static void kcs_force_abort(struct kcs_bmc *kcs_bmc, enum kcs_errors error)
 {
-   set_state(kcs_bmc, ERROR_STATE);
+   kcs_bmc->phase = KCS_PHASE_ERROR;
+   kcs_bmc->error = error;
+   kcs_set_state(kcs_bmc, KCS_STATE_ERROR);
kcs_bmc->read_data_in(kcs_bmc);
-   kcs_bmc->write_data_out(kcs_bmc, KCS_ZERO_DATA);
+   kcs_bmc->write_data_out(kcs_bmc, 0);
+}
 
-   kcs_bmc->phase = KCS_PHASE_ERROR;
-   kcs_bmc->data_in_avail = false;
-   kcs_bmc->data_in_idx = 0;
+static void kcs_pump_data_out(struct kcs_bmc *kcs_bmc)
+{
+   kcs_bmc->write_data_out(kcs_bmc,
+   kcs_bmc->data_idx >= kcs_bmc->data_len ?
+   0 : kcs_bmc->data[kcs_bmc->data_idx++]);
 }
 
 static void kcs_bmc_handle_data(struct kcs_bmc *kcs_bmc)
 {
-   u8 data;
-
switch (kcs_bmc->phase) {
-   case KCS_PHASE_WRITE_START:
-   kcs_bmc->phase = KCS_PHASE_WRITE_DATA;
-   fallthrough;
-
case KCS_PHASE_WRITE_DATA:
-   if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ) {
-   set_state(kcs_bmc, WRITE_STATE);
-   kcs_bmc->write_data_out(kcs_bmc, KCS_ZERO_DATA);
-   kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
-   kcs_bmc->read_data_in(kcs_bmc);
-   } else {
-   kcs_force_abort(kcs_bmc);
-   kcs_bmc->error = KCS_LENGTH_ERROR;
-   }
+   if (kcs_bmc->data_len >= KCS_MSG_BUFSIZ)
+   return kcs_force_abort(kcs_bmc, KCS_LENGTH_ERROR);
+   kcs_bmc->data[kcs_bmc->data_len++] =
+   kcs_bmc->read_data_in(kcs_bmc);
+   kcs_bmc->write_data_out(kcs_bmc, 0);
break;
 
-   case KCS_PHASE_WRITE_END_CMD:
-   if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ) {
-   set_state(kcs_bmc, 

[PATCH 3/4] ipmi: kcs_bmc: Invert allocation

2021-02-16 Thread William A. Kennington III
This is a more typical pattern for having the platform specific drivers
store their own data around the generic driver data.

Signed-off-by: William A. Kennington III 
---
 drivers/char/ipmi/kcs_bmc.c |  40 +++---
 drivers/char/ipmi/kcs_bmc.h |  13 +-
 drivers/char/ipmi/kcs_bmc_aspeed.c  | 216 ++--
 drivers/char/ipmi/kcs_bmc_npcm7xx.c |  61 
 4 files changed, 163 insertions(+), 167 deletions(-)

diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c
index 4c504588e714..f182c4f6f982 100644
--- a/drivers/char/ipmi/kcs_bmc.c
+++ b/drivers/char/ipmi/kcs_bmc.c
@@ -277,9 +277,6 @@ static ssize_t kcs_bmc_read(struct file *filp, char __user 
*buf,
}
 
if (count < data_len) {
-   pr_err("channel=%u with too large data : %zu\n",
-   kcs_bmc->channel, data_len);
-
spin_lock_irq(_bmc->lock);
kcs_force_abort(kcs_bmc);
spin_unlock_irq(_bmc->lock);
@@ -402,17 +399,11 @@ static const struct file_operations kcs_bmc_fops = {
.unlocked_ioctl = kcs_bmc_ioctl,
 };
 
-struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, u32 channel)
+int kcs_bmc_init(struct kcs_bmc *kcs_bmc, struct device *dev, u32 channel)
 {
-   struct kcs_bmc *kcs_bmc;
-
-   kcs_bmc = devm_kzalloc(dev, sizeof(*kcs_bmc) + sizeof_priv, GFP_KERNEL);
-   if (!kcs_bmc)
-   return NULL;
+   int rc;
 
spin_lock_init(_bmc->lock);
-   kcs_bmc->channel = channel;
-
mutex_init(_bmc->mutex);
init_waitqueue_head(_bmc->queue);
 
@@ -420,17 +411,28 @@ struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int 
sizeof_priv, u32 channel)
kcs_bmc->data_out = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
kcs_bmc->kbuffer = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
 
-   kcs_bmc->miscdev.minor = MISC_DYNAMIC_MINOR;
-   kcs_bmc->miscdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s%u",
-  DEVICE_NAME, channel);
-   if (!kcs_bmc->data_in || !kcs_bmc->data_out || !kcs_bmc->kbuffer ||
-   !kcs_bmc->miscdev.name)
-   return NULL;
kcs_bmc->miscdev.fops = _bmc_fops;
+   kcs_bmc->miscdev.minor = MISC_DYNAMIC_MINOR;
+   kcs_bmc->miscdev.name =
+   devm_kasprintf(dev, GFP_KERNEL, "%s%u", DEVICE_NAME, channel);
+   if (!kcs_bmc->miscdev.name)
+   return -ENOMEM;
+
+   rc = misc_register(_bmc->miscdev);
+   if (rc) {
+   dev_err(dev, "Registering kcs_bmc: %d\n", rc);
+   return rc;
+   }
 
-   return kcs_bmc;
+   return 0;
+}
+EXPORT_SYMBOL(kcs_bmc_init);
+
+void kcs_bmc_stop(struct kcs_bmc *kcs_bmc)
+{
+   misc_deregister(_bmc->miscdev);
 }
-EXPORT_SYMBOL(kcs_bmc_alloc);
+EXPORT_SYMBOL(kcs_bmc_stop);
 
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Haiyue Wang ");
diff --git a/drivers/char/ipmi/kcs_bmc.h b/drivers/char/ipmi/kcs_bmc.h
index 8c541251fe97..d65ffd479e9b 100644
--- a/drivers/char/ipmi/kcs_bmc.h
+++ b/drivers/char/ipmi/kcs_bmc.h
@@ -64,7 +64,6 @@ enum kcs_errors {
 struct kcs_bmc {
spinlock_t lock;
 
-   u32 channel;
int running;
 
/* Setup by BMC KCS controller driver */
@@ -89,16 +88,10 @@ struct kcs_bmc {
u8 *kbuffer;
 
struct miscdevice miscdev;
-
-   unsigned long priv[];
 };
 
-static inline void *kcs_bmc_priv(struct kcs_bmc *kcs_bmc)
-{
-   return kcs_bmc->priv;
-}
-
 irqreturn_t kcs_bmc_irq(int irq, void *arg);
-struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv,
-   u32 channel);
+int kcs_bmc_init(struct kcs_bmc *kcs_bmc, struct device *dev, u32 channel);
+void kcs_bmc_stop(struct kcs_bmc *kcs_bmc);
+
 #endif /* __KCS_BMC_H__ */
diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c 
b/drivers/char/ipmi/kcs_bmc_aspeed.c
index d3b771e4d039..b466569d049d 100644
--- a/drivers/char/ipmi/kcs_bmc_aspeed.c
+++ b/drivers/char/ipmi/kcs_bmc_aspeed.c
@@ -69,11 +69,29 @@ struct aspeed_kcs_reg {
 };
 
 struct aspeed_kcs {
+   struct kcs_bmc kcs_bmc;
+
+   u32 channel;
struct regmap *map;
+};
 
-   const struct aspeed_kcs_reg *reg;
+static const struct aspeed_kcs_reg aspeed_kcs_regs[KCS_CHANNEL_MAX] = {
+   { .idr = LPC_IDR1, .odr = LPC_ODR1, .str = LPC_STR1 },
+   { .idr = LPC_IDR2, .odr = LPC_ODR2, .str = LPC_STR2 },
+   { .idr = LPC_IDR3, .odr = LPC_ODR3, .str = LPC_STR3 },
+   { .idr = LPC_IDR4, .odr = LPC_ODR4, .str = LPC_STR4 },
 };
 
+static struct aspeed_kcs *to_aspeed_kcs(struct kcs_bmc *kcs_bmc)
+{
+   return container_of(kcs_bmc, struct aspeed_kcs, kcs_bmc);
+}
+
+static const struct aspeed_kcs_reg *to_aspeed_kcs_reg(
+   const struct aspeed_kcs *aspeed_kcs)
+{
+   return _kcs_regs[aspeed_kcs->channel-1];
+}
 
 static u8 aspeed_kcs_inb(struct aspeed_kcs *aspeed_kcs, u32 reg)
 {
@@ -91,26 +109,26 @@ static void 

[PATCH 3/4] ipmi: kcs_bmc: Invert allocation pattern

2021-02-16 Thread William A. Kennington III
The generic kcs_bmc code shouldn't need to store data on behalf of the
platform specific driver that initializes it. Instead, have the platform
specific driver allocate memory and call a generic initialization
routine.

Signed-off-by: William A. Kennington III 
---
 drivers/char/ipmi/kcs_bmc.c |  40 +++---
 drivers/char/ipmi/kcs_bmc.h |  13 +-
 drivers/char/ipmi/kcs_bmc_aspeed.c  | 216 ++--
 drivers/char/ipmi/kcs_bmc_npcm7xx.c |  61 
 4 files changed, 163 insertions(+), 167 deletions(-)

diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c
index aa2093323622..16a378d79db9 100644
--- a/drivers/char/ipmi/kcs_bmc.c
+++ b/drivers/char/ipmi/kcs_bmc.c
@@ -276,9 +276,6 @@ static ssize_t kcs_bmc_read(struct file *filp, char __user 
*buf,
}
 
if (count < data_len) {
-   pr_err("channel=%u with too large data : %zu\n",
-   kcs_bmc->channel, data_len);
-
spin_lock_irq(_bmc->lock);
kcs_force_abort(kcs_bmc);
spin_unlock_irq(_bmc->lock);
@@ -401,17 +398,11 @@ static const struct file_operations kcs_bmc_fops = {
.unlocked_ioctl = kcs_bmc_ioctl,
 };
 
-struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, u32 channel)
+int kcs_bmc_init(struct kcs_bmc *kcs_bmc, struct device *dev, u32 channel)
 {
-   struct kcs_bmc *kcs_bmc;
-
-   kcs_bmc = devm_kzalloc(dev, sizeof(*kcs_bmc) + sizeof_priv, GFP_KERNEL);
-   if (!kcs_bmc)
-   return NULL;
+   int rc;
 
spin_lock_init(_bmc->lock);
-   kcs_bmc->channel = channel;
-
mutex_init(_bmc->mutex);
init_waitqueue_head(_bmc->queue);
 
@@ -419,17 +410,28 @@ struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int 
sizeof_priv, u32 channel)
kcs_bmc->data_out = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
kcs_bmc->kbuffer = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
 
-   kcs_bmc->miscdev.minor = MISC_DYNAMIC_MINOR;
-   kcs_bmc->miscdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s%u",
-  DEVICE_NAME, channel);
-   if (!kcs_bmc->data_in || !kcs_bmc->data_out || !kcs_bmc->kbuffer ||
-   !kcs_bmc->miscdev.name)
-   return NULL;
kcs_bmc->miscdev.fops = _bmc_fops;
+   kcs_bmc->miscdev.minor = MISC_DYNAMIC_MINOR;
+   kcs_bmc->miscdev.name =
+   devm_kasprintf(dev, GFP_KERNEL, "%s%u", DEVICE_NAME, channel);
+   if (!kcs_bmc->miscdev.name)
+   return -ENOMEM;
+
+   rc = misc_register(_bmc->miscdev);
+   if (rc) {
+   dev_err(dev, "Registering kcs_bmc: %d\n", rc);
+   return rc;
+   }
 
-   return kcs_bmc;
+   return 0;
+}
+EXPORT_SYMBOL(kcs_bmc_init);
+
+void kcs_bmc_stop(struct kcs_bmc *kcs_bmc)
+{
+   misc_deregister(_bmc->miscdev);
 }
-EXPORT_SYMBOL(kcs_bmc_alloc);
+EXPORT_SYMBOL(kcs_bmc_stop);
 
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Haiyue Wang ");
diff --git a/drivers/char/ipmi/kcs_bmc.h b/drivers/char/ipmi/kcs_bmc.h
index 8c541251fe97..d65ffd479e9b 100644
--- a/drivers/char/ipmi/kcs_bmc.h
+++ b/drivers/char/ipmi/kcs_bmc.h
@@ -64,7 +64,6 @@ enum kcs_errors {
 struct kcs_bmc {
spinlock_t lock;
 
-   u32 channel;
int running;
 
/* Setup by BMC KCS controller driver */
@@ -89,16 +88,10 @@ struct kcs_bmc {
u8 *kbuffer;
 
struct miscdevice miscdev;
-
-   unsigned long priv[];
 };
 
-static inline void *kcs_bmc_priv(struct kcs_bmc *kcs_bmc)
-{
-   return kcs_bmc->priv;
-}
-
 irqreturn_t kcs_bmc_irq(int irq, void *arg);
-struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv,
-   u32 channel);
+int kcs_bmc_init(struct kcs_bmc *kcs_bmc, struct device *dev, u32 channel);
+void kcs_bmc_stop(struct kcs_bmc *kcs_bmc);
+
 #endif /* __KCS_BMC_H__ */
diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c 
b/drivers/char/ipmi/kcs_bmc_aspeed.c
index d3b771e4d039..b466569d049d 100644
--- a/drivers/char/ipmi/kcs_bmc_aspeed.c
+++ b/drivers/char/ipmi/kcs_bmc_aspeed.c
@@ -69,11 +69,29 @@ struct aspeed_kcs_reg {
 };
 
 struct aspeed_kcs {
+   struct kcs_bmc kcs_bmc;
+
+   u32 channel;
struct regmap *map;
+};
 
-   const struct aspeed_kcs_reg *reg;
+static const struct aspeed_kcs_reg aspeed_kcs_regs[KCS_CHANNEL_MAX] = {
+   { .idr = LPC_IDR1, .odr = LPC_ODR1, .str = LPC_STR1 },
+   { .idr = LPC_IDR2, .odr = LPC_ODR2, .str = LPC_STR2 },
+   { .idr = LPC_IDR3, .odr = LPC_ODR3, .str = LPC_STR3 },
+   { .idr = LPC_IDR4, .odr = LPC_ODR4, .str = LPC_STR4 },
 };
 
+static struct aspeed_kcs *to_aspeed_kcs(struct kcs_bmc *kcs_bmc)
+{
+   return container_of(kcs_bmc, struct aspeed_kcs, kcs_bmc);
+}
+
+static const struct aspeed_kcs_reg *to_aspeed_kcs_reg(
+   const struct aspeed_kcs *aspeed_kcs)
+{
+   return _kcs_regs[aspeed_kcs->channel-1];
+}
 
 static u8 

[PATCH 2/4] ipmi: kcs_bmc: Remove register abstraction

2021-02-16 Thread William A. Kennington III
The generic kcs_bmc code doesn't care about how byte reads / writes are
implemented. This pushes that logic to the device specific handlers, so
that kcs_bmc doesn't need to understand registers and how to read
or write them.

Signed-off-by: William A. Kennington III 
---
 drivers/char/ipmi/kcs_bmc.c |  60 +--
 drivers/char/ipmi/kcs_bmc.h |  13 +---
 drivers/char/ipmi/kcs_bmc_aspeed.c  | 110 +---
 drivers/char/ipmi/kcs_bmc_npcm7xx.c |  60 +--
 4 files changed, 130 insertions(+), 113 deletions(-)

diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c
index ccb35f1645cf..aa2093323622 100644
--- a/drivers/char/ipmi/kcs_bmc.c
+++ b/drivers/char/ipmi/kcs_bmc.c
@@ -45,34 +45,12 @@ enum kcs_states {
 #define KCS_CMD_WRITE_END 0x62
 #define KCS_CMD_READ_BYTE 0x68
 
-static inline u8 read_data(struct kcs_bmc *kcs_bmc)
-{
-   return kcs_bmc->io_inputb(kcs_bmc, kcs_bmc->ioreg.idr);
-}
-
-static inline void write_data(struct kcs_bmc *kcs_bmc, u8 data)
-{
-   kcs_bmc->io_outputb(kcs_bmc, kcs_bmc->ioreg.odr, data);
-}
-
-static inline u8 read_status(struct kcs_bmc *kcs_bmc)
-{
-   return kcs_bmc->io_inputb(kcs_bmc, kcs_bmc->ioreg.str);
-}
-
-static inline void write_status(struct kcs_bmc *kcs_bmc, u8 data)
-{
-   kcs_bmc->io_outputb(kcs_bmc, kcs_bmc->ioreg.str, data);
-}
-
 static void update_status_bits(struct kcs_bmc *kcs_bmc, u8 mask, u8 val)
 {
-   u8 tmp = read_status(kcs_bmc);
-
+   u8 tmp = kcs_bmc->read_status(kcs_bmc);
tmp &= ~mask;
tmp |= val & mask;
-
-   write_status(kcs_bmc, tmp);
+   kcs_bmc->write_status(kcs_bmc, tmp);
 }
 
 static inline void set_state(struct kcs_bmc *kcs_bmc, u8 state)
@@ -84,8 +62,8 @@ static inline void set_state(struct kcs_bmc *kcs_bmc, u8 
state)
 static void kcs_force_abort(struct kcs_bmc *kcs_bmc)
 {
set_state(kcs_bmc, ERROR_STATE);
-   read_data(kcs_bmc);
-   write_data(kcs_bmc, KCS_ZERO_DATA);
+   kcs_bmc->read_data_in(kcs_bmc);
+   kcs_bmc->write_data_out(kcs_bmc, KCS_ZERO_DATA);
 
kcs_bmc->phase = KCS_PHASE_ERROR;
kcs_bmc->data_in_avail = false;
@@ -104,9 +82,9 @@ static void kcs_bmc_handle_data(struct kcs_bmc *kcs_bmc)
case KCS_PHASE_WRITE_DATA:
if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ) {
set_state(kcs_bmc, WRITE_STATE);
-   write_data(kcs_bmc, KCS_ZERO_DATA);
+   kcs_bmc->write_data_out(kcs_bmc, KCS_ZERO_DATA);
kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
-   read_data(kcs_bmc);
+   kcs_bmc->read_data_in(kcs_bmc);
} else {
kcs_force_abort(kcs_bmc);
kcs_bmc->error = KCS_LENGTH_ERROR;
@@ -117,7 +95,7 @@ static void kcs_bmc_handle_data(struct kcs_bmc *kcs_bmc)
if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ) {
set_state(kcs_bmc, READ_STATE);
kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
-   read_data(kcs_bmc);
+   kcs_bmc->read_data_in(kcs_bmc);
kcs_bmc->phase = KCS_PHASE_WRITE_DONE;
kcs_bmc->data_in_avail = true;
wake_up_interruptible(_bmc->queue);
@@ -131,34 +109,34 @@ static void kcs_bmc_handle_data(struct kcs_bmc *kcs_bmc)
if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len)
set_state(kcs_bmc, IDLE_STATE);
 
-   data = read_data(kcs_bmc);
+   data = kcs_bmc->read_data_in(kcs_bmc);
if (data != KCS_CMD_READ_BYTE) {
set_state(kcs_bmc, ERROR_STATE);
-   write_data(kcs_bmc, KCS_ZERO_DATA);
+   kcs_bmc->write_data_out(kcs_bmc, KCS_ZERO_DATA);
break;
}
 
if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len) {
-   write_data(kcs_bmc, KCS_ZERO_DATA);
+   kcs_bmc->write_data_out(kcs_bmc, KCS_ZERO_DATA);
kcs_bmc->phase = KCS_PHASE_IDLE;
break;
}
 
-   write_data(kcs_bmc,
+   kcs_bmc->write_data_out(kcs_bmc,
kcs_bmc->data_out[kcs_bmc->data_out_idx++]);
break;
 
case KCS_PHASE_ABORT_ERROR1:
set_state(kcs_bmc, READ_STATE);
-   read_data(kcs_bmc);
-   write_data(kcs_bmc, kcs_bmc->error);
+   kcs_bmc->read_data_in(kcs_bmc);
+   kcs_bmc->write_data_out(kcs_bmc, kcs_bmc->error);
kcs_bmc->phase = KCS_PHASE_ABORT_ERROR2;
break;
 
case KCS_PHASE_ABORT_ERROR2:

[PATCH 1/4] ipmi: kcs_bmc: Simplify irq handling

2021-02-16 Thread William A. Kennington III
Platforms specific IRQ handles repeat the same logic, calling a
sub-handler in the kcs_bmc generic code that should just conform to the
irqhandler callback.

Signed-off-by: William A. Kennington III 
---
 drivers/char/ipmi/kcs_bmc.c | 10 +-
 drivers/char/ipmi/kcs_bmc.h |  3 ++-
 drivers/char/ipmi/kcs_bmc_aspeed.c  | 12 +---
 drivers/char/ipmi/kcs_bmc_npcm7xx.c | 12 +---
 4 files changed, 9 insertions(+), 28 deletions(-)

diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c
index f292e74bd4a5..ccb35f1645cf 100644
--- a/drivers/char/ipmi/kcs_bmc.c
+++ b/drivers/char/ipmi/kcs_bmc.c
@@ -209,10 +209,11 @@ static void kcs_bmc_handle_cmd(struct kcs_bmc *kcs_bmc)
}
 }
 
-int kcs_bmc_handle_event(struct kcs_bmc *kcs_bmc)
+irqreturn_t kcs_bmc_irq(int irq, void *arg)
 {
+   struct kcs_bmc *kcs_bmc = arg;
unsigned long flags;
-   int ret = -ENODATA;
+   irqreturn_t ret = IRQ_NONE;
u8 status;
 
spin_lock_irqsave(_bmc->lock, flags);
@@ -225,15 +226,14 @@ int kcs_bmc_handle_event(struct kcs_bmc *kcs_bmc)
kcs_bmc_handle_cmd(kcs_bmc);
else
kcs_bmc_handle_data(kcs_bmc);
-
-   ret = 0;
+   ret = IRQ_HANDLED;
}
 
spin_unlock_irqrestore(_bmc->lock, flags);
 
return ret;
 }
-EXPORT_SYMBOL(kcs_bmc_handle_event);
+EXPORT_SYMBOL(kcs_bmc_irq);
 
 static inline struct kcs_bmc *to_kcs_bmc(struct file *filp)
 {
diff --git a/drivers/char/ipmi/kcs_bmc.h b/drivers/char/ipmi/kcs_bmc.h
index eb9ea4ce78b8..959d7042e6d2 100644
--- a/drivers/char/ipmi/kcs_bmc.h
+++ b/drivers/char/ipmi/kcs_bmc.h
@@ -6,6 +6,7 @@
 #ifndef __KCS_BMC_H__
 #define __KCS_BMC_H__
 
+#include 
 #include 
 
 /* Different phases of the KCS BMC module.
@@ -102,7 +103,7 @@ static inline void *kcs_bmc_priv(struct kcs_bmc *kcs_bmc)
return kcs_bmc->priv;
 }
 
-int kcs_bmc_handle_event(struct kcs_bmc *kcs_bmc);
+irqreturn_t kcs_bmc_irq(int irq, void *arg);
 struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv,
u32 channel);
 #endif /* __KCS_BMC_H__ */
diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c 
b/drivers/char/ipmi/kcs_bmc_aspeed.c
index a140203c079b..6451a8af2664 100644
--- a/drivers/char/ipmi/kcs_bmc_aspeed.c
+++ b/drivers/char/ipmi/kcs_bmc_aspeed.c
@@ -203,16 +203,6 @@ static void aspeed_kcs_enable_channel(struct kcs_bmc 
*kcs_bmc, bool enable)
}
 }
 
-static irqreturn_t aspeed_kcs_irq(int irq, void *arg)
-{
-   struct kcs_bmc *kcs_bmc = arg;
-
-   if (!kcs_bmc_handle_event(kcs_bmc))
-   return IRQ_HANDLED;
-
-   return IRQ_NONE;
-}
-
 static int aspeed_kcs_config_irq(struct kcs_bmc *kcs_bmc,
struct platform_device *pdev)
 {
@@ -223,7 +213,7 @@ static int aspeed_kcs_config_irq(struct kcs_bmc *kcs_bmc,
if (irq < 0)
return irq;
 
-   return devm_request_irq(dev, irq, aspeed_kcs_irq, IRQF_SHARED,
+   return devm_request_irq(dev, irq, kcs_bmc_irq, IRQF_SHARED,
dev_name(dev), kcs_bmc);
 }
 
diff --git a/drivers/char/ipmi/kcs_bmc_npcm7xx.c 
b/drivers/char/ipmi/kcs_bmc_npcm7xx.c
index 722f7391fe1f..f417813cf900 100644
--- a/drivers/char/ipmi/kcs_bmc_npcm7xx.c
+++ b/drivers/char/ipmi/kcs_bmc_npcm7xx.c
@@ -108,16 +108,6 @@ static void npcm7xx_kcs_enable_channel(struct kcs_bmc 
*kcs_bmc, bool enable)
   enable ? KCS_IE_IRQE | KCS_IE_HIRQE : 0);
 }
 
-static irqreturn_t npcm7xx_kcs_irq(int irq, void *arg)
-{
-   struct kcs_bmc *kcs_bmc = arg;
-
-   if (!kcs_bmc_handle_event(kcs_bmc))
-   return IRQ_HANDLED;
-
-   return IRQ_NONE;
-}
-
 static int npcm7xx_kcs_config_irq(struct kcs_bmc *kcs_bmc,
  struct platform_device *pdev)
 {
@@ -128,7 +118,7 @@ static int npcm7xx_kcs_config_irq(struct kcs_bmc *kcs_bmc,
if (irq < 0)
return irq;
 
-   return devm_request_irq(dev, irq, npcm7xx_kcs_irq, IRQF_SHARED,
+   return devm_request_irq(dev, irq, kcs_bmc_irq, IRQF_SHARED,
dev_name(dev), kcs_bmc);
 }
 
-- 
2.30.0.478.g8a0d178c01-goog



Re: [PATCH v1 01/12] gna: add driver module

2021-02-16 Thread Maciej Kwapulinski


Greg Kroah-Hartman  writes:

> On Tue, Feb 16, 2021 at 05:05:14PM +0100, Maciej Kwapulinski wrote:
>> --- /dev/null
>> +++ b/drivers/misc/gna/gna_driver.c
>> @@ -0,0 +1,65 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +// Copyright(c) 2017-2021 Intel Corporation
>> +
>> +#define pr_fmt(fmt) KBUILD_MODNAME " " fmt
>
> You are a driver, you should never need a pr_* call, so this should not
> be needed.  You should always just use dev_* instead.
>

Hi Greg and all other Reviewers.

Thank You for all the comments so far.

I'm starting preparing PATCH v2 series based on them.
I'll also answer comments individually where need arises.

regards,
Maciej


Re: [PATCH 2/2] ath9k: fix ath_tx_process_buffer() potential null ptr dereference

2021-02-16 Thread Kalle Valo
Shuah Khan  writes:

> On 2/16/21 12:53 AM, Felix Fietkau wrote:
>>
>> On 2021-02-16 08:03, Kalle Valo wrote:
>>> Shuah Khan  wrote:
>>>
 ath_tx_process_buffer() references ieee80211_find_sta_by_ifaddr()
 return pointer (sta) outside null check. Fix it by moving the code
 block under the null check.

 This problem was found while reviewing code to debug RCU warn from
 ath10k_wmi_tlv_parse_peer_stats_info() and a subsequent manual audit
 of other callers of ieee80211_find_sta_by_ifaddr() that don't hold
 RCU read lock.

 Signed-off-by: Shuah Khan 
 Signed-off-by: Kalle Valo 
>>>
>>> Patch applied to ath-next branch of ath.git, thanks.
>>>
>>> a56c14bb21b2 ath9k: fix ath_tx_process_buffer() potential null ptr 
>>> dereference
>> I just took another look at this patch, and it is completely bogus.
>> Not only does the stated reason not make any sense (sta is simply passed
>> to other functions, not dereferenced without checks), but this also
>> introduces a horrible memory leak by skipping buffer completion if sta
>> is NULL.
>> Please drop it, the code is fine as-is.
>
> A comment describing what you said here might be a good addition to this
> comment block though.

Shuah, can you send a followup patch which reverts your change and adds
the comment? I try to avoid rebasing my trees.

-- 
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


Re: [PATCH v3 0/5] iio: core: Add mmap interface infrastructure

2021-02-16 Thread Alexandru Ardelean
On Tue, Feb 16, 2021 at 10:02 PM Jonathan Cameron  wrote:
>
> On Mon, 15 Feb 2021 16:32:29 +0200
> Alexandru Ardelean  wrote:
>
>
> Hi Alex,
>
> I'm a little nervous about adding the userspace interface used in this
> series, but it seems reasonable and as you say below, is close to what
> Analog have been using for years.
>
> So I've applied it to the togreg branch of iio.git and pushed out as
> testing as normal.   I'm not going to push that out as anything I can't
> rebase for at least a few weeks, so if anyone else wants to take a look
> that would be great.
>

Oops.
I actually was preparing a new version yesterday with a fix for this
and a few tweaks.
This issue seems to appear on 64 bit only.

Will send it.


> One slight tweak was needed. I forced it with min_t(size_t,...
> as it should always be at least as bit as __u32 so should be fine.
>
>   CHECK   drivers/iio/industrialio-core.c
> In file included from ./include/linux/kernel.h:14,
>  from ./include/asm-generic/bug.h:20,
>  from ./arch/x86/include/asm/bug.h:93,
>  from ./include/linux/bug.h:5,
>  from ./include/linux/mmdebug.h:5,
>  from ./include/linux/gfp.h:5,
>  from ./include/linux/slab.h:15,
>  from drivers/iio/buffer/industrialio-buffer-dmaengine.c:7:
> drivers/iio/buffer/industrialio-buffer-dmaengine.c: In function 
> ‘iio_dmaengine_buffer_submit_block’:
> ./include/linux/minmax.h:18:28: warning: comparison of distinct pointer types 
> lacks a cast
>18 |  (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1)))
>   |^~
> ./include/linux/minmax.h:32:4: note: in expansion of macro ‘__typecheck’
>32 |   (__typecheck(x, y) && __no_side_effects(x, y))
>   |^~~
> ./include/linux/minmax.h:42:24: note: in expansion of macro ‘__safe_cmp’
>42 |  __builtin_choose_expr(__safe_cmp(x, y), \
>   |^~
> ./include/linux/minmax.h:51:19: note: in expansion of macro ‘__careful_cmp’
>51 | #define min(x, y) __careful_cmp(x, y, <)
>   |   ^
> drivers/iio/buffer/industrialio-buffer-dmaengine.c:69:28: note: in expansion 
> of macro ‘min’
>69 |  block->block.bytes_used = min(block->block.size,
>   |^~~
>   CHECK   drivers/iio/buffer/industrialio-buffer-dmaengine.c
>   CHECK   drivers/iio/industrialio-buffer.c
> drivers/iio/buffer/industrialio-buffer-dmaengine.c:69:35: error: incompatible 
> types in comparison expression (different type sizes):
> drivers/iio/buffer/industrialio-buffer-dmaengine.c:69:35:unsigned int *
> drivers/iio/buffer/industrialio-buffer-dmaengine.c:69:35:unsigned long *
>
> Thanks,
>
> Jonathan
>
>
> > Changelog v2 -> v3:
> > * 
> > https://lore.kernel.org/linux-iio/20210212101143.18993-1-alexandru.ardel...@analog.com/T/#u
> > * added 'Documentation: iio: add doc for high-speed buffer API'
> > * add 'iio: buffer-dma: split iio_dma_buffer_fileio_free() function'
> > * patch 'iio: buffer-dma: Add mmap support'
> >- unwind free on error path in iio_dma_buffer_alloc_blocks()
> >- removed double mm.h include
> > * patch 'tools: iio: add example for high-speed buffer support'
> >- call IIO_BUFFER_BLOCK_FREE_IOCTL on the error path of the
> >  enable_high_speed() function
> >
> > Changelog v1 -> v2:
> > * 
> > https://lore.kernel.org/linux-iio/20210211123353.78963-1-alexandru.ardel...@analog.com/T/#t
> > * removed IIO_BUFFER_BLOCK_FLAG_CYCLIC flag; will be added in a later
> >   patch
> > * removed extra line in tools/iio/iio_generic_buffer.c
> > * patch 'iio: core: Add mmap interface infrastructure'
> >   added docstrings for new hooks (alloc_blocks, mmap, etc)
> >
> > This is basically Lars' work adapted from branch:
> >   https://github.com/larsclausen/linux/commits/iio-high-speed-5.10
> > [hopefully i got the stuff correctly from that branch]
> >
> > What is different, is that this one is adapted on top of the multibuffer
> > support (currently at v5) discussed here:
> >   
> > https://lore.kernel.org/linux-iio/20210211122452.78106-1-alexandru.ardel...@analog.com/T/#t
> >
> > Also, adapted an example for high-speed/mmap support in
> > 'tools/iio/iio_generic_buffer.c'
> >
> > The example is adapted from libiio:
> >   https://github.com/analogdevicesinc/libiio/blob/master/local.c#L51
> > but will all the ioctl()s organized after the one that are reserved
> > (hopefully) for IIO
> >
> > Tested that mmap() works.
> > Moved (artifically) valid buffer0 as buffer2 and the operation still
> > works.
> >
> > Alexandru Ardelean (3):
> >   Documentation: iio: add doc for high-speed buffer API
> >   iio: buffer-dma: split iio_dma_buffer_fileio_free() function
> >   tools: iio: add example for high-speed buffer support
> >
> > Lars-Peter Clausen (2):
> >   iio: core: Add mmap interface infrastructure
> >   iio: buffer-dma: Add mmap support
> >
> >  

Re: [PATCH 0/2] block: avoid to drop & re-add partitions if partitions aren't changed

2021-02-16 Thread Christoph Hellwig
On Wed, Feb 17, 2021 at 11:07:14AM +0800, Ming Lei wrote:
> Do you think it is correct for ioctl(BLKRRPART) to always drop/re-add
> partition device node?

Yes, that is what it is designed to do.  The only reason to call this
ioctl is when userspace software has written new partition table
information to the disk.


Re: [PATCH net-next v2] misc: Add Renesas Synchronization Management Unit (SMU) support

2021-02-16 Thread Greg KH
On Tue, Feb 16, 2021 at 07:50:49PM +, Min Li wrote:
> > 
> > Yes, that line.
> > 
> > The documentation should tell you how to do that, as per my patch bot:
> > 
> > - This looks like a new version of a previously submitted patch, but you
> >   did not list below the --- line any changes from the previous version.
> >   Please read the section entitled "The canonical patch format" in the
> >   kernel file, Documentation/SubmittingPatches for what needs to be done
> >   here to properly describe this.
> > 
> > thanks,
> > 
> > greg k-h
> 
> Hi Greg
> 
> I read documentation. Am I supposed to add the "---" marker line manually by 
> myself when doing "git commit --amend"? git commit will
> always add a "---" marker line before the actual change like below
> 
> Signed-off-by: Min Li 
> ---
> Changes since v1:
> -Provide more background for purpose of the change.
> -Provide compat_ioctl support
> -Fix ioctl cmd definition
> ---
>  drivers/misc/Kconfig  |  13 ++
>  drivers/misc/Makefile |   3 +

You add the text after you have created the patch with 'git
format-patch' by editing the text file before sending it off to us.  You
don't add it to the changelog comment itself.

hope this helps,

greg k-h


Re: [PATCH v2] Staging: mt7621-pci: fixed a blank line coding style issue

2021-02-16 Thread Sergio Paracuellos
On Wed, Feb 17, 2021 at 8:07 AM Selvakumar Elangovan
 wrote:>
> Removed an unnecessary blank line before closing brace reported by
> checkpatch.pl
>
> Signed-off-by: Selvakumar Elangovan 
> ---
>  drivers/staging/mt7621-pci/pci-mt7621.c | 1 -
>  1 file changed, 1 deletion(-)

Reviewed-by: Sergio Paracuellos 

Best regards,
Sergio Paracuellos


[PATCH v2] Staging: mt7621-pci: fixed a blank line coding style issue

2021-02-16 Thread Selvakumar Elangovan
Removed an unnecessary blank line before closing brace reported by
checkpatch.pl

Signed-off-by: Selvakumar Elangovan 
---
 drivers/staging/mt7621-pci/pci-mt7621.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/staging/mt7621-pci/pci-mt7621.c 
b/drivers/staging/mt7621-pci/pci-mt7621.c
index c3532bc138fb..1781c1dcf5b4 100644
--- a/drivers/staging/mt7621-pci/pci-mt7621.c
+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
@@ -521,7 +521,6 @@ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie)

if (slot == 1 && tmp && !tmp->enabled)
phy_power_off(tmp->phy);
-
}
}
 }
--
2.17.1



Re: [PATCH] Makefile: Remove # characters from compiler string

2021-02-16 Thread Masahiro Yamada
On Wed, Feb 17, 2021 at 6:33 AM Nathan Chancellor  wrote:
>
> When using AMD's Optimizing C/C++ Compiler (AOCC), the build fails due
> to a # character in the version string, which is interpreted as a
> comment:
>
> $ make CC=clang defconfig init/main.o
> include/config/auto.conf.cmd:1374: *** invalid syntax in conditional. Stop.
>
> $ sed -n 1374p include/config/auto.conf.cmd
> ifneq "$(CC_VERSION_TEXT)" "AMD clang version 11.0.0 (CLANG: 
> AOCC_2.3.0-Build#85 2020_11_10) (based on LLVM Mirror.Version.11.0.0)"
>
> Remove all # characters in the version string so that the build does not
> fail unexpectedly.
>
> Link: https://github.com/ClangBuiltLinux/linux/issues/1298
> Reported-by: Michael Fuckner 
> Signed-off-by: Nathan Chancellor 
> ---


After some thoughts, I decided to apply this as-is for now.


Ideally, the part "AOCC_2.3.0-Build#85"
could be escaped like "AOCC_2.3.0-Build\#85"
so that the original version string is preserved.

I know it is impossible because escape sequence
handling in Kconfig is buggy.

So, I accept dropping problematic '#' characters entirely,
and I agree this is the safest fix.

When I have time, I might want to revisit this with a Kconfig fix.


Applied to linux-kbuild. Thanks.






--
Best Regards
Masahiro Yamada


Re: [PATCH] Staging: mt7621-pci: pci-mt7621: fixed a blank line coding style issue

2021-02-16 Thread Sergio Paracuellos
Hi Selvakumar,

On Wed, Feb 17, 2021 at 7:53 AM Selvakumar Elangovan
 wrote:
>
> Removed an unecessary blank line before closing brace reported by
> checkpatch.pl

Typo:

s/unecessary/unnecessary/g

>
> Signed-off-by: Selvakumar Elangovan 
> ---
>  drivers/staging/mt7621-pci/pci-mt7621.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/drivers/staging/mt7621-pci/pci-mt7621.c 
> b/drivers/staging/mt7621-pci/pci-mt7621.c
> index c3532bc138fb..1781c1dcf5b4 100644
> --- a/drivers/staging/mt7621-pci/pci-mt7621.c
> +++ b/drivers/staging/mt7621-pci/pci-mt7621.c
> @@ -521,7 +521,6 @@ static void mt7621_pcie_init_ports(struct mt7621_pcie 
> *pcie)
>
> if (slot == 1 && tmp && !tmp->enabled)
> phy_power_off(tmp->phy);
> -
> }
> }
>  }
> --
> 2.17.1
>

Please, also change commit short message to:

staging: mt7621-pci: fixed a blank line coding style issue

With that changes:

Reviewed-by: Sergio Paracuellos 

Best regards,
Sergio Paracuellos


RE: [Intel-gfx] [drm/i915] 04ff178484: phoronix-test-suite.supertuxkart.1024x768.Fullscreen.Ultimate.1.GranParadisoIsland.frames_per_second -30.4% regression

2021-02-16 Thread Chiou, Cooper
Hi upstream committee, 

Please consider to merge this patch which resolved VP8 hardware encoding GPU 
hang critical issue on Gen9 sku, and there is no performance regression on this 
fix.

Best Regards,
Cooper

-Original Message-
From: kernel test robot  
Sent: Monday, February 8, 2021 8:46 AM
To: Chiou, Cooper 
Cc: Tang, Feng ; Li, Tiejun ; Chris 
Wilson ; Du, Frank ; Chen, 
Guobing ; Tseng, William ; 
Xie, Gengxin ; Fan, Shuhua ; Zhao, 
Fan ; Huang, Ying ; Kang, Shan 
; Xing, Zhengjun ; Huang, Wenhuan 
; Nikula, Jani ; 
intel-...@lists.freedesktop.org; l...@lists.01.org; Chen, Ming A 
; Ma, Yu ; Ji, Jessica 
; Li, Guangli ; Guo, Wangyang 
; Mi, Dapeng1 ; LKML 
; Sun, Jiebin 
Subject: Re: [Intel-gfx] [drm/i915] 04ff178484: 
phoronix-test-suite.supertuxkart.1024x768.Fullscreen.Ultimate.1.GranParadisoIsland.frames_per_second
 -30.4% regression

Hi all,

The problem can't be reproduced after test environment changed, there's no 
regression found on this patch now, we don't know yet why it caused a 
regression in September 2020, but we'll continue to root cause.

Best Regards,
Rong Chen


[PATCH v4 net-next] net: socket: use BIT() for MSG_*

2021-02-16 Thread menglong8 . dong
From: Menglong Dong 

The bit mask for MSG_* seems a little confused here. Replace it
with BIT() to make it clear to understand.

Signed-off-by: Menglong Dong 
---
v4:
- CC netdev
v3:
- move changelog here
v2:
- use BIT() instead of BIT_MASK()
---
 include/linux/socket.h | 71 ++
 1 file changed, 37 insertions(+), 34 deletions(-)

diff --git a/include/linux/socket.h b/include/linux/socket.h
index 385894b4a8bb..e88859f38cd0 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -283,42 +283,45 @@ struct ucred {
Added those for 1003.1g not all are supported yet
  */
 
-#define MSG_OOB1
-#define MSG_PEEK   2
-#define MSG_DONTROUTE  4
-#define MSG_TRYHARD 4   /* Synonym for MSG_DONTROUTE for DECnet */
-#define MSG_CTRUNC 8
-#define MSG_PROBE  0x10/* Do not send. Only probe path f.e. for MTU */
-#define MSG_TRUNC  0x20
-#define MSG_DONTWAIT   0x40/* Nonblocking io*/
-#define MSG_EOR 0x80   /* End of record */
-#define MSG_WAITALL0x100   /* Wait for a full request */
-#define MSG_FIN 0x200
-#define MSG_SYN0x400
-#define MSG_CONFIRM0x800   /* Confirm path validity */
-#define MSG_RST0x1000
-#define MSG_ERRQUEUE   0x2000  /* Fetch message from error queue */
-#define MSG_NOSIGNAL   0x4000  /* Do not generate SIGPIPE */
-#define MSG_MORE   0x8000  /* Sender will send more */
-#define MSG_WAITFORONE 0x1 /* recvmmsg(): block until 1+ packets avail */
-#define MSG_SENDPAGE_NOPOLICY 0x1 /* sendpage() internal : do no apply 
policy */
-#define MSG_SENDPAGE_NOTLAST 0x2 /* sendpage() internal : not the last 
page */
-#define MSG_BATCH  0x4 /* sendmmsg(): more messages coming */
-#define MSG_EOF MSG_FIN
-#define MSG_NO_SHARED_FRAGS 0x8 /* sendpage() internal : page frags are 
not shared */
-#define MSG_SENDPAGE_DECRYPTED 0x10 /* sendpage() internal : page may carry
- * plain text and require encryption
- */
-
-#define MSG_ZEROCOPY   0x400   /* Use user data in kernel path */
-#define MSG_FASTOPEN   0x2000  /* Send data in TCP SYN */
-#define MSG_CMSG_CLOEXEC 0x4000/* Set close_on_exec for file
-  descriptor received through
-  SCM_RIGHTS */
+#define MSG_OOBBIT(0)
+#define MSG_PEEK   BIT(1)
+#define MSG_DONTROUTE  BIT(2)
+#define MSG_TRYHARDBIT(2)  /* Synonym for MSG_DONTROUTE for DECnet 
*/
+#define MSG_CTRUNC BIT(3)
+#define MSG_PROBE  BIT(4)  /* Do not send. Only probe path f.e. for MTU
*/
+#define MSG_TRUNC  BIT(5)
+#define MSG_DONTWAIT   BIT(6)  /* Nonblocking io   */
+#define MSG_EORBIT(7)  /* End of record*/
+#define MSG_WAITALLBIT(8)  /* Wait for a full request  */
+#define MSG_FINBIT(9)
+#define MSG_SYNBIT(10)
+#define MSG_CONFIRMBIT(11) /* Confirm path validity*/
+#define MSG_RSTBIT(12)
+#define MSG_ERRQUEUE   BIT(13) /* Fetch message from error queue */
+#define MSG_NOSIGNAL   BIT(14) /* Do not generate SIGPIPE  */
+#define MSG_MORE   BIT(15) /* Sender will send more*/
+#define MSG_WAITFORONE BIT(16) /* recvmmsg(): block until 1+ packets avail */
+#define MSG_SENDPAGE_NOPOLICY  BIT(16) /* sendpage() internal : do no apply 
policy */
+#define MSG_SENDPAGE_NOTLAST   BIT(17) /* sendpage() internal : not the last 
page  */
+#define MSG_BATCH  BIT(18) /* sendmmsg(): more messages coming */
+#define MSG_EOFMSG_FIN
+#define MSG_NO_SHARED_FRAGSBIT(19) /* sendpage() internal : page frags
+* are not shared
+*/
+#define MSG_SENDPAGE_DECRYPTED BIT(20) /* sendpage() internal : page may carry
+* plain text and require encryption
+*/
+
+#define MSG_ZEROCOPY   BIT(26) /* Use user data in kernel path */
+#define MSG_FASTOPEN   BIT(29) /* Send data in TCP SYN */
+#define MSG_CMSG_CLOEXEC   BIT(30) /* Set close_on_exec for file
+* descriptor received through
+* SCM_RIGHTS
+*/
 #if defined(CONFIG_COMPAT)
-#define MSG_CMSG_COMPAT0x8000  /* This message needs 32 bit 
fixups */
+#define MSG_CMSG_COMPATBIT(31) /* This message needs 32 bit fixups */
 #else
-#define MSG_CMSG_COMPAT0   /* We never have 32 bit fixups 
*/
+#define MSG_CMSG_COMPAT0   /* We never have 32 bit fixups */
 #endif
 
 
-- 
2.30.0



[PATCH] Staging: mt7621-pci: pci-mt7621: fixed a blank line coding style issue

2021-02-16 Thread Selvakumar Elangovan
Removed an unecessary blank line before closing brace reported by
checkpatch.pl

Signed-off-by: Selvakumar Elangovan 
---
 drivers/staging/mt7621-pci/pci-mt7621.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/staging/mt7621-pci/pci-mt7621.c 
b/drivers/staging/mt7621-pci/pci-mt7621.c
index c3532bc138fb..1781c1dcf5b4 100644
--- a/drivers/staging/mt7621-pci/pci-mt7621.c
+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
@@ -521,7 +521,6 @@ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
 
if (slot == 1 && tmp && !tmp->enabled)
phy_power_off(tmp->phy);
-
}
}
 }
-- 
2.17.1



Re: [PATCH v1] vdpa/mlx5: Restore the hardware used index after change map

2021-02-16 Thread Eli Cohen
On Tue, Feb 16, 2021 at 04:25:20PM -0800, Si-Wei Liu wrote:
> 
> > > The saved mvq->avail_idx will be used to recreate hardware virtq object 
> > > and
> > > the used index in create_virtqueue(), once status DRIVER_OK is set. I
> > > suspect we should pass the index to mvq->used_idx in
> > > mlx5_vdpa_set_vq_state() below instead.
> > > 
> > Right, that's what I am checking but still no final conclusions. I need
> > to harness hardware guy to provide me with clear answers.
> OK. Could you update what you find from the hardware guy and let us know
> e.g. if the current firmware interface would suffice?
> 

Te answer I got is that upon query_virtqueue, the hardware available and
used indices should always return the same value for virtqueues that
complete in order - that's the case for network virtqueues. The value
returned is the consumer index of the hardware. These values should be
provided when creating a virtqueue; in case of attaching to an existing
virtqueue (e.g. after suspend and resume), the values can be non zero.

Currently there's a bug in the firmware where for RX virtqueue, the
value returned for the available index is wrong. However, the value
returned for used index is the correct value.

Therefore, we need to return the hardware used index in get_vq_state()
and restore this value into both the new object's available and used
indices.


[PATCH V0 6/6] MAINTAINERS:Added the entry for DCC(Data Capture and Compare) driver support

2021-02-16 Thread Souradeep Chowdhury
Added the entries for all the files added as a part of driver support for
DCC(Data Capture and Compare).

Signed-off-by: Souradeep Chowdhury 
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 546aa66..f0d208a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4931,6 +4931,14 @@ F:   include/linux/tfrc.h
 F: include/uapi/linux/dccp.h
 F: net/dccp/
 
+QUALCOMM DCC DRIVER
+M: Souradeep Chowdhury 
+L: linux-arm-...@vger.kernel.org
+S: Maintained
+F: Documentation/ABI/testing/sysfs-driver-dcc
+F: Documentation/devicetree/bindings/arm/msm/qcom,dcc.yaml
+F: drivers/soc/qcom/dcc.c
+
 DECnet NETWORK LAYER
 L: linux-decnet-u...@lists.sourceforge.net
 S: Orphan
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



[PATCH V0 2/6] arm64: dts: qcom: sm8150: Add Data Capture and Compare(DCC) support node

2021-02-16 Thread Souradeep Chowdhury
Add the DCC(Data Capture and Compare) device tree node entry along with
the addresses for register regions.

Signed-off-by: Souradeep Chowdhury 
---
 arch/arm64/boot/dts/qcom/sm8150.dtsi | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi 
b/arch/arm64/boot/dts/qcom/sm8150.dtsi
index e5bb17b..3198bd3 100644
--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
@@ -654,6 +654,13 @@
interrupts = ;
};
 
+   dcc@010a2000{
+   compatible = "qcom,sm8150-dcc", "qcom,dcc";
+   reg = <0x0 0x010a2000 0x0 0x1000>,
+   <0x0 0x010ad000 0x0 0x3000>;
+   reg-names = "dcc-base", "dcc-ram-base";
+   };
+
ufs_mem_hc: ufshc@1d84000 {
compatible = "qcom,sm8150-ufshc", "qcom,ufshc",
 "jedec,ufs-2.0";
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



[PATCH V0 3/6] soc: qcom: dcc:Add driver support for Data Capture and Compare unit(DCC)

2021-02-16 Thread Souradeep Chowdhury
The DCC is a DMA Engine designed to capture and store data
during system crash or software triggers.The DCC operates
based on link list entries which provides it with data and
addresses and the function it needs to perform.These functions
are read,write and loop.Added the basic driver in this patch
which contains a probe method which instantiates all the link
list data specific to a SoC.Methods have also been added to
handle all the functionalities specific to a linked list.Each
DCC has it's own SRAM which needs to be instantiated at probe
time as well.

Signed-off-by: Souradeep Chowdhury 
---
 drivers/soc/qcom/Kconfig  |8 +
 drivers/soc/qcom/Makefile |1 +
 drivers/soc/qcom/dcc.c| 1055 +
 3 files changed, 1064 insertions(+)
 create mode 100644 drivers/soc/qcom/dcc.c

diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 79b568f..8819e0b 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -69,6 +69,14 @@ config QCOM_LLCC
  SDM845. This provides interfaces to clients that use the LLCC.
  Say yes here to enable LLCC slice driver.
 
+config QCOM_DCC
+   tristate "Qualcomm Technologies, Inc. Data Capture and Compare engine 
driver"
+   depends on ARCH_QCOM || COMPILE_TEST
+   help
+ This option enables driver for Data Capture and Compare engine. DCC
+ driver provides interface to configure DCC block and read back
+ captured data from DCC's internal SRAM.
+
 config QCOM_KRYO_L2_ACCESSORS
bool
depends on ARCH_QCOM && ARM64 || COMPILE_TEST
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index ad675a6..1b00870 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -26,3 +26,4 @@ obj-$(CONFIG_QCOM_LLCC) += llcc-qcom.o
 obj-$(CONFIG_QCOM_RPMHPD) += rpmhpd.o
 obj-$(CONFIG_QCOM_RPMPD) += rpmpd.o
 obj-$(CONFIG_QCOM_KRYO_L2_ACCESSORS) +=kryo-l2-accessors.o
+obj-$(CONFIG_QCOM_DCC) += dcc.o
diff --git a/drivers/soc/qcom/dcc.c b/drivers/soc/qcom/dcc.c
new file mode 100644
index 000..d67452b
--- /dev/null
+++ b/drivers/soc/qcom/dcc.c
@@ -0,0 +1,1055 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define TIMEOUT_US 100
+
+#define BM(lsb, msb)   ((BIT(msb) - BIT(lsb)) + BIT(msb))
+#define BMVAL(val, lsb, msb)   ((val & BM(lsb, msb)) >> lsb)
+#define BVAL(val, n)   ((val & BIT(n)) >> n)
+
+#define dcc_writel(drvdata, val, off)  \
+   writel((val), drvdata->base + dcc_offset_conv(drvdata, off))
+#define dcc_readl(drvdata, off)
\
+   readl(drvdata->base + dcc_offset_conv(drvdata, off))
+
+#define dcc_sram_readl(drvdata, off)   \
+   readl(drvdata->ram_base + off)
+
+/* DCC registers */
+#define DCC_HW_INFO0x04
+#define DCC_LL_NUM_INFO0x10
+#define DCC_STATUS 0x1C
+#define DCC_LL_LOCK(m) (0x34 + 0x80 * m)
+#define DCC_LL_CFG(m)  (0x38 + 0x80 * m)
+#define DCC_LL_BASE(m) (0x3c + 0x80 * m)
+#define DCC_FD_BASE(m) (0x40 + 0x80 * m)
+#define DCC_LL_TIMEOUT(m)  (0x44 + 0x80 * m)
+#define DCC_LL_INT_ENABLE(m)   (0x4C + 0x80 * m)
+#define DCC_LL_INT_STATUS(m)   (0x50 + 0x80 * m)
+#define DCC_LL_SW_TRIGGER(m)   (0x60 + 0x80 * m)
+#define DCC_LL_BUS_ACCESS_STATUS(m)(0x64 + 0x80 * m)
+
+#define DCC_MAP_LEVEL1 0x18
+#define DCC_MAP_LEVEL2 0x34
+#define DCC_MAP_LEVEL3 0x4C
+
+#define DCC_MAP_OFFSET10x10
+#define DCC_MAP_OFFSET20x18
+#define DCC_MAP_OFFSET30x1C
+#define DCC_MAP_OFFSET40x8
+
+#define DCC_FIX_LOOP_OFFSET16
+#define DCC_VER_INFO_BIT   9
+
+#define DCC_READ0
+#define DCC_WRITE   1
+#define DCC_LOOP2
+#define DCC_READ_WRITE  3
+
+#define MAX_DCC_OFFSET (0xFF * 4)
+#define MAX_DCC_LEN0x7F
+#define MAX_LOOP_CNT   0xFF
+
+#define DCC_ADDR_DESCRIPTOR0x00
+#define DCC_LOOP_DESCRIPTOR(BIT(30))
+#define DCC_RD_MOD_WR_DESCRIPTOR   (BIT(31))
+#define DCC_LINK_DESCRIPTOR(BIT(31) | BIT(30))
+
+#define DCC_READ_IND   0x00
+#define DCC_WRITE_IND  

[PATCH V0 5/6] DCC:Added the sysfs entries for DCC(Data Capture and Compare) driver

2021-02-16 Thread Souradeep Chowdhury
The DCC is a DMA engine designed to store register values either in
case of a system crash or in case of software triggers manually done
by the user.Using DCC hardware and the sysfs interface of the driver
the user can exploit various functionalities of DCC.The user can specify
the register addresses,the values of which is stored by DCC in it's
dedicated SRAM.The register addresses can be used either to read from,
write to,first read and store value and then write or to loop.All these
options can be exploited using the sysfs interface given to the user.
Following are the sysfs interfaces exposed in DCC driver which are
documented
1)trigger
2)config
3)config_write
4)config_reset
5)enable
6)rd_mod_wr
7)loop

Signed-off-by: Souradeep Chowdhury 
---
 Documentation/ABI/testing/sysfs-driver-dcc | 74 ++
 1 file changed, 74 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-driver-dcc

diff --git a/Documentation/ABI/testing/sysfs-driver-dcc 
b/Documentation/ABI/testing/sysfs-driver-dcc
new file mode 100644
index 000..7a855ca
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-dcc
@@ -0,0 +1,74 @@
+What:   /sys/bus/platform/devices/.../trigger
+Date:   February 2021
+Contact:Souradeep Chowdhury 
+Description:
+   This file allows the software trigger to be enabled
+   by the user through the sysfs interface.Through this
+   interface the user can manually start a software trigger
+   in dcc where by the dcc driver stores the current status
+   of the specified registers in dcc sram.
+
+What:   /sys/bus/platform/devices/.../enable
+Date:   February 2021
+Contact:Souradeep Chowdhury 
+Description:
+   This file allows the user to manually enable or
+   disable dcc driver.The dcc hardware needs to be
+   enabled before use.
+
+What:   /sys/bus/platform/devices/.../config
+Date:   February 2021
+Contact:Souradeep Chowdhury 
+Description:
+   This file allows user to configure the register values
+   along with addresses to the dcc driver.This register
+   addresses are used to read from,write or loop through.
+   To enable all these options separate sysfs files have
+   are created.
+
+What:   /sys/bus/platform/devices/.../config_write
+Date:   February 2021
+Contact:Souradeep Chowdhury 
+Description:
+   This file allows user to write a value to the register
+   address given as argument.The values are entered in the
+   form of  .
+
+What:   /sys/bus/platform/devices/.../config_reset
+Date:   February 2021
+Contact:Souradeep Chowdhury 
+Description:
+   This file is used to reset the configuration of
+   a dcc driver to the default configuration.
+
+What:   /sys/bus/platform/devices/.../loop
+Date:   February 2021
+Contact:Souradeep Chowdhury 
+Description:
+   This file is used to enter the loop count as dcc
+   driver gives the option to loop multiple times on
+   the same register and store the values for each
+   loop.
+
+What:   /sys/bus/platform/devices/.../rd_mod_wr
+Date:   February 2021
+Contact:Souradeep Chowdhury 
+Description:
+   This file is used to read the value of the register
+   and then write the value given as an argument to the
+   register address in config.The address argument should
+   be given of the form  .
+
+What:   /sys/bus/platform/devices/.../ready
+Date:   February 2021
+Contact:Souradeep Chowdhury 
+Description:
+   This file is used to check the status of the dcc
+   hardware if it's ready to take the inputs.
+
+What:  /sys/bus/platform/devices/.../curr_list
+Date:  February 2021
+Contact:   Souradeep Chowdhury 
+Description:
+   This file is used to configure the linkedlist data
+   to be used while configuring addresses.
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



[PATCH V0 4/6] soc: qcom: dcc:Add the sysfs variables to the Data Capture and Compare driver(DCC)

2021-02-16 Thread Souradeep Chowdhury
Added the sysfs variables to expose the user space functionalities
like DCC enable,disable,configure addresses and software triggers.
Also added the necessary methods along with the same.

Signed-off-by: Souradeep Chowdhury 
---
 drivers/soc/qcom/dcc.c | 519 +
 1 file changed, 519 insertions(+)

diff --git a/drivers/soc/qcom/dcc.c b/drivers/soc/qcom/dcc.c
index d67452b..02eee96 100644
--- a/drivers/soc/qcom/dcc.c
+++ b/drivers/soc/qcom/dcc.c
@@ -185,6 +185,82 @@ static int dcc_sram_writel(struct dcc_drvdata *drvdata,
return 0;
 }
 
+static bool dcc_ready(struct dcc_drvdata *drvdata)
+{
+   u32 val;
+
+   /* poll until DCC ready */
+   if (!readl_poll_timeout((drvdata->base + DCC_STATUS), val,
+   (BMVAL(val, 0, 1) == 0), 1, TIMEOUT_US))
+   return true;
+
+   return false;
+}
+
+static int dcc_read_status(struct dcc_drvdata *drvdata)
+{
+   int curr_list;
+   u32 bus_status;
+   u32 ll_cfg = 0;
+   u32 tmp_ll_cfg = 0;
+
+   for (curr_list = 0; curr_list < drvdata->nr_link_list; curr_list++) {
+   if (!drvdata->enable[curr_list])
+   continue;
+
+   bus_status = dcc_readl(drvdata, 
DCC_LL_BUS_ACCESS_STATUS(curr_list));
+
+   if (bus_status) {
+   dev_err(drvdata->dev,
+   "Read access error for list %d err: 0x%x.\n",
+   curr_list, bus_status);
+
+   ll_cfg = dcc_readl(drvdata, DCC_LL_CFG(curr_list));
+   tmp_ll_cfg = ll_cfg & ~BIT(9);
+   dcc_writel(drvdata, tmp_ll_cfg, DCC_LL_CFG(curr_list));
+   dcc_writel(drvdata, 0x3,
+   DCC_LL_BUS_ACCESS_STATUS(curr_list));
+   dcc_writel(drvdata, ll_cfg, DCC_LL_CFG(curr_list));
+   return -ENODATA;
+   }
+   }
+
+   return 0;
+}
+
+static int dcc_sw_trigger(struct dcc_drvdata *drvdata)
+{
+   int ret = 0;
+   int curr_list;
+   u32 ll_cfg = 0;
+   u32 tmp_ll_cfg = 0;
+
+   mutex_lock(>mutex);
+
+   for (curr_list = 0; curr_list < drvdata->nr_link_list; curr_list++) {
+   if (!drvdata->enable[curr_list])
+   continue;
+   ll_cfg = dcc_readl(drvdata, DCC_LL_CFG(curr_list));
+   tmp_ll_cfg = ll_cfg & ~BIT(9);
+   dcc_writel(drvdata, tmp_ll_cfg, DCC_LL_CFG(curr_list));
+   dcc_writel(drvdata, 1, DCC_LL_SW_TRIGGER(curr_list));
+   dcc_writel(drvdata, ll_cfg, DCC_LL_CFG(curr_list));
+   }
+
+   if (!dcc_ready(drvdata)) {
+   dev_err(drvdata->dev,
+   "DCC is busy after receiving sw tigger.\n");
+   ret = -EBUSY;
+   goto err;
+   }
+
+   ret = dcc_read_status(drvdata);
+
+err:
+   mutex_unlock(>mutex);
+   return ret;
+}
+
 static int _dcc_ll_cfg_read_write(struct dcc_drvdata *drvdata,
 struct dcc_config_entry *entry, struct dcc_cfg_attr *cfg)
 {
@@ -628,6 +704,211 @@ static int dcc_enable(struct dcc_drvdata *drvdata)
return ret;
 }
 
+static void dcc_disable(struct dcc_drvdata *drvdata)
+{
+   int curr_list;
+
+   mutex_lock(>mutex);
+
+   if (!dcc_ready(drvdata))
+   dev_err(drvdata->dev, "DCC is not ready Disabling DCC...\n");
+
+   for (curr_list = 0; curr_list < drvdata->nr_link_list; curr_list++) {
+   if (!drvdata->enable[curr_list])
+   continue;
+   dcc_writel(drvdata, 0, DCC_LL_CFG(curr_list));
+   dcc_writel(drvdata, 0, DCC_LL_BASE(curr_list));
+   dcc_writel(drvdata, 0, DCC_FD_BASE(curr_list));
+   dcc_writel(drvdata, 0, DCC_LL_LOCK(curr_list));
+   drvdata->enable[curr_list] = false;
+   }
+   memset_io(drvdata->ram_base, 0, drvdata->ram_size);
+   drvdata->ram_cfg = 0;
+   drvdata->ram_start = 0;
+   mutex_unlock(>mutex);
+}
+
+static ssize_t curr_list_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   int ret;
+   struct dcc_drvdata *drvdata = dev_get_drvdata(dev);
+
+   mutex_lock(>mutex);
+   if (drvdata->curr_list == DCC_INVALID_LINK_LIST) {
+   dev_err(dev, "curr_list is not set.\n");
+   ret = -EINVAL;
+   goto err;
+   }
+
+   ret = scnprintf(buf, PAGE_SIZE, "%d\n", drvdata->curr_list);
+err:
+   mutex_unlock(>mutex);
+   return ret;
+}
+
+static ssize_t curr_list_store(struct device *dev,
+   struct device_attribute *attr,
+   const char *buf, size_t size)
+{
+   struct dcc_drvdata *drvdata = dev_get_drvdata(dev);
+   unsigned long val;
+   u32 lock_reg;
+   bool dcc_enable = false;
+
+

[PATCH V0 0/6] Add driver support for Data Capture and Compare Engine(DCC) for SM8150

2021-02-16 Thread Souradeep Chowdhury
DCC(Data Capture and Compare) is a DMA engine designed for debugging 
purposes.In case of a system
crash or manual software triggers by the user the DCC hardware stores the value 
at the register
addresses which can be used for debugging purposes.The DCC driver provides the 
user with sysfs
interface to configure the register addresses.The options that the DCC hardware 
provides include
reading from registers,writing to registers,first reading and then writing to 
registers and looping
through the values of the same register.
In certain cases a register write needs to be executed for
accessing the rest of the registers,also the user might want to recaord the 
changing values of a
particular register with time for which he has the option to use the loop 
feature.
The options mentioned above are exposed to the user by sysfs files once the 
driver is probed.The
details and usage of this sysfs files are documented in 
Documentation/ABI/testing/sysfs-driver-dcc.
As an example if a user wants to configure to store 100 words starting from 
address 0x8050
he should give inputs as following to the sysfs config file:-
echo  0x8050 100 > /sys/bus/platform/devices/.../config
Similarly if he wants to write to a register using DCC hardware he should give 
following input to
config_write sysfs file:-
echo 0x8000 0xFF > /sys/bus/platform/devices/10a2000.dcc/config_write
This will write the value 0xFF on address 0x8000.
All this read and write occurs at crash time or if the user manually invokes a 
software trigger.

Souradeep Chowdhury (6):
  dt-bindings: Added the yaml bindings for DCC
  arm64: dts: qcom: sm8150: Add Data Capture and Compare(DCC) support
node
  soc: qcom: dcc:Add driver support for Data Capture and Compare
unit(DCC)
  soc: qcom: dcc:Add the sysfs variables to the Data Capture and Compare
driver(DCC)
  DCC:Added the sysfs entries for DCC(Data Capture and Compare) driver
  MAINTAINERS:Added the entry for DCC(Data Capture and Compare) driver
support

 Documentation/ABI/testing/sysfs-driver-dcc |   74 +
 .../devicetree/bindings/arm/msm/qcom,dcc.yaml  |   49 +
 MAINTAINERS|8 +
 arch/arm64/boot/dts/qcom/sm8150.dtsi   |7 +
 drivers/soc/qcom/Kconfig   |8 +
 drivers/soc/qcom/Makefile  |1 +
 drivers/soc/qcom/dcc.c | 1574 
 7 files changed, 1721 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-driver-dcc
 create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,dcc.yaml
 create mode 100644 drivers/soc/qcom/dcc.c

--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



[PATCH V0 1/6] dt-bindings: Added the yaml bindings for DCC

2021-02-16 Thread Souradeep Chowdhury
Documentation for Data Capture and Compare(DCC) device tree bindings
in yaml format.

Signed-off-by: Souradeep Chowdhury 
---
 .../devicetree/bindings/arm/msm/qcom,dcc.yaml  | 49 ++
 1 file changed, 49 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,dcc.yaml

diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,dcc.yaml 
b/Documentation/devicetree/bindings/arm/msm/qcom,dcc.yaml
new file mode 100644
index 000..8f09578
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/qcom,dcc.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/msm/qcom,dcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Data Capture and Compare
+
+maintainers:
+  - Souradeep Chowdhury 
+
+description: |
+DCC (Data Capture and Compare) is a DMA engine which is used to save
+configuration data or system memory contents during catastrophic failure
+or SW trigger.DCC is used to capture and store data for debugging purpose
+
+
+properties:
+  compatible:
+items:
+- enum:
+  - qcom,sm8150-dcc
+- const: qcom,dcc
+
+  reg:
+items:
+  - description: DCC base register region
+  - description: DCC RAM base register region
+
+  reg-names:
+items:
+  - const: dcc-base
+  - const: dcc-ram-base
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+dcc@010a2000{
+compatible = "qcom,sm8150-dcc";
+reg = <0 0x010a2000 0  0x1000>,
+  <0 0x010ae000 0  0x2000>;
+reg-names = "dcc-base", "dcc-ram-base";
+};
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



Re: [PATCH] mm: slub: Convert sys slab alloc_calls, free_calls to bin attribute

2021-02-16 Thread Faiyaz Mohammed
Hi Vlastimil,

On 1/13/2021 9:35 PM, Vlastimil Babka wrote:
> On 1/12/21 10:21 AM, Faiyaz Mohammed wrote:
>> Reading the sys slab alloc_calls, free_calls returns the available object
>> owners, but the size of this file is limited to PAGE_SIZE
>> because of the limitation of sysfs attributes, it is returning the
>> partial owner info, which is not sufficient to debug/account the slab
>> memory and alloc_calls output is not matching with /proc/slabinfo.
>>
>> To remove the PAGE_SIZE limitation converted the sys slab
>> alloc_calls, free_calls to bin attribute.
>>
>> Signed-off-by: Faiyaz Mohammed 
>> ---
>>  mm/slub.c | 61 +++--
>>  1 file changed, 47 insertions(+), 14 deletions(-)
>>
>> diff --git a/mm/slub.c b/mm/slub.c
>> index b52384e..8744e5ec 100644
>> --- a/mm/slub.c
>> +++ b/mm/slub.c
>> @@ -4710,13 +4710,14 @@ static void process_slab(struct loc_track *t, struct 
>> kmem_cache *s,
>>  }
>>  
>>  static int list_locations(struct kmem_cache *s, char *buf,
>> -enum track_item alloc)
>> +loff_t offset, enum track_item alloc)
>>  {
>>  int len = 0;
>>  unsigned long i;
>>  struct loc_track t = { 0, 0, NULL };
>>  int node;
>>  struct kmem_cache_node *n;
>> +static unsigned int previous_read_count;
> 
> Hmm static? What about parallel reads from different files? I guess you'll 
> have
> to somehow employ the offset parameter here and it won't be pretty, because 
> you
> are still printing free text and not some fixed-size binary chunks where 
> seeking
> is simple.
To avoid static, I have used small logic by fixing track max length and
tracks per page. Please find patch v2.

> Also it's wasteful to to repeat the data gathering for each pritned page, 
> you'd
> need a mechanism that allows holding private data between printing out the
> pages. If bin_attribute doesn't have that, you'd need e.g. seq_file which we 
> use
> for /proc/pid/(s)maps etc.>I think seq_file implementation is not feasible 
> with sysfs and I didn't
find any example in kernel. If we want to use seq_file than I guess we
have to move slab in debugfs.


>>  unsigned long *map = bitmap_alloc(oo_objects(s->max), GFP_KERNEL);
> 
> This line doesn't exist since 90e9f6a66c78f in v5.6-rc1, is the patch based on
> an old kernel?
> 
Updated the patch v2.

>>  if (!map || !alloc_loc_track(, PAGE_SIZE / sizeof(struct location),
>> @@ -4742,11 +4743,9 @@ static int list_locations(struct kmem_cache *s, char 
>> *buf,
>>  spin_unlock_irqrestore(>list_lock, flags);
>>  }
>>  
>> -for (i = 0; i < t.count; i++) {
>> +for (i = previous_read_count; i < t.count; i++) {
>>  struct location *l = [i];
>>  
>> -if (len > PAGE_SIZE - KSYM_SYMBOL_LEN - 100)
>> -break;
>>  len += sprintf(buf + len, "%7ld ", l->count);
>>  
>>  if (l->addr)
>> @@ -4784,12 +4783,20 @@ static int list_locations(struct kmem_cache *s, char 
>> *buf,
>>   nodemask_pr_args(>nodes));
>>  
>>  len += sprintf(buf + len, "\n");
>> +
>> +if (len > PAGE_SIZE - KSYM_SYMBOL_LEN - 100) {
>> +previous_read_count = i + 1;
>> +break;
>> +}
>>  }
>>  
>> +if ((offset != 0) && ((i >= t.count) || (previous_read_count > 
>> t.count))) {
>> +previous_read_count = 0;
>> +len = 0;
>> +} else if (!t.count)
>> +len += sprintf(buf, "No data\n");
>>  free_loc_track();
>>  bitmap_free(map);
>> -if (!t.count)
>> -len += sprintf(buf, "No data\n");
>>  return len;
>>  }
>>  
>> @@ -5180,6 +5187,7 @@ static int any_slab_objects(struct kmem_cache *s)
>>  
>>  struct slab_attribute {
>>  struct attribute attr;
>> +struct bin_attribute bin_attr;
>>  ssize_t (*show)(struct kmem_cache *s, char *buf);
>>  ssize_t (*store)(struct kmem_cache *s, const char *x, size_t count);
>>  };
>> @@ -5192,6 +5200,12 @@ struct slab_attribute {
>>  static struct slab_attribute _name##_attr =  \
>>  __ATTR(_name, 0600, _name##_show, _name##_store)
>>  
>> +#define SLAB_BIN_ATTR_RO(_name) \
>> +static struct slab_attribute _name##_attr = { \
>> +.bin_attr = \
>> +__BIN_ATTR_RO(_name, 0) \
>> +} \
>> +
>>  static ssize_t slab_size_show(struct kmem_cache *s, char *buf)
>>  {
>>  return sprintf(buf, "%u\n", s->size);
>> @@ -5535,21 +5549,33 @@ static ssize_t validate_store(struct kmem_cache *s,
>>  }
>>  SLAB_ATTR(validate);
>>  
>> -static ssize_t alloc_calls_show(struct kmem_cache *s, char *buf)
>> +static ssize_t alloc_calls_read(struct file *filp, struct kobject *kobj,
>> +struct bin_attribute *bin_attr, char *buf,
>> +loff_t offset, size_t count)
>>  {
>> +struct kmem_cache *s;
>> +
>> +s = 

Re: [RESEND PATCH] drm/tilcdc: fix raster control register setting

2021-02-16 Thread Tomi Valkeinen
On 16/02/2021 22:22, Dario Binacchi wrote:
> The fdd property of the tilcdc_panel_info structure must set the reqdly
> bit field  (bit 12 to 19) of the raster control register. The previous
> statement set the least significant bit instead.
> 
> Signed-off-by: Dario Binacchi 
> 
> ---
> 
>  drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c 
> b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> index 30213708fc99..238068e28729 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> @@ -393,7 +393,7 @@ static void tilcdc_crtc_set_mode(struct drm_crtc *crtc)
>   return;
>   }
>   }
> - reg |= info->fdd < 12;
> + reg |= info->fdd << 12;
>   tilcdc_write(dev, LCDC_RASTER_CTRL_REG, reg);
>  
>   if (info->invert_pxl_clk)
> 

This is interesting, looks like this has always been broken, and in many
cases sets bits 0, which is the enable bit. So we enable LCDC before
even setting the fb address. How does this not blow up LCDC totally?

The fix looks correct to me, but it will change the register value for
boards that have apparently been working for years.

Dario, did you test this on actual HW, or did you just spot the error?

Reviewed-by: Tomi Valkeinen 

 Tomi


Re: [v8 PATCH 10/13] mm: vmscan: use per memcg nr_deferred of shrinker

2021-02-16 Thread Kirill Tkhai
On 17.02.2021 03:13, Yang Shi wrote:
> Use per memcg's nr_deferred for memcg aware shrinkers.  The shrinker's 
> nr_deferred
> will be used in the following cases:
> 1. Non memcg aware shrinkers
> 2. !CONFIG_MEMCG
> 3. memcg is disabled by boot parameter
> 
> Signed-off-by: Yang Shi 

Acked-by: Kirill Tkhai 

> ---
>  mm/vmscan.c | 78 -
>  1 file changed, 66 insertions(+), 12 deletions(-)
> 
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index fcb399e18fc3..57cbc6bc8a49 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -374,6 +374,24 @@ static void unregister_memcg_shrinker(struct shrinker 
> *shrinker)
>   idr_remove(_idr, id);
>  }
>  
> +static long xchg_nr_deferred_memcg(int nid, struct shrinker *shrinker,
> +struct mem_cgroup *memcg)
> +{
> + struct shrinker_info *info;
> +
> + info = shrinker_info_protected(memcg, nid);
> + return atomic_long_xchg(>nr_deferred[shrinker->id], 0);
> +}
> +
> +static long add_nr_deferred_memcg(long nr, int nid, struct shrinker 
> *shrinker,
> +   struct mem_cgroup *memcg)
> +{
> + struct shrinker_info *info;
> +
> + info = shrinker_info_protected(memcg, nid);
> + return atomic_long_add_return(nr, >nr_deferred[shrinker->id]);
> +}
> +
>  static bool cgroup_reclaim(struct scan_control *sc)
>  {
>   return sc->target_mem_cgroup;
> @@ -412,6 +430,18 @@ static void unregister_memcg_shrinker(struct shrinker 
> *shrinker)
>  {
>  }
>  
> +static long xchg_nr_deferred_memcg(int nid, struct shrinker *shrinker,
> +struct mem_cgroup *memcg)
> +{
> + return 0;
> +}
> +
> +static long add_nr_deferred_memcg(long nr, int nid, struct shrinker 
> *shrinker,
> +   struct mem_cgroup *memcg)
> +{
> + return 0;
> +}
> +
>  static bool cgroup_reclaim(struct scan_control *sc)
>  {
>   return false;
> @@ -423,6 +453,39 @@ static bool writeback_throttling_sane(struct 
> scan_control *sc)
>  }
>  #endif
>  
> +static long xchg_nr_deferred(struct shrinker *shrinker,
> +  struct shrink_control *sc)
> +{
> + int nid = sc->nid;
> +
> + if (!(shrinker->flags & SHRINKER_NUMA_AWARE))
> + nid = 0;
> +
> + if (sc->memcg &&
> + (shrinker->flags & SHRINKER_MEMCG_AWARE))
> + return xchg_nr_deferred_memcg(nid, shrinker,
> +   sc->memcg);
> +
> + return atomic_long_xchg(>nr_deferred[nid], 0);
> +}
> +
> +
> +static long add_nr_deferred(long nr, struct shrinker *shrinker,
> + struct shrink_control *sc)
> +{
> + int nid = sc->nid;
> +
> + if (!(shrinker->flags & SHRINKER_NUMA_AWARE))
> + nid = 0;
> +
> + if (sc->memcg &&
> + (shrinker->flags & SHRINKER_MEMCG_AWARE))
> + return add_nr_deferred_memcg(nr, nid, shrinker,
> +  sc->memcg);
> +
> + return atomic_long_add_return(nr, >nr_deferred[nid]);
> +}
> +
>  /*
>   * This misses isolated pages which are not accounted for to save counters.
>   * As the data only determines if reclaim or compaction continues, it is
> @@ -558,14 +621,10 @@ static unsigned long do_shrink_slab(struct 
> shrink_control *shrinkctl,
>   long freeable;
>   long nr;
>   long new_nr;
> - int nid = shrinkctl->nid;
>   long batch_size = shrinker->batch ? shrinker->batch
> : SHRINK_BATCH;
>   long scanned = 0, next_deferred;
>  
> - if (!(shrinker->flags & SHRINKER_NUMA_AWARE))
> - nid = 0;
> -
>   freeable = shrinker->count_objects(shrinker, shrinkctl);
>   if (freeable == 0 || freeable == SHRINK_EMPTY)
>   return freeable;
> @@ -575,7 +634,7 @@ static unsigned long do_shrink_slab(struct shrink_control 
> *shrinkctl,
>* and zero it so that other concurrent shrinker invocations
>* don't also do this scanning work.
>*/
> - nr = atomic_long_xchg(>nr_deferred[nid], 0);
> + nr = xchg_nr_deferred(shrinker, shrinkctl);
>  
>   total_scan = nr;
>   if (shrinker->seeks) {
> @@ -666,14 +725,9 @@ static unsigned long do_shrink_slab(struct 
> shrink_control *shrinkctl,
>   next_deferred = 0;
>   /*
>* move the unused scan count back into the shrinker in a
> -  * manner that handles concurrent updates. If we exhausted the
> -  * scan, there is no need to do an update.
> +  * manner that handles concurrent updates.
>*/
> - if (next_deferred > 0)
> - new_nr = atomic_long_add_return(next_deferred,
> - >nr_deferred[nid]);
> - else
> - new_nr = atomic_long_read(>nr_deferred[nid]);
> + new_nr = add_nr_deferred(next_deferred, shrinker, shrinkctl);
>  
>   trace_mm_shrink_slab_end(shrinker, shrinkctl->nid, 

Re: [PATCH v2 0/5] dax-device: Some cleanups

2021-02-16 Thread Uwe Kleine-König

Hello Dan,

On 2/17/21 4:55 AM, Dan Williams wrote:

One small comment on patch5, otherwise looks good.


I take it back, patch5 looks good. I was going to ask about the return
value removal for dax_bus_remove(), but that would need struct
bus_type to change prototypes.


Changing struct bus_type::remove to return void is the eventual plan. To 
make this a pretty and easily reviewable patch I currently go through 
all buses and make sure that for the prototype change I only have to do 
one s/int/void/ and drop a "return 0" per bus.



All merged to the nvdimm tree.


Great, thanks
Uwe



OpenPGP_signature
Description: OpenPGP digital signature


Re: KASAN: invalid-access Write in enqueue_timer

2021-02-16 Thread Dmitry Vyukov
On Tue, Feb 16, 2021 at 7:15 PM Dmitry Vyukov  wrote:
> > On Tue, Feb 16, 2021 at 06:50:20PM +0100, Jason A. Donenfeld wrote:
> > > On Tue, Feb 16, 2021 at 6:46 PM Jason A. Donenfeld  
> > > wrote:
> > > > On Tue, Feb 16, 2021 at 6:28 PM Catalin Marinas 
> > > >  wrote:
> > > > > >  hlist_add_head include/linux/list.h:883 [inline]
> > > > > >  enqueue_timer+0x18/0xc0 kernel/time/timer.c:581
> > > > > >  mod_timer+0x14/0x20 kernel/time/timer.c:1106
> > > > > >  mod_peer_timer drivers/net/wireguard/timers.c:37 [inline]
> > > > > >  wg_timers_any_authenticated_packet_traversal+0x68/0x90 
> > > > > > drivers/net/wireguard/timers.c:215
> > > >
> > > > The line of hlist_add_head that it's hitting is:
> > > >
> > > > static inline void hlist_add_head(struct hlist_node *n, struct 
> > > > hlist_head *h)
> > > > {
> > > >struct hlist_node *first = h->first;
> > > >WRITE_ONCE(n->next, first);
> > > >if (first)
> > > >
> > > > So that means it's the dereferencing of h that's a problem. That comes 
> > > > from:
> > > >
> > > > static void enqueue_timer(struct timer_base *base, struct timer_list 
> > > > *timer,
> > > >  unsigned int idx, unsigned long bucket_expiry)
> > > > {
> > > >
> > > >hlist_add_head(>entry, base->vectors + idx);
> > > >
> > > > That means it concerns base->vectors + idx, not the timer_list object
> > > > that wireguard manages. That's confusing. Could that imply that the
> > > > bug is in freeing a previous timer without removing it from the timer
> > > > lists, so that it winds up being in base->vectors?
> >
> > Good point, it's indeed likely that the timer list is messed up already,
> > just an unlucky encounter in the wireguard code.
> >
> > > Digging around on syzkaller, it looks like there's a similar bug on
> > > jbd2, concerning iptunnels's allocation:
> > >
> > > https://syzkaller.appspot.com/text?tag=CrashReport=13afb19cd0
> > [...]
> > > It might not actually be a wireguard bug?
> >
> > I wonder whether syzbot reported similar issues with
> > CONFIG_KASAN_SW_TAGS. It shouldn't be that different from the HW_TAGS
> > but at least we can rule out qemu bugs with the MTE emulation.
>
> +Eric

I've seen some similar reports on other syzkaller instances. They all
have similar alloc/free stacks, but different access stacks.
This does not seem to be wireguard nor arm/mte related. It seems that
something released the device prematurely, and then some innocent code
gets a use-after-free.


Re: [v8 PATCH 09/13] mm: vmscan: add per memcg shrinker nr_deferred

2021-02-16 Thread Kirill Tkhai
On 17.02.2021 03:13, Yang Shi wrote:
> Currently the number of deferred objects are per shrinker, but some slabs, 
> for example,
> vfs inode/dentry cache are per memcg, this would result in poor isolation 
> among memcgs.
> 
> The deferred objects typically are generated by __GFP_NOFS allocations, one 
> memcg with
> excessive __GFP_NOFS allocations may blow up deferred objects, then other 
> innocent memcgs
> may suffer from over shrink, excessive reclaim latency, etc.
> 
> For example, two workloads run in memcgA and memcgB respectively, workload in 
> B is vfs
> heavy workload.  Workload in A generates excessive deferred objects, then B's 
> vfs cache
> might be hit heavily (drop half of caches) by B's limit reclaim or global 
> reclaim.
> 
> We observed this hit in our production environment which was running vfs 
> heavy workload
> shown as the below tracing log:
> 
> <...>-409454 [016]  28286961.747146: mm_shrink_slab_start: 
> super_cache_scan+0x0/0x1a0 9a83046f3458:
> nid: 1 objects to shrink 3641681686040 gfp_flags 
> GFP_HIGHUSER_MOVABLE|__GFP_ZERO pgs_scanned 1 lru_pgs 15721
> cache items 246404277 delta 31345 total_scan 123202138
> <...>-409454 [022]  28287105.928018: mm_shrink_slab_end: 
> super_cache_scan+0x0/0x1a0 9a83046f3458:
> nid: 1 unused scan count 3641681686040 new scan count 3641798379189 
> total_scan 602
> last shrinker return val 123186855
> 
> The vfs cache and page cache ratio was 10:1 on this machine, and half of 
> caches were dropped.
> This also resulted in significant amount of page caches were dropped due to 
> inodes eviction.
> 
> Make nr_deferred per memcg for memcg aware shrinkers would solve the 
> unfairness and bring
> better isolation.
> 
> When memcg is not enabled (!CONFIG_MEMCG or memcg disabled), the shrinker's 
> nr_deferred
> would be used.  And non memcg aware shrinkers use shrinker's nr_deferred all 
> the time.
> 
> Signed-off-by: Yang Shi 

Acked-by: Kirill Tkhai 

> ---
>  include/linux/memcontrol.h |  7 +++--
>  mm/vmscan.c| 60 ++
>  2 files changed, 46 insertions(+), 21 deletions(-)
> 
> diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
> index 4c9253896e25..c457fc7bc631 100644
> --- a/include/linux/memcontrol.h
> +++ b/include/linux/memcontrol.h
> @@ -93,12 +93,13 @@ struct lruvec_stat {
>  };
>  
>  /*
> - * Bitmap of shrinker::id corresponding to memcg-aware shrinkers,
> - * which have elements charged to this memcg.
> + * Bitmap and deferred work of shrinker::id corresponding to memcg-aware
> + * shrinkers, which have elements charged to this memcg.
>   */
>  struct shrinker_info {
>   struct rcu_head rcu;
> - unsigned long map[];
> + atomic_long_t *nr_deferred;
> + unsigned long *map;
>  };
>  
>  /*
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index a1047ea60ecf..fcb399e18fc3 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -187,11 +187,17 @@ static DECLARE_RWSEM(shrinker_rwsem);
>  #ifdef CONFIG_MEMCG
>  static int shrinker_nr_max;
>  
> +/* The shrinker_info is expanded in a batch of BITS_PER_LONG */
>  static inline int shrinker_map_size(int nr_items)
>  {
>   return (DIV_ROUND_UP(nr_items, BITS_PER_LONG) * sizeof(unsigned long));
>  }
>  
> +static inline int shrinker_defer_size(int nr_items)
> +{
> + return (round_up(nr_items, BITS_PER_LONG) * sizeof(atomic_long_t));
> +}
> +
>  static struct shrinker_info *shrinker_info_protected(struct mem_cgroup 
> *memcg,
>int nid)
>  {
> @@ -200,10 +206,12 @@ static struct shrinker_info 
> *shrinker_info_protected(struct mem_cgroup *memcg,
>  }
>  
>  static int expand_one_shrinker_info(struct mem_cgroup *memcg,
> - int size, int old_size)
> + int map_size, int defer_size,
> + int old_map_size, int old_defer_size)
>  {
>   struct shrinker_info *new, *old;
>   int nid;
> + int size = map_size + defer_size;
>  
>   for_each_node(nid) {
>   old = shrinker_info_protected(memcg, nid);
> @@ -215,9 +223,16 @@ static int expand_one_shrinker_info(struct mem_cgroup 
> *memcg,
>   if (!new)
>   return -ENOMEM;
>  
> - /* Set all old bits, clear all new bits */
> - memset(new->map, (int)0xff, old_size);
> - memset((void *)new->map + old_size, 0, size - old_size);
> + new->nr_deferred = (atomic_long_t *)(new + 1);
> + new->map = (void *)new->nr_deferred + defer_size;
> +
> + /* map: set all old bits, clear all new bits */
> + memset(new->map, (int)0xff, old_map_size);
> + memset((void *)new->map + old_map_size, 0, map_size - 
> old_map_size);
> + /* nr_deferred: copy old values, clear all new values */
> + memcpy(new->nr_deferred, old->nr_deferred, old_defer_size);
> + 

Re: [PATCH] mm: slub: Convert sys slab alloc_calls, free_calls to bin attribute

2021-02-16 Thread Faiyaz Mohammed
Hi Matthew,

On 1/12/2021 5:52 PM, Matthew Wilcox wrote:
> On Tue, Jan 12, 2021 at 02:51:27PM +0530, Faiyaz Mohammed wrote:
>> @@ -5180,6 +5187,7 @@ static int any_slab_objects(struct kmem_cache *s)
>>  
>>  struct slab_attribute {
>>  struct attribute attr;
>> +struct bin_attribute bin_attr;
>>  ssize_t (*show)(struct kmem_cache *s, char *buf);
>>  ssize_t (*store)(struct kmem_cache *s, const char *x, size_t count);
>>  };
> 
> I'd rather you added a struct slab_bin_attribute.  If that's even
> needed ..  I think you could just use the bin_attribute directly instead
> of embedding it in this struct.
> 
Yes, we can use bin_attribute directly. Please find patch v2.


Re: [v8 PATCH 05/13] mm: vmscan: use kvfree_rcu instead of call_rcu

2021-02-16 Thread Kirill Tkhai
On 17.02.2021 03:13, Yang Shi wrote:
> Using kvfree_rcu() to free the old shrinker_maps instead of call_rcu().
> We don't have to define a dedicated callback for call_rcu() anymore.
> 
> Signed-off-by: Yang Shi 

Acked-by: Kirill Tkhai 

> ---
>  mm/vmscan.c | 7 +--
>  1 file changed, 1 insertion(+), 6 deletions(-)
> 
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index 2e753c2516fa..c2a309acd86b 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -192,11 +192,6 @@ static inline int shrinker_map_size(int nr_items)
>   return (DIV_ROUND_UP(nr_items, BITS_PER_LONG) * sizeof(unsigned long));
>  }
>  
> -static void free_shrinker_map_rcu(struct rcu_head *head)
> -{
> - kvfree(container_of(head, struct memcg_shrinker_map, rcu));
> -}
> -
>  static int expand_one_shrinker_map(struct mem_cgroup *memcg,
>  int size, int old_size)
>  {
> @@ -219,7 +214,7 @@ static int expand_one_shrinker_map(struct mem_cgroup 
> *memcg,
>   memset((void *)new->map + old_size, 0, size - old_size);
>  
>   rcu_assign_pointer(memcg->nodeinfo[nid]->shrinker_map, new);
> - call_rcu(>rcu, free_shrinker_map_rcu);
> + kvfree_rcu(old);
>   }
>  
>   return 0;
> 



Re: [PATCH] remove unused variable driver_desc

2021-02-16 Thread Greg Kroah-Hartman
On Tue, Feb 16, 2021 at 10:59:51PM -0500, Sean Behan wrote:
> ---
>  drivers/staging/emxx_udc/emxx_udc.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/staging/emxx_udc/emxx_udc.c 
> b/drivers/staging/emxx_udc/emxx_udc.c
> index 3536c03ff523..741147a4f0fe 100644
> --- a/drivers/staging/emxx_udc/emxx_udc.c
> +++ b/drivers/staging/emxx_udc/emxx_udc.c
> @@ -38,7 +38,6 @@ static struct gpio_desc *vbus_gpio;
>  static int vbus_irq;
>  
>  static const chardriver_name[] = "emxx_udc";
> -static const chardriver_desc[] = DRIVER_DESC;
>  
>  
> /*===*/
>  /* Prototype */
> -- 
> 2.29.2


Hi,

This is the friendly patch-bot of Greg Kroah-Hartman.  You have sent him
a patch that has triggered this response.  He used to manually respond
to these common problems, but in order to save his sanity (he kept
writing the same thing over and over, yet to different people), I was
created.  Hopefully you will not take offence and will fix the problem
in your patch and resubmit it so that it can be accepted into the Linux
kernel tree.

You are receiving this message because of the following common error(s)
as indicated below:

- Your patch does not have a Signed-off-by: line.  Please read the
  kernel file, Documentation/SubmittingPatches and resend it after
  adding that line.  Note, the line needs to be in the body of the
  email, before the patch, not at the bottom of the patch or in the
  email signature.

- You did not specify a description of why the patch is needed, or
  possibly, any description at all, in the email body.  Please read the
  section entitled "The canonical patch format" in the kernel file,
  Documentation/SubmittingPatches for what is needed in order to
  properly describe the change.

- You did not write a descriptive Subject: for the patch, allowing Greg,
  and everyone else, to know what this patch is all about.  Please read
  the section entitled "The canonical patch format" in the kernel file,
  Documentation/SubmittingPatches for what a proper Subject: line should
  look like.

If you wish to discuss this problem further, or you have questions about
how to resolve this issue, please feel free to respond to this email and
Greg will reply once he has dug out from the pending patches received
from other developers.

thanks,

greg k-h's patch email bot


arch/sh/kernel/ftrace.c:368:17: sparse: sparse: incorrect type in argument 1 (different address spaces)

2021-02-16 Thread kernel test robot
Hi Luc,

First bad commit (maybe != root cause):

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
master
head:   f40ddce88593482919761f74910f42f4b84c004b
commit: e5fc436f06eef54ef512ea55a9db8eb9f2e76959 sparse: use static inline for 
__chk_{user,io}_ptr()
date:   6 months ago
config: sh-randconfig-s032-20210217 (attached as .config)
compiler: sh4-linux-gcc (GCC) 9.3.0
reproduce:
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# apt-get install sparse
# sparse version: v0.6.3-215-g0fb77bb6-dirty
# 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e5fc436f06eef54ef512ea55a9db8eb9f2e76959
git remote add linus 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
git fetch --no-tags linus master
git checkout e5fc436f06eef54ef512ea55a9db8eb9f2e76959
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross C=1 
CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=sh 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 


"sparse warnings: (new ones prefixed by >>)"
>> arch/sh/kernel/ftrace.c:368:17: sparse: sparse: incorrect type in argument 1 
>> (different address spaces) @@ expected void const volatile [noderef] 
>> __iomem *ptr @@ got unsigned long *parent @@
   arch/sh/kernel/ftrace.c:368:17: sparse: expected void const volatile 
[noderef] __iomem *ptr
   arch/sh/kernel/ftrace.c:368:17: sparse: got unsigned long *parent
--
>> arch/sh/kernel/cpu/sh3/serial-sh7720.c:16:32: sparse: sparse: incorrect type 
>> in argument 1 (different base types) @@ expected void const volatile 
>> [noderef] __iomem *ptr @@ got unsigned long @@
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:16:32: sparse: expected void 
const volatile [noderef] __iomem *ptr
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:16:32: sparse: got unsigned long
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:17:25: sparse: sparse: incorrect type 
in argument 1 (different base types) @@ expected void const volatile 
[noderef] __iomem *ptr @@ got unsigned long @@
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:17:25: sparse: expected void 
const volatile [noderef] __iomem *ptr
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:17:25: sparse: got unsigned long
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:20:32: sparse: sparse: incorrect type 
in argument 1 (different base types) @@ expected void const volatile 
[noderef] __iomem *ptr @@ got unsigned long @@
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:20:32: sparse: expected void 
const volatile [noderef] __iomem *ptr
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:20:32: sparse: got unsigned long
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:21:25: sparse: sparse: incorrect type 
in argument 1 (different base types) @@ expected void const volatile 
[noderef] __iomem *ptr @@ got unsigned long @@
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:21:25: sparse: expected void 
const volatile [noderef] __iomem *ptr
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:21:25: sparse: got unsigned long
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:26:32: sparse: sparse: incorrect type 
in argument 1 (different base types) @@ expected void const volatile 
[noderef] __iomem *ptr @@ got unsigned long @@
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:26:32: sparse: expected void 
const volatile [noderef] __iomem *ptr
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:26:32: sparse: got unsigned long
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:27:25: sparse: sparse: incorrect type 
in argument 1 (different base types) @@ expected void const volatile 
[noderef] __iomem *ptr @@ got unsigned long @@
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:27:25: sparse: expected void 
const volatile [noderef] __iomem *ptr
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:27:25: sparse: got unsigned long
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:30:32: sparse: sparse: incorrect type 
in argument 1 (different base types) @@ expected void const volatile 
[noderef] __iomem *ptr @@ got unsigned long @@
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:30:32: sparse: expected void 
const volatile [noderef] __iomem *ptr
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:30:32: sparse: got unsigned long
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:31:25: sparse: sparse: incorrect type 
in argument 1 (different base types) @@ expected void const volatile 
[noderef] __iomem *ptr @@ got unsigned long @@
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:31:25: sparse: expected void 
const volatile [noderef] __iomem *ptr
   arch/sh/kernel/cpu/sh3/serial-sh7720.c:31:25: sparse: got unsigned long
--
>> arch/sh/boards/board-magicpanelr2.c:39:13: sparse: sparse: incorrect type in 
>> argument 1 (different base 

[PATCH v3 net-next 6/7] ptp: ptp_clockmatrix: Simplify code - remove unnecessary `err` variable.

2021-02-16 Thread vincent.cheng.xh
From: Vincent Cheng 

Code clean-up.

Signed-off-by: Vincent Cheng 
---
 drivers/ptp/ptp_clockmatrix.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/ptp/ptp_clockmatrix.c b/drivers/ptp/ptp_clockmatrix.c
index 241bff0..dc42c36 100644
--- a/drivers/ptp/ptp_clockmatrix.c
+++ b/drivers/ptp/ptp_clockmatrix.c
@@ -282,12 +282,9 @@ static int idtcm_write(struct idtcm *idtcm,
 
 static int clear_boot_status(struct idtcm *idtcm)
 {
-   int err;
u8 buf[4] = {0};
 
-   err = idtcm_write(idtcm, GENERAL_STATUS, BOOT_STATUS, buf, sizeof(buf));
-
-   return err;
+   return idtcm_write(idtcm, GENERAL_STATUS, BOOT_STATUS, buf, 
sizeof(buf));
 }
 
 static int read_boot_status(struct idtcm *idtcm, u32 *status)
-- 
2.7.4



[PATCH v3 net-next 0/7] ptp: ptp_clockmatrix: Fix output 1 PPS alignment.

2021-02-16 Thread vincent.cheng.xh
From: Vincent Cheng 

This series fixes a race condition that may result in the output clock
not aligned to internal 1 PPS clock.

Part of device initialization is to align the rising edge of output
clocks to the internal rising edge of the 1 PPS clock.  If the system
APLL and DPLL are not locked when this alignment occurs, the alignment
fails and a fixed offset between the internal 1 PPS clock and the
output clock occurs.

If a clock is dynamically enabled after power-up, the output clock
also needs to be aligned to the internal 1 PPS clock.

v3:
Suggested by: Jakub Kicinski 
- Remove unnecessary 'err' variable
- Increase msleep()/loop accuracy by using jiffies in while()
- No empty lines between variables
- No empty lines between call and the if
- parenthesis around a == b are unnecessary
- Inconsistent \n usage in dev_()
- Remove unnecessary empty line
- Leave string format in place so static code checkers can
  validate arguments

v2:
Suggested by: Richard Cochran 
- Added const to "char * fmt"
- Break unrelated header change into separate patch

Vincent Cheng (7):
  ptp: ptp_clockmatrix: Add wait_for_sys_apll_dpll_lock.
  ptp: ptp_clockmatrix: Add alignment of 1 PPS to idtcm_perout_enable.
  ptp: ptp_clockmatrix: Remove unused header declarations.
  ptp: ptp_clockmatrix: Clean-up dev_*() messages.
  ptp: ptp_clockmatrix: Coding style - tighten vertical spacing.
  ptp: ptp_clockmatrix: Simplify code - remove unnecessary `err`
variable.
  ptp: ptp_clockmatrix: clean-up - parenthesis around a == b are
unnecessary

 drivers/ptp/idt8a340_reg.h|  10 ++
 drivers/ptp/ptp_clockmatrix.c | 313 ++
 drivers/ptp/ptp_clockmatrix.h |  17 ++-
 3 files changed, 162 insertions(+), 178 deletions(-)

-- 
2.7.4



[PATCH v3 net-next 2/7] ptp: ptp_clockmatrix: Add alignment of 1 PPS to idtcm_perout_enable.

2021-02-16 Thread vincent.cheng.xh
From: Vincent Cheng 

When enabling output using PTP_CLK_REQ_PEROUT, need to align the output
clock to the internal 1 PPS clock.

Signed-off-by: Vincent Cheng 
Acked-by: Richard Cochran 
---
 drivers/ptp/ptp_clockmatrix.c | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/ptp/ptp_clockmatrix.c b/drivers/ptp/ptp_clockmatrix.c
index 9bfd32b..f597e4f 100644
--- a/drivers/ptp/ptp_clockmatrix.c
+++ b/drivers/ptp/ptp_clockmatrix.c
@@ -1389,13 +1389,23 @@ static int idtcm_perout_enable(struct idtcm_channel 
*channel,
   bool enable,
   struct ptp_perout_request *perout)
 {
+   struct idtcm *idtcm = channel->idtcm;
unsigned int flags = perout->flags;
+   struct timespec64 ts = {0, 0};
+   int err;
 
if (flags == PEROUT_ENABLE_OUTPUT_MASK)
-   return idtcm_output_mask_enable(channel, enable);
+   err = idtcm_output_mask_enable(channel, enable);
+   else
+   err = idtcm_output_enable(channel, enable, perout->index);
+
+   if (err) {
+   dev_err(>client->dev, "Unable to set output enable");
+   return err;
+   }
 
-   /* Enable/disable individual output instead */
-   return idtcm_output_enable(channel, enable, perout->index);
+   /* Align output to internal 1 PPS */
+   return _idtcm_settime(channel, , SCSR_TOD_WR_TYPE_SEL_DELTA_PLUS);
 }
 
 static int idtcm_get_pll_mode(struct idtcm_channel *channel,
-- 
2.7.4



[PATCH v3 net-next 4/7] ptp: ptp_clockmatrix: Clean-up dev_*() messages.

2021-02-16 Thread vincent.cheng.xh
From: Vincent Cheng 

Code clean-up.

* Remove unnecessary \n termination from dev_*() messages.
* Remove 'char *fmt' to define strings to stay within 80 column
  limit.  Not needed since coding guidelines increased to
  100 columns limit.
  Keeping format in place allows static code checkers to
  validate the arguments.
* Tighten up vertical spacing.

Signed-off-by: Vincent Cheng 
---
 drivers/ptp/ptp_clockmatrix.c | 122 +++---
 1 file changed, 43 insertions(+), 79 deletions(-)

diff --git a/drivers/ptp/ptp_clockmatrix.c b/drivers/ptp/ptp_clockmatrix.c
index f597e4f..eec0a74 100644
--- a/drivers/ptp/ptp_clockmatrix.c
+++ b/drivers/ptp/ptp_clockmatrix.c
@@ -160,7 +160,6 @@ static int idtcm_xfer_read(struct idtcm *idtcm,
struct i2c_client *client = idtcm->client;
struct i2c_msg msg[2];
int cnt;
-   char *fmt = "i2c_transfer failed at %d in %s, at addr: %04X!\n";
 
msg[0].addr = client->addr;
msg[0].flags = 0;
@@ -176,14 +175,12 @@ static int idtcm_xfer_read(struct idtcm *idtcm,
 
if (cnt < 0) {
dev_err(>dev,
-   fmt,
-   __LINE__,
-   __func__,
-   regaddr);
+   "i2c_transfer failed at %d in %s, at addr: %04x!",
+   __LINE__, __func__, regaddr);
return cnt;
} else if (cnt != 2) {
dev_err(>dev,
-   "i2c_transfer sent only %d of %d messages\n", cnt, 2);
+   "i2c_transfer sent only %d of %d messages", cnt, 2);
return -EIO;
}
 
@@ -199,7 +196,6 @@ static int idtcm_xfer_write(struct idtcm *idtcm,
/* we add 1 byte for device register */
u8 msg[IDTCM_MAX_WRITE_COUNT + 1];
int cnt;
-   char *fmt = "i2c_master_send failed at %d in %s, at addr: %04X!\n";
 
if (count > IDTCM_MAX_WRITE_COUNT)
return -EINVAL;
@@ -211,10 +207,8 @@ static int idtcm_xfer_write(struct idtcm *idtcm,
 
if (cnt < 0) {
dev_err(>dev,
-   fmt,
-   __LINE__,
-   __func__,
-   regaddr);
+   "i2c_master_send failed at %d in %s, at addr: %04x!",
+   __LINE__, __func__, regaddr);
return cnt;
}
 
@@ -238,7 +232,7 @@ static int idtcm_page_offset(struct idtcm *idtcm, u8 val)
 
if (err) {
idtcm->page_offset = 0xff;
-   dev_err(>client->dev, "failed to set page offset\n");
+   dev_err(>client->dev, "failed to set page offset");
} else {
idtcm->page_offset = val;
}
@@ -330,7 +324,7 @@ static int wait_for_boot_status_ready(struct idtcm *idtcm)
 
} while (i);
 
-   dev_warn(>client->dev, "%s timed out\n", __func__);
+   dev_warn(>client->dev, "%s timed out", __func__);
 
return -EBUSY;
 }
@@ -811,7 +805,7 @@ static int _idtcm_set_dpll_scsr_tod(struct idtcm_channel 
*channel,
 
if (++count > 20) {
dev_err(>client->dev,
-   "Timed out waiting for the write counter\n");
+   "Timed out waiting for the write counter");
return -EIO;
}
}
@@ -877,7 +871,7 @@ static int _idtcm_settime_deprecated(struct idtcm_channel 
*channel,
 
if (err) {
dev_err(>client->dev,
-   "%s: Set HW ToD failed\n", __func__);
+   "%s: Set HW ToD failed", __func__);
return err;
}
 
@@ -1079,14 +1073,14 @@ static int idtcm_state_machine_reset(struct idtcm 
*idtcm)
 
if (status == 0xA0) {
dev_dbg(>client->dev,
-   "SM_RESET completed in %d ms\n",
-   i * 100);
+   "SM_RESET completed in %d ms", i * 100);
break;
}
}
 
if (!status)
-   dev_err(>client->dev, "Timed out waiting for 
CM_RESET to complete\n");
+   dev_err(>client->dev,
+   "Timed out waiting for CM_RESET to complete");
}
 
return err;
@@ -1182,12 +1176,12 @@ static int set_pll_output_mask(struct idtcm *idtcm, u16 
addr, u8 val)
 static int set_tod_ptp_pll(struct idtcm *idtcm, u8 index, u8 pll)
 {
if (index >= MAX_TOD) {
-   dev_err(>client->dev, "ToD%d not supported\n", index);
+   dev_err(>client->dev, "ToD%d not supported", index);
return -EINVAL;
}
 
if (pll >= MAX_PLL) {
-   dev_err(>client->dev, "Pll%d not supported\n", pll);
+   

Re: [PATCH v2 1/2] exfat: add initial ioctl function

2021-02-16 Thread Hyeongseok Kim

On 2/17/21 2:39 PM, Namjae Jeon wrote:

Hi Hyeongseok,

Do you have any other opinion about this?

I also think this patch should be combined with the 2/2 patch.

If you agree, I'll merge these as one.

Yep, Agreed. Please do that:)
Thanks!

Thank you for the opinion.
I sent out v3.




[PATCH v3 net-next 5/7] ptp: ptp_clockmatrix: Coding style - tighten vertical spacing.

2021-02-16 Thread vincent.cheng.xh
From: Vincent Cheng 

Code clean-up.

* Remove blank line between variable declarations.
* Remove blank line between:
err = blah(...)

if (err)
...
* Remove unnecessary blank line before/after loop constructs.

Signed-off-by: Vincent Cheng 
---
 drivers/ptp/ptp_clockmatrix.c | 90 ++-
 1 file changed, 11 insertions(+), 79 deletions(-)

diff --git a/drivers/ptp/ptp_clockmatrix.c b/drivers/ptp/ptp_clockmatrix.c
index eec0a74..241bff0 100644
--- a/drivers/ptp/ptp_clockmatrix.c
+++ b/drivers/ptp/ptp_clockmatrix.c
@@ -229,7 +229,6 @@ static int idtcm_page_offset(struct idtcm *idtcm, u8 val)
buf[3] = 0x20;
 
err = idtcm_xfer_write(idtcm, PAGE_ADDR, buf, sizeof(buf));
-
if (err) {
idtcm->page_offset = 0xff;
dev_err(>client->dev, "failed to set page offset");
@@ -254,7 +253,6 @@ static int _idtcm_rdwr(struct idtcm *idtcm,
lo = regaddr & 0xff;
 
err = idtcm_page_offset(idtcm, hi);
-
if (err)
return err;
 
@@ -312,7 +310,6 @@ static int wait_for_boot_status_ready(struct idtcm *idtcm)
 
do {
err = read_boot_status(idtcm, );
-
if (err)
return err;
 
@@ -415,14 +412,12 @@ static int _idtcm_gettime(struct idtcm_channel *channel,
 
/* wait trigger to be 0 */
while (trigger & TOD_READ_TRIGGER_MASK) {
-
if (idtcm->calculate_overhead_flag)
idtcm->start_time = ktime_get_raw();
 
err = idtcm_read(idtcm, channel->tod_read_primary,
 TOD_READ_PRIMARY_CMD, ,
 sizeof(trigger));
-
if (err)
return err;
 
@@ -432,7 +427,6 @@ static int _idtcm_gettime(struct idtcm_channel *channel,
 
err = idtcm_read(idtcm, channel->tod_read_primary,
 TOD_READ_PRIMARY, buf, sizeof(buf));
-
if (err)
return err;
 
@@ -595,7 +589,6 @@ static int sync_source_dpll_tod_pps(u16 tod_addr, u8 
*sync_src)
 static int idtcm_sync_pps_output(struct idtcm_channel *channel)
 {
struct idtcm *idtcm = channel->idtcm;
-
u8 pll;
u8 sync_src;
u8 qn;
@@ -604,7 +597,6 @@ static int idtcm_sync_pps_output(struct idtcm_channel 
*channel)
u8 out8_mux = 0;
u8 out11_mux = 0;
u8 temp;
-
u16 output_mask = channel->output_mask;
 
err = sync_source_dpll_tod_pps(channel->tod_n, _src);
@@ -681,7 +673,6 @@ static int _idtcm_set_dpll_hw_tod(struct idtcm_channel 
*channel,
   enum hw_tod_write_trig_sel wr_trig)
 {
struct idtcm *idtcm = channel->idtcm;
-
u8 buf[TOD_BYTE_COUNT];
u8 cmd;
int err;
@@ -691,7 +682,6 @@ static int _idtcm_set_dpll_hw_tod(struct idtcm_channel 
*channel,
/* Configure HW TOD write trigger. */
err = idtcm_read(idtcm, channel->hw_dpll_n, HW_DPLL_TOD_CTRL_1,
 , sizeof(cmd));
-
if (err)
return err;
 
@@ -700,20 +690,16 @@ static int _idtcm_set_dpll_hw_tod(struct idtcm_channel 
*channel,
 
err = idtcm_write(idtcm, channel->hw_dpll_n, HW_DPLL_TOD_CTRL_1,
  , sizeof(cmd));
-
if (err)
return err;
 
if (wr_trig  != HW_TOD_WR_TRIG_SEL_MSB) {
-
err = timespec_to_char_array(_ts, buf, sizeof(buf));
-
if (err)
return err;
 
err = idtcm_write(idtcm, channel->hw_dpll_n,
  HW_DPLL_TOD_OVR__0, buf, sizeof(buf));
-
if (err)
return err;
}
@@ -725,7 +711,6 @@ static int _idtcm_set_dpll_hw_tod(struct idtcm_channel 
*channel,
  , sizeof(cmd));
 
if (wr_trig == HW_TOD_WR_TRIG_SEL_MSB) {
-
if (idtcm->calculate_overhead_flag) {
/* Assumption: I2C @ 400KHz */
ktime_t diff = ktime_sub(ktime_get_raw(),
@@ -740,7 +725,6 @@ static int _idtcm_set_dpll_hw_tod(struct idtcm_channel 
*channel,
}
 
err = timespec_to_char_array(_ts, buf, sizeof(buf));
-
if (err)
return err;
 
@@ -764,7 +748,6 @@ static int _idtcm_set_dpll_scsr_tod(struct idtcm_channel 
*channel,
timespec64_add_ns(_ts, SETTIME_CORRECTION);
 
err = timespec_to_char_array(_ts, buf, sizeof(buf));
-
if (err)
return err;
 
@@ -868,7 +851,6 @@ static int _idtcm_settime_deprecated(struct idtcm_channel 
*channel,
int err;
 
err = _idtcm_set_dpll_hw_tod(channel, ts, HW_TOD_WR_TRIG_SEL_MSB);
-
if (err) {
dev_err(>client->dev,
"%s: Set HW ToD failed", __func__);
@@ -893,7 +875,6 @@ static int 

[PATCH v3 0/1] Add FITRIM ioctl support for exFAT filesystem

2021-02-16 Thread Hyeongseok Kim
This is for adding FITRIM ioctl functionality to exFAT filesystem.
To do that, add generic ioctl function and FITRIM handler.

Changelog
=
v2->v3:
- Remove unnecessary local variable
- Merge all changes to a single patch

v1->v2:
- Change variable declaration order as reverse tree style.
- Return -EOPNOTSUPP from sb_issue_discard() just as it is.
- Remove cond_resched() in while loop.
- Move ioctl related code into it's helper function.

Hyeongseok Kim (1):
  exfat: add support ioctl and FITRIM function

 fs/exfat/balloc.c   | 81 +
 fs/exfat/dir.c  |  5 +++
 fs/exfat/exfat_fs.h |  4 +++
 fs/exfat/file.c | 53 +
 4 files changed, 143 insertions(+)

-- 
2.27.0.83.g0313f36



[PATCH v3 1/1] exfat: add support ioctl and FITRIM function

2021-02-16 Thread Hyeongseok Kim
Add FITRIM ioctl to enable discarding unused blocks while mounted.
As current exFAT doesn't have generic ioctl handler, add empty ioctl
function first, and add FITRIM handler.

Signed-off-by: Hyeongseok Kim 
---
 fs/exfat/balloc.c   | 81 +
 fs/exfat/dir.c  |  5 +++
 fs/exfat/exfat_fs.h |  4 +++
 fs/exfat/file.c | 53 +
 4 files changed, 143 insertions(+)

diff --git a/fs/exfat/balloc.c b/fs/exfat/balloc.c
index 761c79c3a4ba..d47beef66892 100644
--- a/fs/exfat/balloc.c
+++ b/fs/exfat/balloc.c
@@ -273,3 +273,84 @@ int exfat_count_used_clusters(struct super_block *sb, 
unsigned int *ret_count)
*ret_count = count;
return 0;
 }
+
+int exfat_trim_fs(struct inode *inode, struct fstrim_range *range)
+{
+   unsigned int trim_begin, trim_end, count, next_free_clu;
+   u64 clu_start, clu_end, trim_minlen, trimmed_total = 0;
+   struct super_block *sb = inode->i_sb;
+   struct exfat_sb_info *sbi = EXFAT_SB(sb);
+   int err = 0;
+
+   clu_start = max_t(u64, range->start >> sbi->cluster_size_bits,
+   EXFAT_FIRST_CLUSTER);
+   clu_end = clu_start + (range->len >> sbi->cluster_size_bits) - 1;
+   trim_minlen = range->minlen >> sbi->cluster_size_bits;
+
+   if (clu_start >= sbi->num_clusters || range->len < sbi->cluster_size)
+   return -EINVAL;
+
+   if (clu_end >= sbi->num_clusters)
+   clu_end = sbi->num_clusters - 1;
+
+   mutex_lock(_SB(inode->i_sb)->s_lock);
+
+   trim_begin = trim_end = exfat_find_free_bitmap(sb, clu_start);
+   if (trim_begin == EXFAT_EOF_CLUSTER)
+   goto unlock;
+
+   next_free_clu = exfat_find_free_bitmap(sb, trim_end + 1);
+   if (next_free_clu == EXFAT_EOF_CLUSTER)
+   goto unlock;
+
+   do {
+   if (next_free_clu == trim_end + 1)
+   /* extend trim range for continuous free cluster */
+   trim_end++;
+   else {
+   /* trim current range if it's larger than trim_minlen */
+   count = trim_end - trim_begin + 1;
+   if (count >= trim_minlen) {
+   err = sb_issue_discard(sb,
+   exfat_cluster_to_sector(sbi, 
trim_begin),
+   count * sbi->sect_per_clus, GFP_NOFS, 
0);
+   if (err)
+   goto unlock;
+
+   trimmed_total += count;
+   }
+
+   /* set next start point of the free hole */
+   trim_begin = trim_end = next_free_clu;
+   }
+
+   if (next_free_clu >= clu_end)
+   break;
+
+   if (fatal_signal_pending(current)) {
+   err = -ERESTARTSYS;
+   goto unlock;
+   }
+
+   next_free_clu = exfat_find_free_bitmap(sb, next_free_clu + 1);
+
+   } while (next_free_clu != EXFAT_EOF_CLUSTER &&
+   next_free_clu > trim_end);
+
+   /* try to trim remainder */
+   count = trim_end - trim_begin + 1;
+   if (count >= trim_minlen) {
+   err = sb_issue_discard(sb, exfat_cluster_to_sector(sbi, 
trim_begin),
+   count * sbi->sect_per_clus, GFP_NOFS, 0);
+   if (err)
+   goto unlock;
+
+   trimmed_total += count;
+   }
+
+unlock:
+   mutex_unlock(_SB(inode->i_sb)->s_lock);
+   range->len = trimmed_total << sbi->cluster_size_bits;
+
+   return err;
+}
diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
index 916797077aad..e1d5536de948 100644
--- a/fs/exfat/dir.c
+++ b/fs/exfat/dir.c
@@ -4,6 +4,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 
@@ -306,6 +307,10 @@ const struct file_operations exfat_dir_operations = {
.llseek = generic_file_llseek,
.read   = generic_read_dir,
.iterate= exfat_iterate,
+   .unlocked_ioctl = exfat_ioctl,
+#ifdef CONFIG_COMPAT
+   .compat_ioctl = exfat_compat_ioctl,
+#endif
.fsync  = exfat_file_fsync,
 };
 
diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h
index 764bc645241e..e050aea0b639 100644
--- a/fs/exfat/exfat_fs.h
+++ b/fs/exfat/exfat_fs.h
@@ -411,6 +411,7 @@ int exfat_set_bitmap(struct inode *inode, unsigned int clu);
 void exfat_clear_bitmap(struct inode *inode, unsigned int clu, bool sync);
 unsigned int exfat_find_free_bitmap(struct super_block *sb, unsigned int clu);
 int exfat_count_used_clusters(struct super_block *sb, unsigned int *ret_count);
+int exfat_trim_fs(struct inode *inode, struct fstrim_range *range);
 
 /* file.c */
 extern const struct file_operations exfat_file_operations;
@@ -420,6 +421,9 @@ int exfat_setattr(struct dentry *dentry, struct 

[PATCH v3 net-next 1/7] ptp: ptp_clockmatrix: Add wait_for_sys_apll_dpll_lock.

2021-02-16 Thread vincent.cheng.xh
From: Vincent Cheng 

Part of the device initialization aligns the rising edge of the output
clock to the internal 1 PPS clock. If the system APLL and DPLL is not
locked, then the alignment will fail and there will be a fixed offset
between the internal 1 PPS clock and the output clock.

After loading the device firmware, poll the system APLL and DPLL for
locked state prior to initialization, timing out after 2 seconds.

Signed-off-by: Vincent Cheng 
Acked-by: Richard Cochran 
---
 drivers/ptp/idt8a340_reg.h| 10 +++
 drivers/ptp/ptp_clockmatrix.c | 64 +--
 drivers/ptp/ptp_clockmatrix.h | 15 ++
 3 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/drivers/ptp/idt8a340_reg.h b/drivers/ptp/idt8a340_reg.h
index a664dfe..ac524cf 100644
--- a/drivers/ptp/idt8a340_reg.h
+++ b/drivers/ptp/idt8a340_reg.h
@@ -122,6 +122,8 @@
 #define OTP_SCSR_CONFIG_SELECT0x0022
 
 #define STATUS0xc03c
+#define DPLL_SYS_STATUS   0x0020
+#define DPLL_SYS_APLL_STATUS  0x0021
 #define USER_GPIO0_TO_7_STATUS0x008a
 #define USER_GPIO8_TO_15_STATUS   0x008b
 
@@ -707,4 +709,12 @@
 /* Bit definitions for the DPLL_CTRL_COMBO_MASTER_CFG register */
 #define COMBO_MASTER_HOLD BIT(0)
 
+/* Bit definitions for DPLL_SYS_STATUS register */
+#define DPLL_SYS_STATE_MASK   (0xf)
+
+/* Bit definitions for SYS_APLL_STATUS register */
+#define SYS_APLL_LOSS_LOCK_LIVE_MASK   BIT(0)
+#define SYS_APLL_LOSS_LOCK_LIVE_LOCKED 0
+#define SYS_APLL_LOSS_LOCK_LIVE_UNLOCKED   1
+
 #endif
diff --git a/drivers/ptp/ptp_clockmatrix.c b/drivers/ptp/ptp_clockmatrix.c
index 051511f..9bfd32b 100644
--- a/drivers/ptp/ptp_clockmatrix.c
+++ b/drivers/ptp/ptp_clockmatrix.c
@@ -335,6 +335,67 @@ static int wait_for_boot_status_ready(struct idtcm *idtcm)
return -EBUSY;
 }
 
+static int read_sys_apll_status(struct idtcm *idtcm, u8 *status)
+{
+   return idtcm_read(idtcm, STATUS, DPLL_SYS_APLL_STATUS, status,
+ sizeof(u8));
+}
+
+static int read_sys_dpll_status(struct idtcm *idtcm, u8 *status)
+{
+   return idtcm_read(idtcm, STATUS, DPLL_SYS_STATUS, status, sizeof(u8));
+}
+
+static int wait_for_sys_apll_dpll_lock(struct idtcm *idtcm)
+{
+   unsigned long timeout = jiffies + msecs_to_jiffies(LOCK_TIMEOUT_MS);
+   u8 apll = 0;
+   u8 dpll = 0;
+   int err;
+
+   do {
+   err = read_sys_apll_status(idtcm, );
+   if (err)
+   return err;
+
+   err = read_sys_dpll_status(idtcm, );
+   if (err)
+   return err;
+
+   apll &= SYS_APLL_LOSS_LOCK_LIVE_MASK;
+   dpll &= DPLL_SYS_STATE_MASK;
+
+   if (apll == SYS_APLL_LOSS_LOCK_LIVE_LOCKED &&
+   dpll == DPLL_STATE_LOCKED) {
+   return 0;
+   } else if (dpll == DPLL_STATE_FREERUN ||
+  dpll == DPLL_STATE_HOLDOVER ||
+  dpll == DPLL_STATE_OPEN_LOOP) {
+   dev_warn(>client->dev,
+   "No wait state: DPLL_SYS_STATE %d", dpll);
+   return -EPERM;
+   }
+
+   msleep(LOCK_POLL_INTERVAL_MS);
+   } while (time_is_after_jiffies(timeout));
+
+   dev_warn(>client->dev,
+"%d ms lock timeout: SYS APLL Loss Lock %d  SYS DPLL state %d",
+LOCK_TIMEOUT_MS, apll, dpll);
+
+   return -ETIME;
+}
+
+static void wait_for_chip_ready(struct idtcm *idtcm)
+{
+   if (wait_for_boot_status_ready(idtcm))
+   dev_warn(>client->dev, "BOOT_STATUS != 0xA0");
+
+   if (wait_for_sys_apll_dpll_lock(idtcm))
+   dev_warn(>client->dev,
+"Continuing while SYS APLL/DPLL is not locked");
+}
+
 static int _idtcm_gettime(struct idtcm_channel *channel,
  struct timespec64 *ts)
 {
@@ -2235,8 +2296,7 @@ static int idtcm_probe(struct i2c_client *client,
dev_warn(>client->dev,
 "loading firmware failed with %d\n", err);
 
-   if (wait_for_boot_status_ready(idtcm))
-   dev_warn(>client->dev, "BOOT_STATUS != 0xA0\n");
+   wait_for_chip_ready(idtcm);
 
if (idtcm->tod_mask) {
for (i = 0; i < MAX_TOD; i++) {
diff --git a/drivers/ptp/ptp_clockmatrix.h b/drivers/ptp/ptp_clockmatrix.h
index 645de2c..0233236 100644
--- a/drivers/ptp/ptp_clockmatrix.h
+++ b/drivers/ptp/ptp_clockmatrix.h
@@ -51,6 +51,9 @@
 #define TOD_WRITE_OVERHEAD_COUNT_MAX   (2)
 #define TOD_BYTE_COUNT (11)
 
+#define LOCK_TIMEOUT_MS(2000)
+#define LOCK_POLL_INTERVAL_MS  (10)
+
 #define PEROUT_ENABLE_OUTPUT_MASK  (0xdeadbeef)
 
 #define IDTCM_MAX_WRITE_COUNT  (512)
@@ -105,6 +108,18 @@ enum 

[PATCH v3 net-next 3/7] ptp: ptp_clockmatrix: Remove unused header declarations.

2021-02-16 Thread vincent.cheng.xh
From: Vincent Cheng 

Removed unused header declarations.

Signed-off-by: Vincent Cheng 
---
 drivers/ptp/ptp_clockmatrix.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/ptp/ptp_clockmatrix.h b/drivers/ptp/ptp_clockmatrix.h
index 0233236..fb32327 100644
--- a/drivers/ptp/ptp_clockmatrix.h
+++ b/drivers/ptp/ptp_clockmatrix.h
@@ -15,7 +15,6 @@
 #define FW_FILENAME"idtcm.bin"
 #define MAX_TOD(4)
 #define MAX_PLL(8)
-#define MAX_OUTPUT (12)
 
 #define MAX_ABS_WRITE_PHASE_PICOSECONDS (107374182350LL)
 
@@ -138,7 +137,6 @@ struct idtcm_channel {
enum pll_mode   pll_mode;
u8  pll;
u16 output_mask;
-   u8  output_phase_adj[MAX_OUTPUT][4];
 };
 
 struct idtcm {
-- 
2.7.4



[PATCH v3 net-next 7/7] ptp: ptp_clockmatrix: clean-up - parenthesis around a == b are unnecessary

2021-02-16 Thread vincent.cheng.xh
From: Vincent Cheng 

Code clean-up.

Signed-off-by: Vincent Cheng 
---
 drivers/ptp/ptp_clockmatrix.c | 18 --
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/ptp/ptp_clockmatrix.c b/drivers/ptp/ptp_clockmatrix.c
index dc42c36..75463c2 100644
--- a/drivers/ptp/ptp_clockmatrix.c
+++ b/drivers/ptp/ptp_clockmatrix.c
@@ -444,7 +444,7 @@ static int _sync_pll_output(struct idtcm *idtcm,
u16 sync_ctrl1;
u8 temp;
 
-   if ((qn == 0) && (qn_plus_1 == 0))
+   if (qn == 0 && qn_plus_1 == 0)
return 0;
 
switch (pll) {
@@ -509,7 +509,7 @@ static int _sync_pll_output(struct idtcm *idtcm,
return err;
 
/* PLL5 can have OUT8 as second additional output. */
-   if ((pll == 5) && (qn_plus_1 != 0)) {
+   if (pll == 5 && qn_plus_1 != 0) {
err = idtcm_read(idtcm, 0, HW_Q8_CTRL_SPARE,
 , sizeof(temp));
if (err)
@@ -531,7 +531,7 @@ static int _sync_pll_output(struct idtcm *idtcm,
}
 
/* PLL6 can have OUT11 as second additional output. */
-   if ((pll == 6) && (qn_plus_1 != 0)) {
+   if (pll == 6 && qn_plus_1 != 0) {
err = idtcm_read(idtcm, 0, HW_Q11_CTRL_SPARE,
 , sizeof(temp));
if (err)
@@ -654,7 +654,7 @@ static int idtcm_sync_pps_output(struct idtcm_channel 
*channel)
}
}
 
-   if ((qn != 0) || (qn_plus_1 != 0))
+   if (qn != 0 || qn_plus_1 != 0)
err = _sync_pll_output(idtcm, pll, sync_src, qn,
   qn_plus_1);
 
@@ -1263,13 +1263,11 @@ static int idtcm_load_firmware(struct idtcm *idtcm,
err = 0;
 
/* Top (status registers) and bottom are read-only */
-   if ((regaddr < GPIO_USER_CONTROL)
-   || (regaddr >= SCRATCH))
+   if (regaddr < GPIO_USER_CONTROL || regaddr >= SCRATCH)
continue;
 
/* Page size 128, last 4 bytes of page skipped */
-   if (((loaddr > 0x7b) && (loaddr <= 0x7f))
-|| loaddr > 0xfb)
+   if ((loaddr > 0x7b && loaddr <= 0x7f) || loaddr > 0xfb)
continue;
 
err = idtcm_write(idtcm, regaddr, 0, , sizeof(val));
@@ -1688,7 +1686,7 @@ static int _enable_pll_tod_sync(struct idtcm *idtcm,
u16 dpll;
u16 out0 = 0, out1 = 0;
 
-   if ((qn == 0) && (qn_plus_1 == 0))
+   if (qn == 0 && qn_plus_1 == 0)
return 0;
 
switch (pll) {
@@ -1883,7 +1881,7 @@ static int idtcm_enable_tod_sync(struct idtcm_channel 
*channel)
}
}
 
-   if ((qn != 0) || (qn_plus_1 != 0))
+   if (qn != 0 || qn_plus_1 != 0)
err = _enable_pll_tod_sync(idtcm, pll, sync_src, qn,
   qn_plus_1);
if (err)
-- 
2.7.4



Re: [PATCH 2/2] mmc: core: Add no single read retries

2021-02-16 Thread Adrian Hunter
On 17/02/21 7:46 am, Adrian Hunter wrote:
> On 17/02/21 7:22 am, DooHyun Hwang wrote:
>> This makes to handle read errors faster by not retrying
>> multiple block read(CMD18) errors with single block reads(CMD17).
>>
>> On some bad SD Cards that have problem with read operations,
>> it is not helpful to retry multiple block read errors with
>> several single block reads, and it is delayed to treat read
>> operations as I/O error as much as retrying single block reads.
> 
> If the issue is that it takes too long, then maybe it would be better to get
> mmc_blk_read_single() to give up after a certain amount of time.
> 

So that a device property would not be needed I mean.  Then everyone would
benefit.


Re: [PATCH] cpufreq: exclude boost frequencies from valid count if not enabled

2021-02-16 Thread Viresh Kumar
Hi Thara,

On 16-02-21, 19:00, Thara Gopinath wrote:
> This is a fix for a regression observed on db845 platforms with 5.7-rc11
> kernel.  On these platforms running stress tests with 5.11-rc7 kernel
> causes big cpus to overheat and ultimately shutdown the system due to
> hitting critical temperature (thermal throttling does not happen and
> cur_state of cpufreq cooling device for big cpus remain stuck at 0 or max
> frequency).
> 
> This platform has boost opp defined for big cpus but boost mode itself is
> disabled in the cpufreq driver. Hence the initial max frequency request
> from cpufreq cooling device(cur_state) for big cpus is for boost
> frequency(2803200) where as initial max frequency request from cpufreq
> driver itself is for the highest non boost frequency (2649600).

Okay.

> qos
> framework collates these two requests and puts the max frequency of big
> cpus to 2649600 which the thermal framework is unaware of.

It doesn't need to be aware of that. It sets its max frequency and other
frameworks can put their own requests and the lowest one wins. In this case the
other constraint came from cpufreq-core, which is fine.

> Now during an
> over heat event, with step-wise policy governor, thermal framework tries to
> throttle the cpu and places a restriction on max frequency of the cpu to
> cur_state - 1

Actually it is cur_state + 1 as the values are inversed here, cooling state 0
refers to highest frequency :)

> which in this case 2649600. qos framework in turn tells the
> cpufreq cooling device that max frequency of the cpu is already at 2649600
> and the cooling device driver returns doing nothing(cur_state of the
> cooling device remains unchanged).

And that's where the bug lies, I have sent proper fix for that now.

> Thus thermal remains stuck in a loop and
> never manages to actually throttle the cpu frequency. This ultimately leads
> to system shutdown in case of a thermal overheat event on big cpus.
 
> There are multiple possible fixes for this issue. Fundamentally,it is wrong
> for cpufreq driver and cpufreq cooling device driver to show different
> maximum possible state/frequency for a cpu.

Not actually, cpufreq core changes the max supported frequency at runtime based
on the availability of boost frequencies.

cpufreq_table_count_valid_entries() is used at different places and it is
implemented correctly.

-- 
viresh


[PATCH] thermal: cpufreq_cooling: freq_qos_update_request() returns < 0 on error

2021-02-16 Thread Viresh Kumar
freq_qos_update_request() returns 1 if the effective constraint value
has changed, 0 if the effective constraint value has not changed, or a
negative error code on failures.

The frequency constraints for CPUs can be set by different parts of the
kernel. If the maximum frequency constraint set by other parts of the
kernel are set at a lower value than the one corresponding to cooling
state 0, then we will never be able to cool down the system as
freq_qos_update_request() will keep on returning 0 and we will skip
updating cpufreq_state and thermal pressure.

Fix that by doing the updates even in the case where
freq_qos_update_request() returns 0, as we have effectively set the
constraint to a new value even if the consolidated value of the
actual constraint is unchanged because of external factors.

Cc: v5.7+  # v5.7+
Reported-by: Thara Gopinath 
Fixes: f12e4f66ab6a ("thermal/cpu-cooling: Update thermal pressure in case of a 
maximum frequency capping")
Signed-off-by: Viresh Kumar 
---
Hi Guys,

This needs to go in 5.12-rc.

Thara, please give this a try and give your tested-by :).

 drivers/thermal/cpufreq_cooling.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/thermal/cpufreq_cooling.c 
b/drivers/thermal/cpufreq_cooling.c
index f5af2571f9b7..10af3341e5ea 100644
--- a/drivers/thermal/cpufreq_cooling.c
+++ b/drivers/thermal/cpufreq_cooling.c
@@ -485,7 +485,7 @@ static int cpufreq_set_cur_state(struct 
thermal_cooling_device *cdev,
frequency = get_state_freq(cpufreq_cdev, state);
 
ret = freq_qos_update_request(_cdev->qos_req, frequency);
-   if (ret > 0) {
+   if (ret >= 0) {
cpufreq_cdev->cpufreq_state = state;
cpus = cpufreq_cdev->policy->cpus;
max_capacity = arch_scale_cpu_capacity(cpumask_first(cpus));
-- 
2.25.0.rc1.19.g042ed3e048af



[PATCH v2] psi: Optimize task switch inside shared cgroups

2021-02-16 Thread Chengming Zhou
The commit 36b238d57172 ("psi: Optimize switching tasks inside shared
cgroups") only update cgroups whose state actually changes during a
task switch only in task preempt case, not in task sleep case.

We actually don't need to clear and set TSK_ONCPU state for common cgroups
of next and prev task in sleep case, that can save many psi_group_change
especially when most activity comes from one leaf cgroup.

sleep before:
psi_dequeue()
  while ((group = iterate_groups(prev)))  # all ancestors
psi_group_change(prev, .clear=TSK_RUNNING|TSK_ONCPU)
psi_task_switch()
  while ((group = iterate_groups(next)))  # all ancestors
psi_group_change(next, .set=TSK_ONCPU)

sleep after:
psi_dequeue()
  nop
psi_task_switch()
  while ((group = iterate_groups(next)))  # until (prev & next)
psi_group_change(next, .set=TSK_ONCPU)
  while ((group = iterate_groups(prev)))  # all ancestors
psi_group_change(prev, .clear = common ? TSK_RUNNING : 
TSK_RUNNING|TSK_ONCPU)

When a voluntary sleep switches to another task, we remove one call of
psi_group_change() for every common cgroup ancestor of the two tasks.

Updates since v1:
- Many improvements in the comments and code from Johannes.

Signed-off-by: Muchun Song 
Signed-off-by: Chengming Zhou 
---
 kernel/sched/psi.c   | 35 +--
 kernel/sched/stats.h | 28 
 2 files changed, 37 insertions(+), 26 deletions(-)

diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c
index 0fe6ff6a6a15..548d405bae3e 100644
--- a/kernel/sched/psi.c
+++ b/kernel/sched/psi.c
@@ -840,20 +840,35 @@ void psi_task_switch(struct task_struct *prev, struct 
task_struct *next,
}
}
 
-   /*
-* If this is a voluntary sleep, dequeue will have taken care
-* of the outgoing TSK_ONCPU alongside TSK_RUNNING already. We
-* only need to deal with it during preemption.
-*/
-   if (sleep)
-   return;
-
if (prev->pid) {
-   psi_flags_change(prev, TSK_ONCPU, 0);
+   int clear = TSK_ONCPU, set = 0;
+
+   /*
+* When we're going to sleep, psi_dequeue() lets us handle
+* TSK_RUNNING and TSK_IOWAIT here, where we can combine it
+* with TSK_ONCPU and save walking common ancestors twice.
+*/
+   if (sleep) {
+   clear |= TSK_RUNNING;
+   if (prev->in_iowait)
+   set |= TSK_IOWAIT;
+   }
+
+   psi_flags_change(prev, clear, set);
 
iter = NULL;
while ((group = iterate_groups(prev, )) && group != common)
-   psi_group_change(group, cpu, TSK_ONCPU, 0, true);
+   psi_group_change(group, cpu, clear, set, true);
+
+   /*
+* TSK_ONCPU is handled up to the common ancestor. If we're 
tasked
+* with dequeuing too, finish that for the rest of the 
hierarchy.
+*/
+   if (sleep) {
+   clear &= ~TSK_ONCPU;
+   for (; group; group = iterate_groups(prev, ))
+   psi_group_change(group, cpu, clear, set, true);
+   }
}
 }
 
diff --git a/kernel/sched/stats.h b/kernel/sched/stats.h
index 9e4e67a94731..dc218e9f4558 100644
--- a/kernel/sched/stats.h
+++ b/kernel/sched/stats.h
@@ -84,28 +84,24 @@ static inline void psi_enqueue(struct task_struct *p, bool 
wakeup)
 
 static inline void psi_dequeue(struct task_struct *p, bool sleep)
 {
-   int clear = TSK_RUNNING, set = 0;
+   int clear = TSK_RUNNING;
 
if (static_branch_likely(_disabled))
return;
 
-   if (!sleep) {
-   if (p->in_memstall)
-   clear |= TSK_MEMSTALL;
-   } else {
-   /*
-* When a task sleeps, schedule() dequeues it before
-* switching to the next one. Merge the clearing of
-* TSK_RUNNING and TSK_ONCPU to save an unnecessary
-* psi_task_change() call in psi_sched_switch().
-*/
-   clear |= TSK_ONCPU;
+   /*
+* A voluntary sleep is a dequeue followed by a task switch. To
+* avoid walking all ancestors twice, psi_task_switch() handles
+* TSK_RUNNING and TSK_IOWAIT for us when it moves TSK_ONCPU.
+* Do nothing here.
+*/
+   if (sleep)
+   return;
 
-   if (p->in_iowait)
-   set |= TSK_IOWAIT;
-   }
+   if (p->in_memstall)
+   clear |= TSK_MEMSTALL;
 
-   psi_task_change(p, clear, set);
+   psi_task_change(p, clear, 0);
 }
 
 static inline void psi_ttwu_dequeue(struct task_struct *p)
-- 
2.11.0



Re: [PATCH 2/2] mmc: core: Add no single read retries

2021-02-16 Thread Adrian Hunter
On 17/02/21 7:22 am, DooHyun Hwang wrote:
> This makes to handle read errors faster by not retrying
> multiple block read(CMD18) errors with single block reads(CMD17).
> 
> On some bad SD Cards that have problem with read operations,
> it is not helpful to retry multiple block read errors with
> several single block reads, and it is delayed to treat read
> operations as I/O error as much as retrying single block reads.

If the issue is that it takes too long, then maybe it would be better to get
mmc_blk_read_single() to give up after a certain amount of time.

> 
> Signed-off-by: DooHyun Hwang 
> ---
>  drivers/mmc/core/block.c | 3 ++-
>  drivers/mmc/core/host.c  | 6 ++
>  include/linux/mmc/host.h | 3 +++
>  3 files changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
> index d666e24fbe0e..e25aaf8fca34 100644
> --- a/drivers/mmc/core/block.c
> +++ b/drivers/mmc/core/block.c
> @@ -1809,7 +1809,8 @@ static void mmc_blk_mq_rw_recovery(struct mmc_queue 
> *mq, struct request *req)
>  
>   /* FIXME: Missing single sector read for large sector size */
>   if (!mmc_large_sector(card) && rq_data_dir(req) == READ &&
> - brq->data.blocks > 1) {
> + brq->data.blocks > 1 &&
> + !card->host->no_single_read_retry) {
>   /* Read one sector at a time */
>   mmc_blk_read_single(mq, req);
>   return;
> diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
> index 9b89a91b6b47..3bf5b2fc111b 100644
> --- a/drivers/mmc/core/host.c
> +++ b/drivers/mmc/core/host.c
> @@ -352,6 +352,12 @@ int mmc_of_parse(struct mmc_host *host)
>   if (device_property_read_bool(dev, "no-mmc"))
>   host->caps2 |= MMC_CAP2_NO_MMC;
>  
> + if (device_property_read_bool(dev, "no-single-read-retry")) {
> + dev_info(host->parent,
> + "Single block read retrying is not supported\n");
> + host->no_single_read_retry = true;
> + }
> +
>   /* Must be after "non-removable" check */
>   if (device_property_read_u32(dev, "fixed-emmc-driver-type", _type) 
> == 0) {
>   if (host->caps & MMC_CAP_NONREMOVABLE)
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index 26a3c7bc29ae..faec55035a63 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -502,6 +502,9 @@ struct mmc_host {
>   /* Host Software Queue support */
>   boolhsq_enabled;
>  
> + /* Do not retry multi block read as single block read */
> + boolno_single_read_retry;
> +
>   unsigned long   private[] cacheline_aligned;
>  };
>  
> 



Re: {standard input}:577: Error: unsupported relocation against base

2021-02-16 Thread Michael Ellerman
Segher Boessenkool  writes:
> Hi!
>
> On Tue, Feb 16, 2021 at 08:36:02PM +1100, Michael Ellerman wrote:
>> Feng Tang  writes:
>> >   {standard input}:577: Error: unsupported relocation against base
>> >   {standard input}:580: Error: unsupported relocation against base
>> >   {standard input}:583: Error: unsupported relocation against base
>
>> > The reason is macro 'mfdcr' requirs an instant number as parameter,
>> > which is not met by show_plbopb_regs().
>> 
>> It doesn't require a constant, it checks if the argument is constant:
>> 
>> #define mfdcr(rn)\
>>  ({unsigned int rval;\
>>  if (__builtin_constant_p(rn) && rn < 1024)  \
>>  asm volatile("mfdcr %0," __stringify(rn)\
>>: "=r" (rval));   \
>>  else if (likely(cpu_has_feature(CPU_FTR_INDEXED_DCR)))  \
>>  rval = mfdcrx(rn);  \
>>  else\
>>  rval = __mfdcr(rn); \
>>  rval;})
>
> It requires a constant number with known (at compile time) value, while
> __builtin_constant_p checks for any constant.  The address of some
> defined symbol is a constant as well normally, for example.
>
> It's better to write that asm as
>   asm volatile("mfdcr %0,%1" : "=r" (rval) : "n"(rn));
> btw (the "n" constraint means "constant integer with known value" (it
> stands for "numeric"), while the "i" constraint means just "constant
> integer").

Actually that fixes it.

diff --git a/arch/powerpc/include/asm/dcr-native.h 
b/arch/powerpc/include/asm/dcr-native.h
index 7141ccea8c94..d143308b0f95 100644
--- a/arch/powerpc/include/asm/dcr-native.h
+++ b/arch/powerpc/include/asm/dcr-native.h
@@ -53,8 +53,8 @@ static inline void mtdcrx(unsigned int reg, unsigned int val)
 #define mfdcr(rn)  \
({unsigned int rval;\
if (__builtin_constant_p(rn) && rn < 1024)  \
-   asm volatile("mfdcr %0," __stringify(rn)\
- : "=r" (rval));   \
+   asm volatile("mfdcr %0, %1" : "=r" (rval)   \
+: "n" (rn));   \
else if (likely(cpu_has_feature(CPU_FTR_INDEXED_DCR)))  \
rval = mfdcrx(rn);  \
else\


I guess because we give the compiler time to work out the constant,
rather than stringifying it immediately.

cheers


Re: memory leak in path_openat (2)

2021-02-16 Thread Al Viro
On Tue, Feb 16, 2021 at 09:21:14PM -0800, syzbot wrote:
> Hello,
> 
> syzbot found the following issue on:
> 
> HEAD commit:dcc0b490 Merge tag 'powerpc-5.11-8' of git://git.kernel.or..
> git tree:   upstream
> console output: https://syzkaller.appspot.com/x/log.txt?x=1316c614d0
> kernel config:  https://syzkaller.appspot.com/x/.config?x=a2fbb1a71525e1d5
> dashboard link: https://syzkaller.appspot.com/bug?extid=921ef0ccfeed3a496721
> syz repro:  https://syzkaller.appspot.com/x/repro.syz?x=1378ba4cd0
> C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=12e73fc2d0
> 
> IMPORTANT: if you fix the issue, please add the following tag to the commit:
> Reported-by: syzbot+921ef0ccfeed3a496...@syzkaller.appspotmail.com

Some observations:
* .config is x86 one
* merge in question is ppc-only
* at least some "leaks" reported are dentries in devtmpfs,
  which should stay around until the shutdown
Care to bisect to something more useful?


Re: [PATCH v2 1/2] exfat: add initial ioctl function

2021-02-16 Thread Namjae Jeon
2021-02-17 9:33 GMT+09:00, Hyeongseok Kim :
> On 2/17/21 9:17 AM, Chaitanya Kulkarni wrote:
>> On 2/16/21 16:13, Hyeongseok Kim wrote:
>>> Sorry, I don't understand exactly.
>>> You're saying that these 2 patch should be merged to a single patch?
>>> Would it be better?
>> I think so unless there is a specific reason for this to keep it
>> isolated.
>>
> The reason was just that I think it seems better to seperate ioctl
> initializing and adding specific ioctl functionality.
> Anyway, I got it.
>
> Namjae,
Hi Hyeongseok,
> Do you have any other opinion about this?
I also think this patch should be combined with the 2/2 patch.
> If you agree, I'll merge these as one.
Yep, Agreed. Please do that:)
Thanks!
>
>


[PATCH 1/2] dt-bindings: mmc: Add no-single-read-retry property

2021-02-16 Thread DooHyun Hwang
Add an optional property to not retry multiple block read error
with several single block reads.

This property makes to handle read errors faster by not retrying
multiple block read errors with single block reads.

Signed-off-by: DooHyun Hwang 
---
 Documentation/devicetree/bindings/mmc/mmc-controller.yaml | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml 
b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
index e141330c1114..1eb3b73a164a 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
+++ b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
@@ -245,6 +245,12 @@ properties:
   Controller is limited to send MMC commands during
   initialization.
 
+  no-single-read-retry:
+$ref: /schemas/types.yaml#/definitions/flag
+description:
+  Single block read retrying is not supported
+  when multiple block read fails.
+
   fixed-emmc-driver-type:
 description:
   For non-removable eMMC, enforce this driver type. The value is
-- 
2.29.0



[PATCH 2/2] mmc: core: Add no single read retries

2021-02-16 Thread DooHyun Hwang
This makes to handle read errors faster by not retrying
multiple block read(CMD18) errors with single block reads(CMD17).

On some bad SD Cards that have problem with read operations,
it is not helpful to retry multiple block read errors with
several single block reads, and it is delayed to treat read
operations as I/O error as much as retrying single block reads.

Signed-off-by: DooHyun Hwang 
---
 drivers/mmc/core/block.c | 3 ++-
 drivers/mmc/core/host.c  | 6 ++
 include/linux/mmc/host.h | 3 +++
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index d666e24fbe0e..e25aaf8fca34 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -1809,7 +1809,8 @@ static void mmc_blk_mq_rw_recovery(struct mmc_queue *mq, 
struct request *req)
 
/* FIXME: Missing single sector read for large sector size */
if (!mmc_large_sector(card) && rq_data_dir(req) == READ &&
-   brq->data.blocks > 1) {
+   brq->data.blocks > 1 &&
+   !card->host->no_single_read_retry) {
/* Read one sector at a time */
mmc_blk_read_single(mq, req);
return;
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 9b89a91b6b47..3bf5b2fc111b 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -352,6 +352,12 @@ int mmc_of_parse(struct mmc_host *host)
if (device_property_read_bool(dev, "no-mmc"))
host->caps2 |= MMC_CAP2_NO_MMC;
 
+   if (device_property_read_bool(dev, "no-single-read-retry")) {
+   dev_info(host->parent,
+   "Single block read retrying is not supported\n");
+   host->no_single_read_retry = true;
+   }
+
/* Must be after "non-removable" check */
if (device_property_read_u32(dev, "fixed-emmc-driver-type", _type) 
== 0) {
if (host->caps & MMC_CAP_NONREMOVABLE)
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 26a3c7bc29ae..faec55035a63 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -502,6 +502,9 @@ struct mmc_host {
/* Host Software Queue support */
boolhsq_enabled;
 
+   /* Do not retry multi block read as single block read */
+   boolno_single_read_retry;
+
unsigned long   private[] cacheline_aligned;
 };
 
-- 
2.29.0



[PATCH 0/2] mmc: core: add a new property

2021-02-16 Thread DooHyun Hwang
Add an optional property to not retry multiple block read error
with several single block reads.

DooHyun Hwang (2):
  dt-bindings: mmc: Add no-single-read-retry property
  mmc: core: Add no single read retries

 Documentation/devicetree/bindings/mmc/mmc-controller.yaml | 6 ++
 drivers/mmc/core/block.c  | 3 ++-
 drivers/mmc/core/host.c   | 6 ++
 include/linux/mmc/host.h  | 3 +++
 4 files changed, 17 insertions(+), 1 deletion(-)

-- 
2.29.0



Re: DT overlay applied via pinctrl description

2021-02-16 Thread Frank Rowand
+Frank, Rob, devicetree list

On 2/16/21 9:35 AM, Michal Simek wrote:
> Hi,
> 
> I have a question about expectations when pinctrl setting is applied. In
> DTS all nodes are described in the order available in DT.
> 
> uart-default {
>   mux {
>   ...
>   };
> 
>   conf {
>   ...
>   };
> };
> 
> I don't know if this standard description or not. I definitely see other
> pinctrl drivers which are using different structure.
> 
> Anyway when overlay is applied the order has changed to
> uart-default {
>   conf {
>   ...
>   };
> 
>   mux {
>   ...
>   };
> };
> 
> which is causing issue because pin is configured first via conf node
> before it is requested via mux. This is something what firmware is
> checking and error out.
> 
> That's why I want to check with you if this is issue with DT binding
> description we use in zynqmp pinctrl driver posted here
> https://lore.kernel.org/linux-arm-kernel/1613131643-60062-1-git-send-email-lakshmi.sai.krishna.potth...@xilinx.com/
> 
> I have also tried to use init and default configuration where init is
> called just with mux setting and then default is called just with config
> but the issue is there as well because in pinctrl_commit_state()
> previous state is checked and for MUXes pinmux_disable_setting() is
> called which release a pin. And then configuration in default is called
> but without requesting pin which fails for the same reason as above.
> 
> That's why my questions are:
> Are we using incorrect DT description?
> And is there a need sort subnodes in a way that mux should be called
> first by core before configuration?
> Or is there any different way how to do it?

Node ordering and property ordering within a node are not defined
in the Linux kernel.  If a subsystem or property is depending upon
a certain order, they must implement a method other than the
order as accessed by of_* functions.  And as you noted, use of an
overlay may also change ordering.

-Frank

> 
> Thanks,
> Michal
> 



[PATCH 1/2] dt-bindings: mmc: Add no-single-read-retry property

2021-02-16 Thread DooHyun Hwang
Add an optional property to not retry multiple block read error
with several single block reads.

This property makes to handle read errors faster by not retrying
multiple block read errors with single block reads.

Signed-off-by: DooHyun Hwang 
---
 Documentation/devicetree/bindings/mmc/mmc-controller.yaml | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml 
b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
index e141330c1114..1eb3b73a164a 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
+++ b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
@@ -245,6 +245,12 @@ properties:
   Controller is limited to send MMC commands during
   initialization.
 
+  no-single-read-retry:
+$ref: /schemas/types.yaml#/definitions/flag
+description:
+  Single block read retrying is not supported
+  when multiple block read fails.
+
   fixed-emmc-driver-type:
 description:
   For non-removable eMMC, enforce this driver type. The value is
-- 
2.29.0



[PATCH 2/2] mmc: core: Add no single read retries

2021-02-16 Thread DooHyun Hwang
This makes to handle read errors faster by not retrying
multiple block read(CMD18) errors with single block reads(CMD17).

On some bad SD Cards that have problem with read operations,
it is not helpful to retry multiple block read errors with
several single block reads, and it is delayed to treat read
operations as I/O error as much as retrying single block reads.

Signed-off-by: DooHyun Hwang 
---
 drivers/mmc/core/block.c | 3 ++-
 drivers/mmc/core/host.c  | 6 ++
 include/linux/mmc/host.h | 3 +++
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index d666e24fbe0e..e25aaf8fca34 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -1809,7 +1809,8 @@ static void mmc_blk_mq_rw_recovery(struct mmc_queue *mq, 
struct request *req)
 
/* FIXME: Missing single sector read for large sector size */
if (!mmc_large_sector(card) && rq_data_dir(req) == READ &&
-   brq->data.blocks > 1) {
+   brq->data.blocks > 1 &&
+   !card->host->no_single_read_retry) {
/* Read one sector at a time */
mmc_blk_read_single(mq, req);
return;
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 9b89a91b6b47..3bf5b2fc111b 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -352,6 +352,12 @@ int mmc_of_parse(struct mmc_host *host)
if (device_property_read_bool(dev, "no-mmc"))
host->caps2 |= MMC_CAP2_NO_MMC;
 
+   if (device_property_read_bool(dev, "no-single-read-retry")) {
+   dev_info(host->parent,
+   "Single block read retrying is not supported\n");
+   host->no_single_read_retry = true;
+   }
+
/* Must be after "non-removable" check */
if (device_property_read_u32(dev, "fixed-emmc-driver-type", _type) 
== 0) {
if (host->caps & MMC_CAP_NONREMOVABLE)
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 26a3c7bc29ae..faec55035a63 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -502,6 +502,9 @@ struct mmc_host {
/* Host Software Queue support */
boolhsq_enabled;
 
+   /* Do not retry multi block read as single block read */
+   boolno_single_read_retry;
+
unsigned long   private[] cacheline_aligned;
 };
 
-- 
2.29.0



[PATCH 0/2] mmc: core: add a new property

2021-02-16 Thread DooHyun Hwang
Add an optional property to not retry multiple block read error
with several single block reads.

DooHyun Hwang (2):
  dt-bindings: mmc: Add no-single-read-retry property
  mmc: core: Add no single read retries

 Documentation/devicetree/bindings/mmc/mmc-controller.yaml | 6 ++
 drivers/mmc/core/block.c  | 3 ++-
 drivers/mmc/core/host.c   | 6 ++
 include/linux/mmc/host.h  | 3 +++
 4 files changed, 17 insertions(+), 1 deletion(-)

-- 
2.29.0



memory leak in path_openat (2)

2021-02-16 Thread syzbot
Hello,

syzbot found the following issue on:

HEAD commit:dcc0b490 Merge tag 'powerpc-5.11-8' of git://git.kernel.or..
git tree:   upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=1316c614d0
kernel config:  https://syzkaller.appspot.com/x/.config?x=a2fbb1a71525e1d5
dashboard link: https://syzkaller.appspot.com/bug?extid=921ef0ccfeed3a496721
syz repro:  https://syzkaller.appspot.com/x/repro.syz?x=1378ba4cd0
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=12e73fc2d0

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+921ef0ccfeed3a496...@syzkaller.appspotmail.com

BUG: memory leak
unreferenced object 0x88810ffa0780 (size 192):
  comm "systemd-udevd", pid 9109, jiffies 4294974202 (age 70.810s)
  hex dump (first 32 bytes):
44 80 00 00 06 00 00 00 00 00 00 00 00 00 00 00  D...
00 00 00 00 00 00 00 00 c0 63 f1 0f 81 88 ff ff  .c..
  backtrace:
[<0f4d69f8>] __d_alloc+0x2a/0x270 fs/dcache.c:1716
[] d_alloc+0x25/0xd0 fs/dcache.c:1795
[<7cbd02b4>] d_alloc_parallel+0x6b/0x940 fs/dcache.c:2547
[] lookup_open fs/namei.c:3033 [inline]
[] open_last_lookups fs/namei.c:3180 [inline]
[] path_openat+0xca3/0x1b00 fs/namei.c:3368
[] do_filp_open+0xa0/0x190 fs/namei.c:3398
[] do_sys_openat2+0xed/0x230 fs/open.c:1172
[<2fb778b6>] do_sys_open fs/open.c:1188 [inline]
[<2fb778b6>] __do_sys_open fs/open.c:1196 [inline]
[<2fb778b6>] __se_sys_open fs/open.c:1192 [inline]
[<2fb778b6>] __x64_sys_open+0x7d/0xe0 fs/open.c:1192
[<11942ea6>] do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46
[<76bff2b1>] entry_SYSCALL_64_after_hwframe+0x44/0xa9

BUG: memory leak
unreferenced object 0x88810ffea360 (size 608):
  comm "systemd-udevd", pid 9109, jiffies 4294974202 (age 70.810s)
  hex dump (first 32 bytes):
a4 81 0c 00 00 00 00 00 00 00 00 00 00 00 00 00  
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  
  backtrace:
[] alloc_inode+0xbe/0x100 fs/inode.c:235
[] iget_locked+0x126/0x340 fs/inode.c:1192
[<25e74921>] kernfs_get_inode+0x20/0x190 fs/kernfs/inode.c:252
[<8b802090>] kernfs_iop_lookup+0xa0/0xe0 fs/kernfs/dir.c:1100
[] lookup_open fs/namei.c:3085 [inline]
[] open_last_lookups fs/namei.c:3180 [inline]
[] path_openat+0x95d/0x1b00 fs/namei.c:3368
[] do_filp_open+0xa0/0x190 fs/namei.c:3398
[] do_sys_openat2+0xed/0x230 fs/open.c:1172
[<2fb778b6>] do_sys_open fs/open.c:1188 [inline]
[<2fb778b6>] __do_sys_open fs/open.c:1196 [inline]
[<2fb778b6>] __se_sys_open fs/open.c:1192 [inline]
[<2fb778b6>] __x64_sys_open+0x7d/0xe0 fs/open.c:1192
[<11942ea6>] do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46
[<76bff2b1>] entry_SYSCALL_64_after_hwframe+0x44/0xa9

BUG: memory leak
unreferenced object 0x88810ec1b2b8 (size 24):
  comm "systemd-udevd", pid 9109, jiffies 4294974202 (age 70.810s)
  hex dump (first 24 bytes):
98 a4 fe 0f 81 88 ff ff 30 e1 09 82 ff ff ff ff  0...
00 00 00 00 00 00 00 00  
  backtrace:
[] kmem_cache_zalloc include/linux/slab.h:672 [inline]
[] lsm_inode_alloc security/security.c:590 [inline]
[] security_inode_alloc+0x2a/0xb0 security/security.c:973
[<9366b0d8>] inode_init_always+0x10c/0x250 fs/inode.c:170
[<357b1464>] alloc_inode+0x44/0x100 fs/inode.c:240
[] iget_locked+0x126/0x340 fs/inode.c:1192
[<25e74921>] kernfs_get_inode+0x20/0x190 fs/kernfs/inode.c:252
[<8b802090>] kernfs_iop_lookup+0xa0/0xe0 fs/kernfs/dir.c:1100
[] lookup_open fs/namei.c:3085 [inline]
[] open_last_lookups fs/namei.c:3180 [inline]
[] path_openat+0x95d/0x1b00 fs/namei.c:3368
[] do_filp_open+0xa0/0x190 fs/namei.c:3398
[] do_sys_openat2+0xed/0x230 fs/open.c:1172
[<2fb778b6>] do_sys_open fs/open.c:1188 [inline]
[<2fb778b6>] __do_sys_open fs/open.c:1196 [inline]
[<2fb778b6>] __se_sys_open fs/open.c:1192 [inline]
[<2fb778b6>] __x64_sys_open+0x7d/0xe0 fs/open.c:1192
[<11942ea6>] do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46
[<76bff2b1>] entry_SYSCALL_64_after_hwframe+0x44/0xa9

BUG: memory leak
unreferenced object 0x88810ffc3f00 (size 192):
  comm "kdevtmpfs", pid 21, jiffies 4294974223 (age 70.600s)
  hex dump (first 32 bytes):
08 80 00 00 

Re: [External] Re: [PATCH 4/4] mm: memcontrol: fix swap uncharge on cgroup v2

2021-02-16 Thread Muchun Song
On Wed, Feb 17, 2021 at 1:28 AM Johannes Weiner  wrote:
>
> On Tue, Feb 16, 2021 at 11:59:01AM -0500, Johannes Weiner wrote:
> > Hello Muchun,
> >
> > On Sat, Feb 13, 2021 at 01:01:59AM +0800, Muchun Song wrote:
> > > The swap charges the actual number of swap entries on cgroup v2.
> > > If a swap cache page is charged successful, and then we uncharge
> > > the swap counter. It is wrong on cgroup v2. Because the swap
> > > entry is not freed.
> >
> > The patch makes sense to me. But this code is a bit tricky, we should
> > add more documentation to how it works and what the problem is.
> >
> > How about this for the changelog?
> >
> > ---
> > mm: memcontrol: fix swap undercounting for shared pages in cgroup2
>
> Coming to think of it, this isn't just for shared pages. We also hold
> on to the swap slot as long as the page is read-only, not mlocked, and
> swap isn't full. So scratch "for shared pages" here.

OK. Will do.

>
> > When shared pages are swapped in partially, we can have some page
> > tables referencing the in-memory page and some referencing the swap
> > slot. Cgroup1 and cgroup2 handle these overlapping lifetimes slightly
> > differently due to the nature of how they account memory and swap:
>
> Correction:
>
> When pages are swapped in, the VM may retain the swap copy to avoid
> repeated writes in the future. It's also retained if shared pages are
> faulted back in some processes, but not in others. During that time we
> have an in-memory copy of the page, as well as an on-swap
> copy. Cgroup1 and cgroup2 handle these overlapping lifetimes slightly
> differently due to the nature of how they account memory and swap:

Thanks a lot.

>
> > Cgroup1 has a unified memory+swap counter that tracks a data page
> > regardless whether it's in-core or swapped out. On swapin, we transfer
> > the charge from the swap entry to the newly allocated swapcache page,
> > even though the swap entry might stick around for a while. That's why
> > we have a mem_cgroup_uncharge_swap() call inside mem_cgroup_charge().
> >
> > Cgroup2 tracks memory and swap as separate, independent resources and
> > thus has split memory and swap counters. On swapin, we charge the
> > newly allocated swapcache page as memory, while the swap slot in turn
> > must remain charged to the swap counter as long as its allocated too.
> >
> > The cgroup2 logic was broken by commit 2d1c498072de ("mm: memcontrol:
> > make swap tracking an integral part of memory control"), because it
> > accidentally removed the do_memsw_account() check in the branch inside
> > mem_cgroup_uncharge() that was supposed to tell the difference between
> > the charge transfer in cgroup1 and the separate counters in cgroup2.
> >
> > As a result, cgroup2 currently undercounts consumed swap when shared
> > pages are partially swapped back in. This in turn allows a cgroup to
> > consume more swap than its configured limit intends.
>
> Correction:
>
> As a result, cgroup2 currently undercounts retained swap to varying
> degrees: swap slots are cached up to 50% of the configured limit or
> total available swap space; partially faulted back shared pages are
> only limited by physical capacity. This in turn allows cgroups to
> significantly overconsume their alloted swap space.

Thanks a lot.

>
> > Add the do_memsw_account() check back to fix this problem.
> > ---
> >
> > > Fixes: 2d1c498072de ("mm: memcontrol: make swap tracking an integral part 
> > > of memory control")
> > > Signed-off-by: Muchun Song 
> >
> > Acked-by: Johannes Weiner 
>
> I also think we should tag stable on this one. The potential
> accounting error is quite large and, even without concrete examples,
> is likely to cause problems for swap management in the real world.
>
> Cc: sta...@vger.kernel.org # 5.8+

OK. I will add a Cc stable tag. Thanks.

>
> > >  mm/memcontrol.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> > > index c737c8f05992..be6bc5044150 100644
> > > --- a/mm/memcontrol.c
> > > +++ b/mm/memcontrol.c
> > > @@ -6753,7 +6753,7 @@ int mem_cgroup_charge(struct page *page, struct 
> > > mm_struct *mm, gfp_t gfp_mask)
> > > memcg_check_events(memcg, page);
> > > local_irq_enable();
> > >
> > > -   if (PageSwapCache(page)) {
> > > +   if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) && PageSwapCache(page)) 
> > > {
> >
> > It's more descriptive to use do_memsw_account() here, IMO.
> >
> > We should also add a comment. How about this above the branch?
> >
> >   /*
> >* Cgroup1's unified memory+swap counter has been charged with the
> >* new swapcache page, finish the transfer by uncharging the swap
> >* slot. The swap slot would also get uncharged when it dies, but
> >* for shared pages it can stick around indefinitely and we'd count
> >* the page twice the entire time.
>
> -for shared pages
>
> >* Cgroup2 has separate resource counters for memory and swap,
> >

Re: [External] Re: [PATCH 4/4] mm: memcontrol: fix swap uncharge on cgroup v2

2021-02-16 Thread Muchun Song
On Wed, Feb 17, 2021 at 12:59 AM Johannes Weiner  wrote:
>
> Hello Muchun,
>
> On Sat, Feb 13, 2021 at 01:01:59AM +0800, Muchun Song wrote:
> > The swap charges the actual number of swap entries on cgroup v2.
> > If a swap cache page is charged successful, and then we uncharge
> > the swap counter. It is wrong on cgroup v2. Because the swap
> > entry is not freed.
>
> The patch makes sense to me. But this code is a bit tricky, we should
> add more documentation to how it works and what the problem is.
>
> How about this for the changelog?
>
> ---
> mm: memcontrol: fix swap undercounting for shared pages in cgroup2
>
> When shared pages are swapped in partially, we can have some page
> tables referencing the in-memory page and some referencing the swap
> slot. Cgroup1 and cgroup2 handle these overlapping lifetimes slightly
> differently due to the nature of how they account memory and swap:
>
> Cgroup1 has a unified memory+swap counter that tracks a data page
> regardless whether it's in-core or swapped out. On swapin, we transfer
> the charge from the swap entry to the newly allocated swapcache page,
> even though the swap entry might stick around for a while. That's why
> we have a mem_cgroup_uncharge_swap() call inside mem_cgroup_charge().
>
> Cgroup2 tracks memory and swap as separate, independent resources and
> thus has split memory and swap counters. On swapin, we charge the
> newly allocated swapcache page as memory, while the swap slot in turn
> must remain charged to the swap counter as long as its allocated too.
>
> The cgroup2 logic was broken by commit 2d1c498072de ("mm: memcontrol:
> make swap tracking an integral part of memory control"), because it
> accidentally removed the do_memsw_account() check in the branch inside
> mem_cgroup_uncharge() that was supposed to tell the difference between
> the charge transfer in cgroup1 and the separate counters in cgroup2.
>
> As a result, cgroup2 currently undercounts consumed swap when shared
> pages are partially swapped back in. This in turn allows a cgroup to
> consume more swap than its configured limit intends.
>
> Add the do_memsw_account() check back to fix this problem.

Thanks. Sorry for my poor English. I should improve my changelog.

> ---
>
> > Fixes: 2d1c498072de ("mm: memcontrol: make swap tracking an integral part 
> > of memory control")
> > Signed-off-by: Muchun Song 
>
> Acked-by: Johannes Weiner 

Thanks.

>
> > ---
> >  mm/memcontrol.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> > index c737c8f05992..be6bc5044150 100644
> > --- a/mm/memcontrol.c
> > +++ b/mm/memcontrol.c
> > @@ -6753,7 +6753,7 @@ int mem_cgroup_charge(struct page *page, struct 
> > mm_struct *mm, gfp_t gfp_mask)
> >   memcg_check_events(memcg, page);
> >   local_irq_enable();
> >
> > - if (PageSwapCache(page)) {
> > + if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) && PageSwapCache(page)) 
> > {
>
> It's more descriptive to use do_memsw_account() here, IMO.
>
> We should also add a comment. How about this above the branch?

I will add a comment here. Thanks.

>
> /*
>  * Cgroup1's unified memory+swap counter has been charged with the
>  * new swapcache page, finish the transfer by uncharging the swap
>  * slot. The swap slot would also get uncharged when it dies, but
>  * for shared pages it can stick around indefinitely and we'd count
>  * the page twice the entire time.
>  *
>  * Cgroup2 has separate resource counters for memory and swap,
>  * so this is a non-issue here. Memory and swap charge lifetimes
>  * correspond 1:1 to page and swap slot lifetimes: we charge the
>  * page to memory here, and uncharge swap when the slot is freed.
>  */


Re: [External] Re: [PATCH] psi: Optimize task switch inside shared cgroups

2021-02-16 Thread Chengming Zhou
Hello Johannes,

在 2021/2/17 上午4:00, Johannes Weiner 写道:
> Hello Chengming,
>
> This patch looks useful to me. A couple of comments below:
>
> On Tue, Feb 09, 2021 at 03:14:13PM +0800, Chengming Zhou wrote:
>> The commit 36b238d57172 ("psi: Optimize switching tasks inside shared
>> cgroups") only update cgroups whose state actually changes during a
>> task switch only in task preempt case, not in task sleep case.
>>
>> We actually don't need to clear and set TSK_ONCPU state for common cgroups
>> of next and prev task in sleep case, that can save many psi_group_change
>> especially when most activity comes from one leaf cgroup.
> Can you please make this a bit more concrete? Maybe include this:
>
> sleep before:
> psi_dequeue()
>   while ((group = iterate_groups(prev)))  # all ancestors
> psi_group_change(prev, .clear=TSK_RUNNING|TSK_ONCPU)
> psi_task_switch()
>   while ((group = iterate_groups(next)))  # all ancestors
> psi_group_change(next, .set=TSK_ONCPU)
>
> sleep after:
> psi_dequeue()
>   nop
> psi_task_switch()
>   while ((group = iterate_groups(next)))  # until (prev & 
> next)
> psi_group_change(next, .set=TSK_ONCPU)
>   while ((group = iterate_groups(prev)))  # all ancestors
> psi_group_change(prev, .clear = common ? TSK_RUNNING : 
> TSK_RUNNING|TSK_ONCPU)
>
> When a voluntary sleep switches to another task, we remove one call of
> psi_group_change() for every common cgroup ancestor of the two tasks.
Thank you for the very beautiful and detailed comments, must be included : )
>> Signed-off-by: Muchun Song 
>> Signed-off-by: Chengming Zhou 
>> ---
>>  kernel/sched/psi.c   | 27 +--
>>  kernel/sched/stats.h | 17 +++--
>>  2 files changed, 20 insertions(+), 24 deletions(-)
>>
>> diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c
>> index 6e46d9eb279b..6061e87089ac 100644
>> --- a/kernel/sched/psi.c
>> +++ b/kernel/sched/psi.c
>> @@ -836,20 +836,27 @@ void psi_task_switch(struct task_struct *prev, struct 
>> task_struct *next,
>>  }
>>  }
>>  
>> -/*
>> - * If this is a voluntary sleep, dequeue will have taken care
>> - * of the outgoing TSK_ONCPU alongside TSK_RUNNING already. We
>> - * only need to deal with it during preemption.
>> - */
>> -if (sleep)
>> -return;
>> -
>>  if (prev->pid) {
>> -psi_flags_change(prev, TSK_ONCPU, 0);
>> +int clear = 0, set = 0;
>> +
>> +if (sleep) {
>> +clear |= TSK_RUNNING;
>> +if (prev->in_iowait)
>> +set |= TSK_IOWAIT;
>> +}
> This needs a comment why it's doing psi_dequeue()'s job. How about this?
>
>   /*
>* When we're going to sleep, psi_dequeue() lets us handle
>* TSK_RUNNING and TSK_IOWAIT here, where we can combine it
>* with TSK_ONCPU and save walking common ancestors twice.
>*/
>   if (sleep) {
>   ...
Make sense, will be added.
>> +psi_flags_change(prev, clear | TSK_ONCPU, set);
>>  
>>  iter = NULL;
>>  while ((group = iterate_groups(prev, )) && group != common)
>> -psi_group_change(group, cpu, TSK_ONCPU, 0, true);
>> +psi_group_change(group, cpu, clear | TSK_ONCPU, set, 
>> true);
>> +
>> +if (sleep) {
>> +while (group) {
>> +psi_group_change(group, cpu, clear, set, true);
>> +group = iterate_groups(prev, );
>> +}
>> +}
> This function is *primarily* about handling TSK_ONCPU and secondarily
> optimizes the dequeue. It would be a bit clearer to do:
>
>   int clear = TSK_ONCPU, set = 0;
>
>   ...
>
>   /*
>* TSK_ONCPU is handled up to the common ancestor. If we're tasked
>* with dequeuing too, finish that for the rest of the hierarchy.
>*/
>   if (sleep) {
>   clear &= TSK_ONCPU;
>   for (; group; group = iterate_groups(prev, ))
>   psi_group_change(group, cpu, clear, set, true); 
> 
>   }
>
Make sense, I will modify the patch and send a patch-v2.

BTW there is a typo above: clear &= ~TSK_ONCPU;

Thanks.

>> diff --git a/kernel/sched/stats.h b/kernel/sched/stats.h
>> index 9e4e67a94731..2d92c8467678 100644
>> --- a/kernel/sched/stats.h
>> +++ b/kernel/sched/stats.h
>> @@ -84,28 +84,17 @@ static inline void psi_enqueue(struct task_struct *p, 
>> bool wakeup)
>>  
>>  static inline void psi_dequeue(struct task_struct *p, bool sleep)
>>  {
>> -int clear = TSK_RUNNING, set = 0;
>> -
>>  if (static_branch_likely(_disabled))
>>  return;
>>  
>>  if (!sleep) {
>> +int clear = TSK_RUNNING;
>> +
>>  if 

linux-next: manual merge of the tip tree with the pm tree

2021-02-16 Thread Stephen Rothwell
Hi all,

Today's linux-next merge of the tip tree got a conflict in:

  arch/x86/platform/intel-mid/device_libs/platform_bt.c

between commit:

  4590d98f5a4f ("sfi: Remove framework for deprecated firmware")

from the pm tree and commit:

  bdb154f074a6 ("x86/platform/intel-mid: Convert comma to semicolon")

from the tip tree.

I fixed it up (the former removed the file, so I did that) and can
carry the fix as necessary. This is now fixed as far as linux-next is
concerned, but any non trivial conflicts should be mentioned to your
upstream maintainer when your tree is submitted for merging.  You may
also want to consider cooperating with the maintainer of the conflicting
tree to minimise any particularly complex conflicts.

-- 
Cheers,
Stephen Rothwell


pgppcBkiaaYcx.pgp
Description: OpenPGP digital signature


Re: [SPAM?]Re: arch/m68k/68000/dragen2.c:73:16: error: 'screen_bits' undeclared

2021-02-16 Thread Greg Ungerer

Hi Arnd,

On 12/2/21 8:05 pm, Arnd Bergmann wrote:

On Fri, Feb 12, 2021 at 6:48 AM kernel test robot  wrote:


FYI, the error/warning still remains.



  | ^~~~
arch/m68k/68000/dragen2.c: In function 'init_dragen2':

arch/m68k/68000/dragen2.c:73:16: error: 'screen_bits' undeclared (first use in 
this function)

   73 |  LSSA = (long) screen_bits;
  |^~~
arch/m68k/68000/dragen2.c:73:16: note: each undeclared identifier is 
reported only once for each function it appears in


This problem existed before my patch, I just moved the line to another file.
To fix it, one needs to test on real hardware and figure out what is supposed
to go in there.

The bug was apparently introduced in linux-2.5.70 in this commit:

>

commit 2b1a7e97c8c2d6330a432cbcaf83a0ef5fab848e
Author: gerg 
Date:   Mon May 26 16:45:57 2003 +

 [PATCH] fix m68knommu DragonEngine2 target setup code

 Numerous fixes for the m68knommu DragonEngine2 setup code.

 It was out of date relative to more recent kernels.  Original patches
 from Georges Menie.

 BKrev: 3ed244c5dPVeFKP63b4kkeS_rEshag


Digging around a bit I think the screen_bits data structure was
originally in a screen.h file that was generated from a screen.xbm file.
That was removed in commit 0c0e6db80683 ("m68k: drop unused parts of 
68VZ328 Makefile").


Obviously no one seems to be using this, that has been broken for a long 
time now.


I could restore the generated screen.h here, so this could compile at 
least. I don't have any of the hardware supported in the arch/m68k/68000 
directory, so I can't test anything we fix in there.


The other option is to remove the dragen code altogether.


Regards
Greg




Re: [PATCH] opp: fix dev_pm_opp_set_rate for different frequency at the same opp level

2021-02-16 Thread Viresh Kumar
On 16-02-21, 15:10, Jonathan Marek wrote:
> There is not "nothing to do" when the opp is the same. The frequency can
> be different from opp->rate.

I am sorry but I am not sure what are you trying to fix here and what exactly is
broken here. Can you provide a usecase for your platform where this doesn't work
like it used to ?

> Fixes: 81c4d8a3c414 ("opp: Keep track of currently programmed OPP")
> Signed-off-by: Jonathan Marek 
> ---
>  drivers/opp/core.c | 7 +--
>  drivers/opp/opp.h  | 1 +
>  2 files changed, 6 insertions(+), 2 deletions(-)

-- 
viresh


Re: [PATCH] dt-bindings: cpufreq: cpufreq-qcom-hw: Document SM8350 CPUfreq compatible

2021-02-16 Thread Viresh Kumar
On 16-02-21, 16:42, Vinod Koul wrote:
> Add the CPUfreq compatible for SM8350 SoC along with note for using the
> specific compatible for SoCs
> 
> Signed-off-by: Vinod Koul 
> ---
>  Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt 
> b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
> index 9299028ee712..3eb3cee59d79 100644
> --- a/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
> +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
> @@ -8,7 +8,9 @@ Properties:
>  - compatible
>   Usage:  required
>   Value type: 
> - Definition: must be "qcom,cpufreq-hw" or "qcom,cpufreq-epss".
> + Definition: must be "qcom,cpufreq-hw" or "qcom,cpufreq-epss"
> + along with SoC specific compatible:
> +   "qcom,sm8350-cpufreq-epss", "qcom,cpufreq-epss"

And why is SoC specific compatible required here ? Is the implementation on
sm8350 any different than the ones using "qcom,cpufreq-epss" compatible ?

FWIW, the same compatible string must be reused until the time there is
difference in the hardware. The compatible string must be considered as a marker
for a particular version of the hardware.

-- 
viresh


Re: [PATCH v2] vfs: prevent copy_file_range to copy across devices

2021-02-16 Thread Nicolas Boichat
On Mon, Feb 15, 2021 at 11:42 PM Luis Henriques  wrote:
>
> Nicolas Boichat reported an issue when trying to use the copy_file_range
> syscall on a tracefs file.  It failed silently because the file content is
> generated on-the-fly (reporting a size of zero) and copy_file_range needs
> to know in advance how much data is present.

Not sure if you have the whole history, these links and discussion can
help if you want to expand on the commit message:
[1] http://issuetracker.google.com/issues/178332739
[2] https://lkml.org/lkml/2021/1/25/64
[3] https://lkml.org/lkml/2021/1/26/1736
[4] 
https://patchwork.kernel.org/project/linux-fsdevel/cover/20210212044405.4120619-1-drink...@chromium.org/

> This commit restores the cross-fs restrictions that existed prior to
> 5dae222a5ff0 ("vfs: allow copy_file_range to copy across devices") and
> removes generic_copy_file_range() calls from ceph, cifs, fuse, and nfs.

It goes beyond that, I think this also prevents copies within the same
FS if copy_file_range is not implemented. Which is IMHO a good thing
since this has been broken on procfs and friends ever since
copy_file_range was implemented (but I assume that nobody ever hit
that before cross-fs became available).

>
> Fixes: 5dae222a5ff0 ("vfs: allow copy_file_range to copy across devices")
> Link: 
> https://lore.kernel.org/linux-fsdevel/20210212044405.4120619-1-drink...@chromium.org/
> Cc: Nicolas Boichat 

You could replace that with Reported-by: Nicolas Boichat 

> Signed-off-by: Luis Henriques 
> ---
> Changes since v1 (after Amir review)
> - restored do_copy_file_range() helper
> - return -EOPNOTSUPP if fs doesn't implement CFR
> - updated commit description
>
>  fs/ceph/file.c | 21 +++-
>  fs/cifs/cifsfs.c   |  3 ---
>  fs/fuse/file.c | 21 +++-
>  fs/nfs/nfs4file.c  | 20 +++
>  fs/read_write.c| 49 ++
>  include/linux/fs.h |  3 ---
>  6 files changed, 19 insertions(+), 98 deletions(-)
>
[snip]
> diff --git a/fs/read_write.c b/fs/read_write.c
> index 75f764b43418..b217cd62ae0d 100644
> --- a/fs/read_write.c
> +++ b/fs/read_write.c
> @@ -1358,40 +1358,12 @@ COMPAT_SYSCALL_DEFINE4(sendfile64, int, out_fd, int, 
> in_fd,
>  }
>  #endif
>
> -/**
> - * generic_copy_file_range - copy data between two files
> - * @file_in:   file structure to read from
> - * @pos_in:file offset to read from
> - * @file_out:  file structure to write data to
> - * @pos_out:   file offset to write data to
> - * @len:   amount of data to copy
> - * @flags: copy flags
> - *
> - * This is a generic filesystem helper to copy data from one file to another.
> - * It has no constraints on the source or destination file owners - the files
> - * can belong to different superblocks and different filesystem types. Short
> - * copies are allowed.
> - *
> - * This should be called from the @file_out filesystem, as per the
> - * ->copy_file_range() method.
> - *
> - * Returns the number of bytes copied or a negative error indicating the
> - * failure.
> - */
> -
> -ssize_t generic_copy_file_range(struct file *file_in, loff_t pos_in,
> -   struct file *file_out, loff_t pos_out,
> -   size_t len, unsigned int flags)
> -{
> -   return do_splice_direct(file_in, _in, file_out, _out,
> -   len > MAX_RW_COUNT ? MAX_RW_COUNT : len, 0);
> -}
> -EXPORT_SYMBOL(generic_copy_file_range);
> -
>  static ssize_t do_copy_file_range(struct file *file_in, loff_t pos_in,
>   struct file *file_out, loff_t pos_out,
>   size_t len, unsigned int flags)
>  {
> +   ssize_t ret = -EXDEV;
> +
> /*
>  * Although we now allow filesystems to handle cross sb copy, passing
>  * a file of the wrong filesystem type to filesystem driver can result
> @@ -1400,14 +1372,14 @@ static ssize_t do_copy_file_range(struct file 
> *file_in, loff_t pos_in,
>  * several different file_system_type structures, but they all end up
>  * using the same ->copy_file_range() function pointer.
>  */
> -   if (file_out->f_op->copy_file_range &&
> -   file_out->f_op->copy_file_range == file_in->f_op->copy_file_range)
> -   return file_out->f_op->copy_file_range(file_in, pos_in,
> -  file_out, pos_out,
> -  len, flags);
> +   if (!file_out->f_op->copy_file_range)
> +   ret = -EOPNOTSUPP;

This doesn't work as the 0-filesize check is done before that in
vfs_copy_file_range (so the syscall still returns 0, works fine if you
comment out `if (len == 0)`).

Also, you need to check for file_in->f_op->copy_file_range instead,
the problem is if the _input_ filesystem doesn't report sizes or can't
seek properly.

> +   else if 

Re: riscv+KASAN does not boot

2021-02-16 Thread Dmitry Vyukov
On Tue, Feb 16, 2021 at 9:42 PM Alex Ghiti  wrote:
>
> Hi Dmitry,
>
> Le 2/16/21 à 6:25 AM, Dmitry Vyukov a écrit :
> > On Tue, Feb 16, 2021 at 12:17 PM Dmitry Vyukov  wrote:
> >>
> >> On Fri, Jan 29, 2021 at 9:11 AM Dmitry Vyukov  wrote:
>  I was fixing KASAN support for my sv48 patchset so I took a look at your
>  issue: I built a kernel on top of the branch riscv/fixes using
>  https://github.com/google/syzkaller/blob/269d24e857a757d09a898086a2fa6fa5d827c3e1/dashboard/config/linux/upstream-riscv64-kasan.config
>  and Buildroot 2020.11. I have the warnings regarding the use of
>  __virt_to_phys on wrong addresses (but that's normal since this function
>  is used in virt_addr_valid) but not the segfaults you describe.
> >>>
> >>> Hi Alex,
> >>>
> >>> Let me try to rebuild buildroot image. Maybe there was something wrong
> >>> with my build, though, I did 'make clean' before doing. But at the
> >>> same time it worked back in June...
> >>>
> >>> Re WARNINGs, they indicate kernel bugs. I am working on setting up a
> >>> syzbot instance on riscv. If there a WARNING during boot then the
> >>> kernel will be marked as broken. No further testing will happen.
> >>> Is it a mis-use of WARN_ON? If so, could anybody please remove it or
> >>> replace it with pr_err.
> >>
> >>
> >> Hi,
> >>
> >> I've localized one issue with riscv/KASAN:
> >> KASAN breaks VDSO and that's I think the root cause of weird faults I
> >> saw earlier. The following patch fixes it.
> >> Could somebody please upstream this fix? I don't know how to add/run
> >> tests for this.
> >> Thanks
> >>
> >> diff --git a/arch/riscv/kernel/vdso/Makefile 
> >> b/arch/riscv/kernel/vdso/Makefile
> >> index 0cfd6da784f84..cf3a383c1799d 100644
> >> --- a/arch/riscv/kernel/vdso/Makefile
> >> +++ b/arch/riscv/kernel/vdso/Makefile
> >> @@ -35,6 +35,7 @@ CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os
> >>   # Disable gcov profiling for VDSO code
> >>   GCOV_PROFILE := n
> >>   KCOV_INSTRUMENT := n
> >> +KASAN_SANITIZE := n
> >>
> >>   # Force dependency
> >>   $(obj)/vdso.o: $(obj)/vdso.so
>
> What's weird is that I don't have any issue without this patch with the
> following config whereas it indeed seems required for KASAN. But when
> looking at the segfaults you got earlier, the segfault address is 0xbb0
> and the cause is an instruction page fault: this address is the PLT base
> address in vdso.so and an instruction page fault would mean that someone
> tried to jump at this address, which is weird. At first sight, that does
> not seem related to your patch above, but clearly I may be wrong.
>
> Tobias, did you observe the same segfaults as Dmitry ?


I noticed that not all buildroot images use VDSO, it seems to be
dependent on libc settings (at least I think I changed it in the
past).
I also booted an image completely successfully including dhcpd/sshd
start, but then my executable crashed in clock_gettime. The executable
was build on linux/amd64 host with "riscv64-linux-gnu-gcc -static"
(10.2.1).


> > Second issue I am seeing seems to be related to text segment size.
> > I check out v5.11 and use this config:
> > https://gist.github.com/dvyukov/6af25474d455437577a84213b0cc9178
>
> This config gave my laptop a hard time ! Finally I was able to boot
> correctly to userspace, but I realized I used my sv48 branch...Either I
> fixed your issue along the way or I can't reproduce it, I'll give it a
> try tomorrow.

Where is your branch? I could also test in my setup on your branch.


> > Then trying to boot it using:
> > QEMU emulator version 5.2.0 (Debian 1:5.2+dfsg-3)
> > $ qemu-system-riscv64 -machine virt -smp 2 -m 4G ...
> >
> > It shows no output from the kernel whatsoever, even though I have
> > earlycon and output shows very early with other configs.
> > Kernel boots fine with defconfig and other smaller configs.
> >
> > If I enable KASAN_OUTLINE and CC_OPTIMIZE_FOR_SIZE, then this config
> > also boots fine. Both of these options significantly reduce kernel
> > size. However, I can also boot the kernel without these 2 configs, if
> > I disable a whole lot of subsystem configs. This makes me think that
> > there is an issue related to kernel size somewhere in
> > qemu/bootloader/kernel bootstrap code.
> > Does it make sense to you? Can somebody reproduce what I am seeing? >
>
> I did not bring any answer to your question, but at least you know I'm
> working on it, I'll keep you posted.
>
> Thanks for taking the time to setup syzkaller.
>
> Alex
>
> > Thanks
> >
> > ___
> > linux-riscv mailing list
> > linux-ri...@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-riscv
> >


[tip:x86/entry] BUILD SUCCESS 3aac798a917be3b8f2f647b834bb06bf2f8df4f1

2021-02-16 Thread kernel test robot
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git 
x86/entry
branch HEAD: 3aac798a917be3b8f2f647b834bb06bf2f8df4f1  um: Enforce the usage of 
asm-generic/softirq_stack.h

elapsed time: 725m

configs tested: 122
configs skipped: 117

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm defconfig
arm64allyesconfig
arm64   defconfig
arm  allyesconfig
arm  allmodconfig
sh  r7780mp_defconfig
powerpc   ebony_defconfig
m68k   m5249evb_defconfig
powerpcklondike_defconfig
arm   stm32_defconfig
m68km5272c3_defconfig
arc haps_hs_smp_defconfig
powerpc  walnut_defconfig
shedosk7760_defconfig
arm  footbridge_defconfig
sh  rsk7264_defconfig
nds32 allnoconfig
powerpc   lite5200b_defconfig
powerpc mpc83xx_defconfig
arm  alldefconfig
xtensa   allyesconfig
mips tb0287_defconfig
arm eseries_pxa_defconfig
arm rpc_defconfig
powerpc sbc8548_defconfig
shapsh4ad0a_defconfig
m68k  hp300_defconfig
ia64defconfig
powerpc  ppc64e_defconfig
shshmin_defconfig
mips cobalt_defconfig
xtensa  cadence_csp_defconfig
mipsmalta_qemu_32r6_defconfig
powerpc mpc832x_mds_defconfig
umkunit_defconfig
mips   ci20_defconfig
mips  maltaaprp_defconfig
mips  cavium_octeon_defconfig
mips  fuloong2e_defconfig
arc  alldefconfig
armmps2_defconfig
ia64 allmodconfig
ia64 allyesconfig
m68k allmodconfig
m68kdefconfig
m68k allyesconfig
nds32   defconfig
nios2allyesconfig
cskydefconfig
alpha   defconfig
alphaallyesconfig
nios2   defconfig
arc  allyesconfig
c6x  allyesconfig
h8300allyesconfig
arc defconfig
sh   allmodconfig
parisc  defconfig
s390 allyesconfig
s390 allmodconfig
parisc   allyesconfig
s390defconfig
i386 allyesconfig
sparcallyesconfig
sparc   defconfig
i386   tinyconfig
i386defconfig
mips allyesconfig
mips allmodconfig
powerpc  allyesconfig
powerpc  allmodconfig
powerpc   allnoconfig
x86_64   randconfig-a003-20210216
x86_64   randconfig-a002-20210216
x86_64   randconfig-a004-20210216
x86_64   randconfig-a001-20210216
x86_64   randconfig-a005-20210216
x86_64   randconfig-a006-20210216
i386 randconfig-a003-20210216
i386 randconfig-a005-20210216
i386 randconfig-a002-20210216
i386 randconfig-a006-20210216
i386 randconfig-a001-20210216
i386 randconfig-a004-20210216
x86_64   randconfig-a016-20210215
x86_64   randconfig-a013-20210215
x86_64   randconfig-a012-20210215
x86_64   randconfig-a015-20210215
x86_64   randconfig-a014-20210215
x86_64   randconfig-a011-20210215
i386 randconfig-a016-20210215
i386 randconfig-a014-20210215
i386 randconfig-a012-20210215
i386 randconfig-a013-20210215
i386 randconfig-a011-20210215
i386 randconfig-a015-20210215
riscvnommu_k210_defconfig
riscvallyesconfig
riscvnommu_virt_defconfig
riscv allnoconfig
riscv

[tip:master] BUILD SUCCESS 74b68949724a504c579e0073e23beba7a71602ba

2021-02-16 Thread kernel test robot
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git master
branch HEAD: 74b68949724a504c579e0073e23beba7a71602ba  Merge branch 'irq/core'

elapsed time: 725m

configs tested: 111
configs skipped: 2

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm defconfig
arm64allyesconfig
arm64   defconfig
arm  allyesconfig
arm  allmodconfig
sh  r7780mp_defconfig
powerpc   ebony_defconfig
m68k   m5249evb_defconfig
arm   imx_v4_v5_defconfig
ia64  tiger_defconfig
xtensasmp_lx200_defconfig
arm  pxa255-idp_defconfig
arm  exynos_defconfig
arm  pxa168_defconfig
sh  rsk7264_defconfig
nds32 allnoconfig
powerpc   lite5200b_defconfig
powerpc mpc83xx_defconfig
arm  alldefconfig
mips tb0287_defconfig
arm eseries_pxa_defconfig
arm rpc_defconfig
powerpc sbc8548_defconfig
shapsh4ad0a_defconfig
xtensa   allyesconfig
m68k  hp300_defconfig
ia64defconfig
powerpc  ppc64e_defconfig
shshmin_defconfig
mips cobalt_defconfig
xtensa  cadence_csp_defconfig
mips  cavium_octeon_defconfig
arc haps_hs_smp_defconfig
mips  fuloong2e_defconfig
arc  alldefconfig
armmps2_defconfig
ia64 allmodconfig
ia64 allyesconfig
m68k allmodconfig
m68kdefconfig
m68k allyesconfig
nds32   defconfig
nios2allyesconfig
cskydefconfig
alpha   defconfig
alphaallyesconfig
nios2   defconfig
arc  allyesconfig
c6x  allyesconfig
h8300allyesconfig
arc defconfig
sh   allmodconfig
parisc  defconfig
s390 allyesconfig
s390 allmodconfig
parisc   allyesconfig
s390defconfig
i386 allyesconfig
sparcallyesconfig
sparc   defconfig
i386   tinyconfig
i386defconfig
mips allyesconfig
mips allmodconfig
powerpc  allyesconfig
powerpc  allmodconfig
powerpc   allnoconfig
i386 randconfig-a003-20210216
i386 randconfig-a005-20210216
i386 randconfig-a002-20210216
i386 randconfig-a006-20210216
i386 randconfig-a001-20210216
i386 randconfig-a004-20210216
x86_64   randconfig-a003-20210216
x86_64   randconfig-a002-20210216
x86_64   randconfig-a004-20210216
x86_64   randconfig-a001-20210216
x86_64   randconfig-a005-20210216
x86_64   randconfig-a006-20210216
x86_64   randconfig-a016-20210215
x86_64   randconfig-a013-20210215
x86_64   randconfig-a012-20210215
x86_64   randconfig-a015-20210215
x86_64   randconfig-a014-20210215
x86_64   randconfig-a011-20210215
i386 randconfig-a016-20210215
i386 randconfig-a014-20210215
i386 randconfig-a012-20210215
i386 randconfig-a013-20210215
i386 randconfig-a011-20210215
i386 randconfig-a015-20210215
riscvnommu_k210_defconfig
riscvallyesconfig
riscvnommu_virt_defconfig
riscv allnoconfig
riscv   defconfig
riscv  rv32_defconfig
riscvallmodconfig
x86_64   rhel
x86_64   allyesconfig
x86_64rhel-7.6-kselftests
x86_64

Re: [PATCH v9 0/7] FPGA Security Manager Class Driver

2021-02-16 Thread Moritz Fischer
Hi Russ,

On Tue, Feb 16, 2021 at 09:46:53AM -0800, Russ Weight wrote:
> I believe all of the dependencies have been accepted now.
> 
> - Russ

Sorry for dropping the ball on this, I'll get to this ASAP after -rc1 is
tagged.

> 
> On 2/15/21 6:56 AM, Tom Rix wrote:
> > Russ, Moritz
> >
> > This patchset still applies.
> >
> > Updating the fpga is a fairly important feature.
> >
> > Are there any dependencies we are waiting on ?
> >
> > Tom
> >
> > On 1/5/21 2:59 PM, Russ Weight wrote:
> >> The FPGA Security Manager class driver provides a common
> >> API for user-space tools to manage updates for secure FPGA
> >> devices. Device drivers that instantiate the FPGA Security
> >> Manager class driver will interact with a HW secure update
> >> engine in order to transfer new FPGA and BMC images to FLASH so
> >> that they will be automatically loaded when the FPGA card reboots.
> >>
> >> A significant difference between the FPGA Manager and the FPGA 
> >> Security Manager is that the FPGA Manager does a live update (Partial
> >> Reconfiguration) to a device whereas the FPGA Security Manager
> >> updates the FLASH images for the Static Region and the BMC so that
> >> they will be loaded the next time the FPGA card boots. Security is
> >> enforced by hardware and firmware. The security manager interacts
> >> with the firmware to initiate an update, pass in the necessary data,
> >> and collect status on the update.
> >>
> >> The n3000bmc-secure driver is the first driver to use the FPGA
> >> Security Manager. This driver was previously submitted in the same
> >> patch set, but has been split out into a separate patch set starting
> >> with V2. Future devices will also make use of this common API for
> >> secure updates.
> >>
> >> In addition to managing secure updates of the FPGA and BMC images,
> >> the FPGA Security Manager update process may also be used to
> >> program root entry hashes and cancellation keys for the FPGA static
> >> region, the FPGA partial reconfiguration region, and the BMC.
> >> The image files are self-describing, and contain a header describing
> >> the image type.
> >>
> >> Secure updates make use of the request_firmware framework, which
> >> requires that image files are accessible under /lib/firmware. A request
> >> for a secure update returns immediately, while the update itself
> >> proceeds in the context of a kernel worker thread. Sysfs files provide
> >> a means for monitoring the progress of a secure update and for
> >> retrieving error information in the event of a failure.
> >>
> >> The API includes a "name" sysfs file to export the name of the parent
> >> driver. It also includes an "update" sub-directory containing files that
> >> that can be used to instantiate and monitor a secure update.
> >>
> >> Changelog v8 -> v9:
> >>   - Rebased patches for 5.11-rc2
> >>   - Updated Date and KernelVersion in ABI documentation
> >>
> >> Changelog v7 -> v8:
> >>   - Fixed grammatical error in Documentation/fpga/fpga-sec-mgr.rst
> >>
> >> Changelog v6 -> v7:
> >>   - Changed dates in documentation file to December 2020
> >>   - Changed filename_store() to use kmemdup_nul() instead of
> >> kstrndup() and changed the count to not assume a line-return.
> >>
> >> Changelog v5 -> v6:
> >>   - Removed sysfs support and documentation for the display of the
> >> flash count, root entry hashes, and code-signing-key cancelation
> >> vectors from the class driver. This information can vary by device
> >> and will instead be displayed by the device-specific parent driver.
> >>
> >> Changelog v4 -> v5:
> >>   - Added the devm_fpga_sec_mgr_unregister() function, following recent
> >> changes to the fpga_manager() implementation.
> >>   - Changed most of the *_show() functions to use sysfs_emit()
> >> instead of sprintf(
> >>   - When checking the return values for functions of type enum
> >> fpga_sec_err err_code, test for FPGA_SEC_ERR_NONE instead of 0
> >>
> >> Changelog v3 -> v4:
> >>   - This driver is generic enough that it could be used for non Intel
> >> FPGA devices. Changed from "Intel FPGA Security Manager" to FPGA
> >> Security Manager" and removed unnecessary references to "Intel".
> >>   - Changed: iops -> sops, imgr -> smgr, IFPGA_ -> FPGA_, ifpga_ to fpga_
> >> Note that this also affects some filenames.
> >>
> >> Changelog v2 -> v3:
> >>   - Use dev_err() to report invalid progress in sec_progress()
> >>   - Use dev_err() to report invalid error code in sec_error()
> >>   - Modified sysfs handler check in check_sysfs_handler() to make
> >> it more readable.
> >>   - Removed unnecessary "goto done"
> >>   - Added a comment to explain imgr->driver_unload in
> >> ifpga_sec_mgr_unregister()
> >>
> >> Changelog v1 -> v2:
> >>   - Separated out the MAX10 BMC Security Engine to be submitted in
> >> a separate patch-set.
> >>   - Bumped documentation dates and versions
> >>   - Split ifpga_sec_mgr_register() into create() and register() 

Re: [PATCH V3 1/2] topology: Allow multiple entities to provide sched_freq_tick() callback

2021-02-16 Thread Viresh Kumar
On 17-02-21, 00:24, Ionela Voinescu wrote:
> I think it could be merged in patch 1/2 as it's part of enabling the use
> of multiple sources of information for FIE. Up to you!

Sure.

> >  static void amu_fie_setup(const struct cpumask *cpus)
> >  {
> > -   bool invariant;
> > int cpu;
> >  
> > /* We are already set since the last insmod of cpufreq driver */
> > @@ -257,25 +256,10 @@ static void amu_fie_setup(const struct cpumask *cpus)
> >  
> > cpumask_or(amu_fie_cpus, amu_fie_cpus, cpus);
> >  
> > -   invariant = topology_scale_freq_invariant();
> > -
> > -   /* We aren't fully invariant yet */
> > -   if (!invariant && !cpumask_equal(amu_fie_cpus, cpu_present_mask))
> > -   return;
> > -
> 
> You still need these checks, otherwise you could end up with only part
> of the CPUs setting a scale factor, when only part of the CPUs support
> AMUs and there is no cpufreq support for FIE.

Both supports_scale_freq_counters() and topology_scale_freq_invariant() take
care of this now and they will keep reporting the system as invariant until the
time all the CPUs have counters (in absence of cpufreq).

The topology_set_scale_freq_source() API is supposed to be called multiple
times, probably once for each policy and so I don't see a need of these checks
anymore.

> Small(ish) optimisation at the beginning of this function:
> 
> if (cpumask_empty(_freq_counters_mask))
> scale_freq_invariant = topology_scale_freq_invariant();
> 
> This will save you a call to rebuild_sched_domains_energy(), which is
> quite expensive, when cpufreq supports FIE and we also have counters.

Good Point.
 
> After comments addressed,
> 
> Reviewed-by: Ionela Voinescu 

Thanks.

> Tested-by: Ionela Voinescu 

Just out of curiosity, what exactly did you test and what was the setup ? :)

-- 
viresh


[PATCH net-next v2 5/5] net: stmmac: dwmac-sun8i: Add a shutdown callback

2021-02-16 Thread Samuel Holland
The Ethernet MAC and PHY are usually major consumers of power on boards
which may not be able to fully power off (those with no PMIC). Powering
down the MAC and internal PHY saves power while these boards are "off".

Reviewed-by: Chen-Yu Tsai 
Signed-off-by: Samuel Holland 
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index a3d333b652836..6b75cf2603ffc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -1284,6 +1284,15 @@ static int sun8i_dwmac_remove(struct platform_device 
*pdev)
return 0;
 }
 
+static void sun8i_dwmac_shutdown(struct platform_device *pdev)
+{
+   struct net_device *ndev = platform_get_drvdata(pdev);
+   struct stmmac_priv *priv = netdev_priv(ndev);
+   struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
+
+   sun8i_dwmac_exit(pdev, gmac);
+}
+
 static const struct of_device_id sun8i_dwmac_match[] = {
{ .compatible = "allwinner,sun8i-h3-emac",
.data = _variant_h3 },
@@ -1304,6 +1313,7 @@ MODULE_DEVICE_TABLE(of, sun8i_dwmac_match);
 static struct platform_driver sun8i_dwmac_driver = {
.probe  = sun8i_dwmac_probe,
.remove = sun8i_dwmac_remove,
+   .shutdown = sun8i_dwmac_shutdown,
.driver = {
.name   = "dwmac-sun8i",
.pm = _pltfr_pm_ops,
-- 
2.26.2



[PATCH net-next v2 1/5] net: stmmac: dwmac-sun8i: Return void from PHY unpower

2021-02-16 Thread Samuel Holland
This is a deinitialization function that always returned zero, and that
return value was always ignored. Have it return void instead.

Reviewed-by: Chen-Yu Tsai 
Signed-off-by: Samuel Holland 
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index a5e0eff4a3874..8e505019adf85 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -820,15 +820,14 @@ static int sun8i_dwmac_power_internal_phy(struct 
stmmac_priv *priv)
return 0;
 }
 
-static int sun8i_dwmac_unpower_internal_phy(struct sunxi_priv_data *gmac)
+static void sun8i_dwmac_unpower_internal_phy(struct sunxi_priv_data *gmac)
 {
if (!gmac->internal_phy_powered)
-   return 0;
+   return;
 
clk_disable_unprepare(gmac->ephy_clk);
reset_control_assert(gmac->rst_ephy);
gmac->internal_phy_powered = false;
-   return 0;
 }
 
 /* MDIO multiplexing switch function
-- 
2.26.2



[PATCH net-next v2 3/5] net: stmmac: dwmac-sun8i: Use reset_control_reset

2021-02-16 Thread Samuel Holland
Use the appropriate function instead of reimplementing it,
and update the error message to match the code.

Reviewed-by: Chen-Yu Tsai 
Signed-off-by: Samuel Holland 
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index 3c3d0b99d3e8c..b61f442ed3033 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -805,12 +805,12 @@ static int sun8i_dwmac_power_internal_phy(struct 
stmmac_priv *priv)
 
/* Make sure the EPHY is properly reseted, as U-Boot may leave
 * it at deasserted state, and thus it may fail to reset EMAC.
+*
+* This assumes the driver has exclusive access to the EPHY reset.
 */
-   reset_control_assert(gmac->rst_ephy);
-
-   ret = reset_control_deassert(gmac->rst_ephy);
+   ret = reset_control_reset(gmac->rst_ephy);
if (ret) {
-   dev_err(priv->device, "Cannot deassert internal phy\n");
+   dev_err(priv->device, "Cannot reset internal PHY\n");
clk_disable_unprepare(gmac->ephy_clk);
return ret;
}
-- 
2.26.2



[PATCH net-next v2 0/5] dwmac-sun8i cleanup and shutdown hook

2021-02-16 Thread Samuel Holland
These patches clean up some things I noticed while fixing suspend/resume
behavior. The first four are minor code improvements. The last one adds
a shutdown hook to minimize power consumption on boards without a PMIC.

Changes v1 to v2:
  - Note the assumption of exclusive reset controller access in patch 3

Samuel Holland (5):
  net: stmmac: dwmac-sun8i: Return void from PHY unpower
  net: stmmac: dwmac-sun8i: Remove unnecessary PHY power check
  net: stmmac: dwmac-sun8i: Use reset_control_reset
  net: stmmac: dwmac-sun8i: Minor probe function cleanup
  net: stmmac: dwmac-sun8i: Add a shutdown callback

 .../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 33 ---
 1 file changed, 21 insertions(+), 12 deletions(-)

-- 
2.26.2



[PATCH net-next v2 4/5] net: stmmac: dwmac-sun8i: Minor probe function cleanup

2021-02-16 Thread Samuel Holland
Adjust the spacing and use an explicit "return 0" in the success path
to make the function easier to parse.

Reviewed-by: Chen-Yu Tsai 
Signed-off-by: Samuel Holland 
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index b61f442ed3033..a3d333b652836 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -1229,6 +1229,7 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
 
ndev = dev_get_drvdata(>dev);
priv = netdev_priv(ndev);
+
/* The mux must be registered after parent MDIO
 * so after stmmac_dvr_probe()
 */
@@ -1247,7 +1248,8 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
goto dwmac_remove;
}
 
-   return ret;
+   return 0;
+
 dwmac_mux:
reset_control_put(gmac->rst_ephy);
clk_put(gmac->ephy_clk);
-- 
2.26.2



[PATCH net-next v2 2/5] net: stmmac: dwmac-sun8i: Remove unnecessary PHY power check

2021-02-16 Thread Samuel Holland
sun8i_dwmac_unpower_internal_phy already checks if the PHY is powered,
so there is no need to do it again here.

Reviewed-by: Chen-Yu Tsai 
Signed-off-by: Samuel Holland 
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index 8e505019adf85..3c3d0b99d3e8c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -1018,10 +1018,8 @@ static void sun8i_dwmac_exit(struct platform_device 
*pdev, void *priv)
 {
struct sunxi_priv_data *gmac = priv;
 
-   if (gmac->variant->soc_has_internal_phy) {
-   if (gmac->internal_phy_powered)
-   sun8i_dwmac_unpower_internal_phy(gmac);
-   }
+   if (gmac->variant->soc_has_internal_phy)
+   sun8i_dwmac_unpower_internal_phy(gmac);
 
clk_disable_unprepare(gmac->tx_clk);
 
-- 
2.26.2



[RFC PATCH v5 9/9] cxl/mem: Add payload dumping for debug

2021-02-16 Thread Ben Widawsky
It's often useful in debug scenarios to see what the hardware has dumped
out. As it stands today, any device error will result in the payload not
being copied out, so there is no way to triage commands which weren't
expected to fail (and sometimes the payload may have that information).

The functionality is protected by normal kernel security mechanisms as
well as a CONFIG option in the CXL driver.

This was extracted from the original version of the CXL enabling patch
series.

Signed-off-by: Ben Widawsky 
---
 drivers/cxl/Kconfig | 13 +
 drivers/cxl/mem.c   |  8 
 2 files changed, 21 insertions(+)

diff --git a/drivers/cxl/Kconfig b/drivers/cxl/Kconfig
index 97dc4d751651..3eec9276e586 100644
--- a/drivers/cxl/Kconfig
+++ b/drivers/cxl/Kconfig
@@ -50,4 +50,17 @@ config CXL_MEM_RAW_COMMANDS
  potential impact to memory currently in use by the kernel.
 
  If developing CXL hardware or the driver say Y, otherwise say N.
+
+config CXL_MEM_INSECURE_DEBUG
+   bool "CXL.mem debugging"
+   depends on CXL_MEM
+   help
+ Enable debug of all CXL command payloads.
+
+ Some CXL devices and controllers support encryption and other
+ security features. The payloads for the commands that enable
+ those features may contain sensitive clear-text security
+ material. Disable debug of those command payloads by default.
+ If you are a kernel developer actively working on CXL
+ security enabling say Y, otherwise say N.
 endif
diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
index 6d7d3870b5da..d63c8eaf23c7 100644
--- a/drivers/cxl/mem.c
+++ b/drivers/cxl/mem.c
@@ -346,6 +346,14 @@ static int __cxl_mem_mbox_send_cmd(struct cxl_mem *cxlm,
 
/* #5 */
rc = cxl_mem_wait_for_doorbell(cxlm);
+
+   if (!cxl_is_security_command(mbox_cmd->opcode) ||
+   IS_ENABLED(CONFIG_CXL_MEM_INSECURE_DEBUG)) {
+   print_hex_dump_debug("Payload ", DUMP_PREFIX_OFFSET, 16, 1,
+mbox_cmd->payload_in, mbox_cmd->size_in,
+true);
+   }
+
if (rc == -ETIMEDOUT) {
cxl_mem_mbox_timeout(cxlm, mbox_cmd);
return rc;
-- 
2.30.1



[PATCH] remove unused variable driver_desc

2021-02-16 Thread Sean Behan
---
 drivers/staging/emxx_udc/emxx_udc.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/staging/emxx_udc/emxx_udc.c 
b/drivers/staging/emxx_udc/emxx_udc.c
index 3536c03ff523..741147a4f0fe 100644
--- a/drivers/staging/emxx_udc/emxx_udc.c
+++ b/drivers/staging/emxx_udc/emxx_udc.c
@@ -38,7 +38,6 @@ static struct gpio_desc *vbus_gpio;
 static int vbus_irq;
 
 static const char  driver_name[] = "emxx_udc";
-static const char  driver_desc[] = DRIVER_DESC;
 
 /*===*/
 /* Prototype */
-- 
2.29.2



[PATCH v5 7/9] cxl/mem: Add set of informational commands

2021-02-16 Thread Ben Widawsky
Add initial set of formal commands beyond basic identify and command
enumeration.

Signed-off-by: Ben Widawsky 
Reviewed-by: Dan Williams 
Reviewed-by: Jonathan Cameron  (v2)
---
 drivers/cxl/mem.c| 9 +
 include/uapi/linux/cxl_mem.h | 5 +
 2 files changed, 14 insertions(+)

diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
index e31b3045e231..6d7d3870b5da 100644
--- a/drivers/cxl/mem.c
+++ b/drivers/cxl/mem.c
@@ -45,12 +45,16 @@
 enum opcode {
CXL_MBOX_OP_INVALID = 0x,
CXL_MBOX_OP_RAW = CXL_MBOX_OP_INVALID,
+   CXL_MBOX_OP_GET_FW_INFO = 0x0200,
CXL_MBOX_OP_ACTIVATE_FW = 0x0202,
CXL_MBOX_OP_GET_SUPPORTED_LOGS  = 0x0400,
CXL_MBOX_OP_GET_LOG = 0x0401,
CXL_MBOX_OP_IDENTIFY= 0x4000,
+   CXL_MBOX_OP_GET_PARTITION_INFO  = 0x4100,
CXL_MBOX_OP_SET_PARTITION_INFO  = 0x4101,
+   CXL_MBOX_OP_GET_LSA = 0x4102,
CXL_MBOX_OP_SET_LSA = 0x4103,
+   CXL_MBOX_OP_GET_HEALTH_INFO = 0x4200,
CXL_MBOX_OP_SET_SHUTDOWN_STATE  = 0x4204,
CXL_MBOX_OP_SCAN_MEDIA  = 0x4304,
CXL_MBOX_OP_GET_SCAN_MEDIA  = 0x4305,
@@ -171,6 +175,11 @@ static struct cxl_mem_command mem_commands[] = {
CXL_CMD(RAW, ~0, ~0, 0),
 #endif
CXL_CMD(GET_SUPPORTED_LOGS, 0, ~0, CXL_CMD_FLAG_FORCE_ENABLE),
+   CXL_CMD(GET_FW_INFO, 0, 0x50, 0),
+   CXL_CMD(GET_PARTITION_INFO, 0, 0x20, 0),
+   CXL_CMD(GET_LSA, 0x8, ~0, 0),
+   CXL_CMD(GET_HEALTH_INFO, 0, 0x12, 0),
+   CXL_CMD(GET_LOG, 0x18, ~0, CXL_CMD_FLAG_FORCE_ENABLE),
 };
 
 /*
diff --git a/include/uapi/linux/cxl_mem.h b/include/uapi/linux/cxl_mem.h
index 59227f82a4c1..3155382dfc9b 100644
--- a/include/uapi/linux/cxl_mem.h
+++ b/include/uapi/linux/cxl_mem.h
@@ -24,6 +24,11 @@
___C(IDENTIFY, "Identify Command"),   \
___C(RAW, "Raw device command"),  \
___C(GET_SUPPORTED_LOGS, "Get Supported Logs"),   \
+   ___C(GET_FW_INFO, "Get FW Info"), \
+   ___C(GET_PARTITION_INFO, "Get Partition Information"),\
+   ___C(GET_LSA, "Get Label Storage Area"),  \
+   ___C(GET_HEALTH_INFO, "Get Health Info"), \
+   ___C(GET_LOG, "Get Log"), \
___C(MAX, "invalid / last command")
 
 #define ___C(a, b) CXL_MEM_COMMAND_ID_##a
-- 
2.30.1



[PATCH v5 6/9] cxl/mem: Enable commands via CEL

2021-02-16 Thread Ben Widawsky
CXL devices identified by the memory-device class code must implement
the Device Command Interface (described in 8.2.9 of the CXL 2.0 spec).
While the driver already maintains a list of commands it supports, there
is still a need to be able to distinguish between commands that the
driver knows about from commands that are optionally supported by the
hardware.

The Command Effects Log (CEL) is specified in the CXL 2.0 specification.
The CEL is one of two types of logs, the other being vendor specific.
They are distinguished in hardware/spec via UUID. The CEL is useful for
2 things:
1. Determine which optional commands are supported by the CXL device.
2. Enumerate any vendor specific commands

The CEL is used by the driver to determine which commands are available
in the hardware and therefore which commands userspace is allowed to
execute. The set of enabled commands might be a subset of commands which
are advertised in UAPI via CXL_MEM_SEND_COMMAND IOCTL.

With the CEL enabling comes a internal flag to indicate a base set of
commands that are enabled regardless of CEL. Such commands are required
for basic interaction with the hardware and thus can be useful in debug
cases, for example if the CEL is corrupted.

The implementation leaves the statically defined table of commands and
supplements it with a bitmap to determine commands that are enabled.
This organization was chosen for the following reasons:
- Smaller memory footprint. Doesn't need a table per device.
- Reduce memory allocation complexity.
- Fixed command IDs to opcode mapping for all devices makes development
  and debugging easier.
- Certain helpers are easily achievable, like cxl_for_each_cmd().

Signed-off-by: Ben Widawsky 
Reviewed-by: Dan Williams  (v2)
Reviewed-by: Jonathan Cameron  (v3)
---
 drivers/cxl/cxl.h|   2 +
 drivers/cxl/mem.c| 223 +--
 include/uapi/linux/cxl_mem.h |   1 +
 3 files changed, 219 insertions(+), 7 deletions(-)

diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index 8fd4a177fe25..6f14838c2d25 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -69,6 +69,7 @@ struct cxl_memdev;
  *(CXL 2.0 8.2.8.4.3 Mailbox Capabilities Register)
  * @mbox_mutex: Mutex to synchronize mailbox access.
  * @firmware_version: Firmware version for the memory device.
+ * @enabled_commands: Hardware commands found enabled in CEL.
  * @pmem_range: Persistent memory capacity information.
  * @ram_range: Volatile memory capacity information.
  */
@@ -84,6 +85,7 @@ struct cxl_mem {
size_t payload_size;
struct mutex mbox_mutex; /* Protects device mailbox and firmware */
char firmware_version[0x10];
+   unsigned long *enabled_cmds;
 
struct range pmem_range;
struct range ram_range;
diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
index 5319412e245c..e31b3045e231 100644
--- a/drivers/cxl/mem.c
+++ b/drivers/cxl/mem.c
@@ -46,6 +46,8 @@ enum opcode {
CXL_MBOX_OP_INVALID = 0x,
CXL_MBOX_OP_RAW = CXL_MBOX_OP_INVALID,
CXL_MBOX_OP_ACTIVATE_FW = 0x0202,
+   CXL_MBOX_OP_GET_SUPPORTED_LOGS  = 0x0400,
+   CXL_MBOX_OP_GET_LOG = 0x0401,
CXL_MBOX_OP_IDENTIFY= 0x4000,
CXL_MBOX_OP_SET_PARTITION_INFO  = 0x4101,
CXL_MBOX_OP_SET_LSA = 0x4103,
@@ -108,10 +110,28 @@ static DEFINE_IDA(cxl_memdev_ida);
 static struct dentry *cxl_debugfs;
 static bool cxl_raw_allow_all;
 
+enum {
+   CEL_UUID,
+   VENDOR_DEBUG_UUID,
+};
+
+/* See CXL 2.0 Table 170. Get Log Input Payload */
+static const uuid_t log_uuid[] = {
+   [CEL_UUID] = UUID_INIT(0xda9c0b5, 0xbf41, 0x4b78, 0x8f, 0x79, 0x96,
+  0xb1, 0x62, 0x3b, 0x3f, 0x17),
+   [VENDOR_DEBUG_UUID] = UUID_INIT(0xe1819d9, 0x11a9, 0x400c, 0x81, 0x1f,
+   0xd6, 0x07, 0x19, 0x40, 0x3d, 0x86),
+};
+
 /**
  * struct cxl_mem_command - Driver representation of a memory device command
  * @info: Command information as it exists for the UAPI
  * @opcode: The actual bits used for the mailbox protocol
+ * @flags: Set of flags effecting driver behavior.
+ *
+ *  * %CXL_CMD_FLAG_FORCE_ENABLE: In cases of error, commands with this flag
+ *will be enabled by the driver regardless of what hardware may have
+ *advertised.
  *
  * The cxl_mem_command is the driver's internal representation of commands that
  * are supported by the driver. Some of these commands may not be supported by
@@ -123,9 +143,12 @@ static bool cxl_raw_allow_all;
 struct cxl_mem_command {
struct cxl_command_info info;
enum opcode opcode;
+   u32 flags;
+#define CXL_CMD_FLAG_NONE 0
+#define CXL_CMD_FLAG_FORCE_ENABLE BIT(0)
 };
 
-#define CXL_CMD(_id, sin, sout)
\
+#define CXL_CMD(_id, sin, sout, _flags)
\

[PATCH v5 8/9] MAINTAINERS: Add maintainers of the CXL driver

2021-02-16 Thread Ben Widawsky
Cc: Dan Williams 
Cc: Vishal Verma 
Cc: Ira Weiny 
Cc: Alison Schofield 
Signed-off-by: Ben Widawsky 
---
 MAINTAINERS | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 6eff4f720c72..93c8694a8f04 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -,6 +,17 @@ M:   Miguel Ojeda 
 S: Maintained
 F: include/linux/compiler_attributes.h
 
+COMPUTE EXPRESS LINK (CXL)
+M: Alison Schofield 
+M: Vishal Verma 
+M: Ira Weiny 
+M: Ben Widawsky 
+M: Dan Williams 
+L: linux-...@vger.kernel.org
+S: Maintained
+F: drivers/cxl/
+F: include/uapi/linux/cxl_mem.h
+
 CONEXANT ACCESSRUNNER USB DRIVER
 L: accessrunner-gene...@lists.sourceforge.net
 S: Orphan
-- 
2.30.1



  1   2   3   4   5   6   7   8   9   10   >