Re: [PATCH net v2 1/2] Revert "tuntap: add missing xdp flush"

2018-02-21 Thread Sergei Shtylyov

On 2/22/2018 9:24 AM, Jason Wang wrote:


This reverts commit 762c330d670e3d4b795cf7a8d761866fdd1eef49. The
reason is we try to batch packets for devmap which causes calling
xdp_do_flush() under the process context. Simply disable premmption


   s/under/in/.
   Disabling preemption.


may not work since process may move among processors which lead
xdp_do_flush() to miss some flushes on some processors.

So simply revert the patch, a follow-up path will add the xdp flush
correctly.

Reported-by: Christoffer Dall 
Fixes: 762c330d670e ("tuntap: add missing xdp flush")
Signed-off-by: Jason Wang 

[...]

MBR, Sergei


Re: [PATCH v4 3/4] arm64: dts: sdm845: Add minimal dts/dtsi files for sdm845 SoC and MTP

2018-02-21 Thread Rajendra Nayak


On 02/22/2018 04:53 AM, Doug Anderson wrote:
> Hi,
> 
> On Mon, Feb 19, 2018 at 8:36 AM, Marc Zyngier  wrote:
>>> + interrupts = ;
>>
>> Please do not use IRQ_TYPE_NONE, ever. It doesn't exist in the GIC
>> binding. Set it to the actual trigger value.
>>
> 
>>> + interrupts = ;
>>
>> Same here.
> 
> Thanks for the review Marc!
> 
> 
> Andy: If I'm reading everything correctly you're the one who would
> collect these patches and apply them.  Is that right?  Do they look OK
> to you in general?  Would you prefer that Rajendra send out a v5 with
> the fixes pointed out by Marc, or would you prefer to fix them up
> yourself when applying?  Is now a good time or would you prefer to
> wait?

I just fixed up to remove all instances of IRQ_TYPE_NONE and sent a v5 out.

> 
> Thanks!  :)
> 
> -Doug
> 
> ___
> linux-arm-kernel mailing list
> linux-arm-ker...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

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


Re: [PATCH net v2 1/2] Revert "tuntap: add missing xdp flush"

2018-02-21 Thread Sergei Shtylyov

On 2/22/2018 9:24 AM, Jason Wang wrote:


This reverts commit 762c330d670e3d4b795cf7a8d761866fdd1eef49. The
reason is we try to batch packets for devmap which causes calling
xdp_do_flush() under the process context. Simply disable premmption


   s/under/in/.
   Disabling preemption.


may not work since process may move among processors which lead
xdp_do_flush() to miss some flushes on some processors.

So simply revert the patch, a follow-up path will add the xdp flush
correctly.

Reported-by: Christoffer Dall 
Fixes: 762c330d670e ("tuntap: add missing xdp flush")
Signed-off-by: Jason Wang 

[...]

MBR, Sergei


Re: [PATCH v4 3/4] arm64: dts: sdm845: Add minimal dts/dtsi files for sdm845 SoC and MTP

2018-02-21 Thread Rajendra Nayak


On 02/22/2018 04:53 AM, Doug Anderson wrote:
> Hi,
> 
> On Mon, Feb 19, 2018 at 8:36 AM, Marc Zyngier  wrote:
>>> + interrupts = ;
>>
>> Please do not use IRQ_TYPE_NONE, ever. It doesn't exist in the GIC
>> binding. Set it to the actual trigger value.
>>
> 
>>> + interrupts = ;
>>
>> Same here.
> 
> Thanks for the review Marc!
> 
> 
> Andy: If I'm reading everything correctly you're the one who would
> collect these patches and apply them.  Is that right?  Do they look OK
> to you in general?  Would you prefer that Rajendra send out a v5 with
> the fixes pointed out by Marc, or would you prefer to fix them up
> yourself when applying?  Is now a good time or would you prefer to
> wait?

I just fixed up to remove all instances of IRQ_TYPE_NONE and sent a v5 out.

> 
> Thanks!  :)
> 
> -Doug
> 
> ___
> linux-arm-kernel mailing list
> linux-arm-ker...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

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


Re: [PATCH 08/20] lightnvm: complete geo structure with maxoc*

2018-02-21 Thread Javier Gonzalez
> On 22 Feb 2018, at 08.45, Matias Bjørling  wrote:
> 
> On 02/21/2018 10:26 AM, Javier González wrote:
>> Complete the generic geometry structure with the maxoc and maxocpu
>> felds, present in the 2.0 spec.
>> Signed-off-by: Javier González 
>> ---
>>  drivers/nvme/host/lightnvm.c | 4 
>>  include/linux/lightnvm.h | 2 ++
>>  2 files changed, 6 insertions(+)
>> diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
>> index cca32da05316..9c1f8225c4e1 100644
>> --- a/drivers/nvme/host/lightnvm.c
>> +++ b/drivers/nvme/host/lightnvm.c
>> @@ -318,6 +318,8 @@ static int nvme_nvm_setup_12(struct nvme_nvm_id12 *id,
>>  dev_geo->c.ws_min = sec_per_pg;
>>  dev_geo->c.ws_opt = sec_per_pg;
>>  dev_geo->c.mw_cunits = 8;   /* default to MLC safe values */
>> +dev_geo->c.maxoc = dev_geo->all_luns;   /* default to 1 chunk per LUN */
>> +dev_geo->c.maxocpu = 1; /* default to 1 chunk per LUN */
> 
> One can't assume that it is 1 open chunk per lun. If you need this for 
> specific hardware, make a quirk for it.
> 

Which default you want for 1.2 if not specified then? I use 1 because it
has been the implicit default until now.

Javier


signature.asc
Description: Message signed with OpenPGP


Re: [PATCH 08/20] lightnvm: complete geo structure with maxoc*

2018-02-21 Thread Javier Gonzalez
> On 22 Feb 2018, at 08.45, Matias Bjørling  wrote:
> 
> On 02/21/2018 10:26 AM, Javier González wrote:
>> Complete the generic geometry structure with the maxoc and maxocpu
>> felds, present in the 2.0 spec.
>> Signed-off-by: Javier González 
>> ---
>>  drivers/nvme/host/lightnvm.c | 4 
>>  include/linux/lightnvm.h | 2 ++
>>  2 files changed, 6 insertions(+)
>> diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
>> index cca32da05316..9c1f8225c4e1 100644
>> --- a/drivers/nvme/host/lightnvm.c
>> +++ b/drivers/nvme/host/lightnvm.c
>> @@ -318,6 +318,8 @@ static int nvme_nvm_setup_12(struct nvme_nvm_id12 *id,
>>  dev_geo->c.ws_min = sec_per_pg;
>>  dev_geo->c.ws_opt = sec_per_pg;
>>  dev_geo->c.mw_cunits = 8;   /* default to MLC safe values */
>> +dev_geo->c.maxoc = dev_geo->all_luns;   /* default to 1 chunk per LUN */
>> +dev_geo->c.maxocpu = 1; /* default to 1 chunk per LUN */
> 
> One can't assume that it is 1 open chunk per lun. If you need this for 
> specific hardware, make a quirk for it.
> 

Which default you want for 1.2 if not specified then? I use 1 because it
has been the implicit default until now.

Javier


signature.asc
Description: Message signed with OpenPGP


Re: [PATCH 04/20] lightnvm: add minor version to generic geometry

2018-02-21 Thread Javier González
> On 22 Feb 2018, at 08.34, Matias Bjørling  wrote:
> 
> On 02/21/2018 10:26 AM, Javier González wrote:
>> Separate the version between major and minor on the generic geometry.
>> Also, add a "subversion" entry to sysfs to expose the minor version
>> without breaking user space.
>> Signed-off-by: Javier González 
>> ---
>>  drivers/lightnvm/core.c  |  4 ++--
>>  drivers/nvme/host/lightnvm.c | 25 -
>>  include/linux/lightnvm.h |  3 ++-
>>  3 files changed, 24 insertions(+), 8 deletions(-)
>> diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
>> index 42596afdf64c..dc9ec6baff45 100644
>> --- a/drivers/lightnvm/core.c
>> +++ b/drivers/lightnvm/core.c
>> @@ -897,8 +897,8 @@ static int nvm_init(struct nvm_dev *dev)
>>  goto err;
>>  }
>>  -   pr_debug("nvm: ver:%u nvm_vendor:%x\n",
>> -dev_geo->ver_id,
>> +pr_debug("nvm: ver:%u.%u nvm_vendor:%x\n",
>> +dev_geo->major_ver_id, dev_geo->minor_ver_id,
>>  dev_geo->c.vmnt);
>>  ret = nvm_core_init(dev);
>> diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
>> index 598abba66f52..71b4ac57a668 100644
>> --- a/drivers/nvme/host/lightnvm.c
>> +++ b/drivers/nvme/host/lightnvm.c
>> @@ -296,7 +296,8 @@ static int nvme_nvm_setup_12(struct nvme_nvm_id12 *id,
>>  }
>>  /* 1.2 spec. only reports a single version id - unfold */
>> -dev_geo->ver_id = id->ver_id;
>> +dev_geo->major_ver_id = id->ver_id;
>> +dev_geo->minor_ver_id = 2;
>>  dev_geo->nr_chnls = src->num_ch;
>>  dev_geo->nr_luns = src->num_lun;
>> @@ -377,7 +378,14 @@ static void nvme_nvm_set_addr_20(struct nvm_addr_format 
>> *dst,
>>  static int nvme_nvm_setup_20(struct nvme_nvm_id20 *id,
>>   struct nvm_dev_geo *dev_geo)
>>  {
>> -dev_geo->ver_id = id->mjr;
>> +dev_geo->major_ver_id = id->mjr;
>> +dev_geo->minor_ver_id = id->mnr;
>> +
>> +if (!(dev_geo->major_ver_id == 2 && dev_geo->minor_ver_id == 0)) {
>> +pr_err("nvm: OCSSD version not supported (v%d.%d)\n",
>> +dev_geo->major_ver_id, dev_geo->minor_ver_id);
>> +return -EINVAL;
>> +}
>>  dev_geo->nr_chnls = le16_to_cpu(id->num_grp);
>>  dev_geo->nr_luns = le16_to_cpu(id->num_pu);
>> @@ -913,7 +921,11 @@ static ssize_t nvm_dev_attr_show(struct device *dev,
>>  attr = >attr;
>>  if (strcmp(attr->name, "version") == 0) {
>> -return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->ver_id);
>> +return scnprintf(page, PAGE_SIZE, "%u\n",
>> +dev_geo->major_ver_id);
>> +} else if (strcmp(attr->name, "subversion") == 0) {
>> +return scnprintf(page, PAGE_SIZE, "%u\n",
>> +dev_geo->minor_ver_id);
>>  } else if (strcmp(attr->name, "media_capabilities") == 0) {
>>  return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->c.mccap);
>>  } else if (strcmp(attr->name, "read_typ") == 0) {
>> @@ -1055,6 +1067,7 @@ static ssize_t nvm_dev_attr_show_20(struct device *dev,
>>/* general attributes */
>>  static NVM_DEV_ATTR_RO(version);
>> +static NVM_DEV_ATTR_RO(subversion);
>>  static NVM_DEV_ATTR_RO(media_capabilities);
>>static NVM_DEV_ATTR_RO(read_typ);
>> @@ -1085,6 +1098,7 @@ static NVM_DEV_ATTR_12_RO(max_phys_secs);
>>static struct attribute *nvm_dev_attrs_12[] = {
>>  _attr_version.attr,
>> +_attr_subversion.attr,
>>  _attr_media_capabilities.attr,
>>  _attr_vendor_opcode.attr,
>> @@ -1134,6 +1148,7 @@ static NVM_DEV_ATTR_20_RO(reset_max);
>>static struct attribute *nvm_dev_attrs_20[] = {
>>  _attr_version.attr,
>> +_attr_subversion.attr,
>>  _attr_media_capabilities.attr,
>>  _attr_groups.attr,
>> @@ -1167,7 +1182,7 @@ int nvme_nvm_register_sysfs(struct nvme_ns *ns)
>>  if (!ndev)
>>  return -EINVAL;
>>  -   switch (dev_geo->ver_id) {
>> +switch (dev_geo->major_ver_id) {
>>  case 1:
>>  return sysfs_create_group(_to_dev(ns->disk)->kobj,
>>  _dev_attr_group_12);
>> @@ -1184,7 +1199,7 @@ void nvme_nvm_unregister_sysfs(struct nvme_ns *ns)
>>  struct nvm_dev *ndev = ns->ndev;
>>  struct nvm_dev_geo *dev_geo = >dev_geo;
>>  -   switch (dev_geo->ver_id) {
>> +switch (dev_geo->major_ver_id) {
>>  case 1:
>>  sysfs_remove_group(_to_dev(ns->disk)->kobj,
>>  _dev_attr_group_12);
>> diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h
>> index 18e3751b1632..5af0b8837095 100644
>> --- a/include/linux/lightnvm.h
>> +++ b/include/linux/lightnvm.h
>> @@ -242,7 +242,8 @@ struct nvm_common_geo {
>>  /* Device identified geometry */
>>  struct nvm_dev_geo {
>>  /* device reported version */
>> -u8  ver_id;
>> 

Re: [PATCH net v2 2/2] tuntap: correctly add the missing xdp flush

2018-02-21 Thread Sergei Shtylyov

Hello!

On 2/22/2018 9:24 AM, Jason Wang wrote:


Commit 762c330d670e ("tuntap: add missing xdp flush") tries to fix the
devmap stall caused by missed xdp flush by counting the pending xdp
redirected packets and flush when it exceeds NAPI_POLL_WEIGHT or
MSG_MORE is clear. This may lead BUG() since xdp_do_flush() was


   Lead to BUG().


called under process context with preemption enabled. Simply disable


   s/under/in the/?


preemption may silent the warning but be not enough since process may


   Silence.


move between different CPUS during a batch which cause xdp_do_flush()
misses some CPU where the process run previously. Consider the several
fallouts, that commit was reverted. To fix the issue correctly, we can
simply calling xdp_do_flush() immediately after xdp_do_redirect(),


   Call.


a side effect is that this removes any possibility of batching which
could be addressed in the future.

Reported-by: Christoffer Dall 
Fixes: 762c330d670e ("tuntap: add missing xdp flush")
Signed-off-by: Jason Wang 

[...]

MBR, Sergei


Re: [PATCH 04/20] lightnvm: add minor version to generic geometry

2018-02-21 Thread Javier González
> On 22 Feb 2018, at 08.34, Matias Bjørling  wrote:
> 
> On 02/21/2018 10:26 AM, Javier González wrote:
>> Separate the version between major and minor on the generic geometry.
>> Also, add a "subversion" entry to sysfs to expose the minor version
>> without breaking user space.
>> Signed-off-by: Javier González 
>> ---
>>  drivers/lightnvm/core.c  |  4 ++--
>>  drivers/nvme/host/lightnvm.c | 25 -
>>  include/linux/lightnvm.h |  3 ++-
>>  3 files changed, 24 insertions(+), 8 deletions(-)
>> diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
>> index 42596afdf64c..dc9ec6baff45 100644
>> --- a/drivers/lightnvm/core.c
>> +++ b/drivers/lightnvm/core.c
>> @@ -897,8 +897,8 @@ static int nvm_init(struct nvm_dev *dev)
>>  goto err;
>>  }
>>  -   pr_debug("nvm: ver:%u nvm_vendor:%x\n",
>> -dev_geo->ver_id,
>> +pr_debug("nvm: ver:%u.%u nvm_vendor:%x\n",
>> +dev_geo->major_ver_id, dev_geo->minor_ver_id,
>>  dev_geo->c.vmnt);
>>  ret = nvm_core_init(dev);
>> diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
>> index 598abba66f52..71b4ac57a668 100644
>> --- a/drivers/nvme/host/lightnvm.c
>> +++ b/drivers/nvme/host/lightnvm.c
>> @@ -296,7 +296,8 @@ static int nvme_nvm_setup_12(struct nvme_nvm_id12 *id,
>>  }
>>  /* 1.2 spec. only reports a single version id - unfold */
>> -dev_geo->ver_id = id->ver_id;
>> +dev_geo->major_ver_id = id->ver_id;
>> +dev_geo->minor_ver_id = 2;
>>  dev_geo->nr_chnls = src->num_ch;
>>  dev_geo->nr_luns = src->num_lun;
>> @@ -377,7 +378,14 @@ static void nvme_nvm_set_addr_20(struct nvm_addr_format 
>> *dst,
>>  static int nvme_nvm_setup_20(struct nvme_nvm_id20 *id,
>>   struct nvm_dev_geo *dev_geo)
>>  {
>> -dev_geo->ver_id = id->mjr;
>> +dev_geo->major_ver_id = id->mjr;
>> +dev_geo->minor_ver_id = id->mnr;
>> +
>> +if (!(dev_geo->major_ver_id == 2 && dev_geo->minor_ver_id == 0)) {
>> +pr_err("nvm: OCSSD version not supported (v%d.%d)\n",
>> +dev_geo->major_ver_id, dev_geo->minor_ver_id);
>> +return -EINVAL;
>> +}
>>  dev_geo->nr_chnls = le16_to_cpu(id->num_grp);
>>  dev_geo->nr_luns = le16_to_cpu(id->num_pu);
>> @@ -913,7 +921,11 @@ static ssize_t nvm_dev_attr_show(struct device *dev,
>>  attr = >attr;
>>  if (strcmp(attr->name, "version") == 0) {
>> -return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->ver_id);
>> +return scnprintf(page, PAGE_SIZE, "%u\n",
>> +dev_geo->major_ver_id);
>> +} else if (strcmp(attr->name, "subversion") == 0) {
>> +return scnprintf(page, PAGE_SIZE, "%u\n",
>> +dev_geo->minor_ver_id);
>>  } else if (strcmp(attr->name, "media_capabilities") == 0) {
>>  return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->c.mccap);
>>  } else if (strcmp(attr->name, "read_typ") == 0) {
>> @@ -1055,6 +1067,7 @@ static ssize_t nvm_dev_attr_show_20(struct device *dev,
>>/* general attributes */
>>  static NVM_DEV_ATTR_RO(version);
>> +static NVM_DEV_ATTR_RO(subversion);
>>  static NVM_DEV_ATTR_RO(media_capabilities);
>>static NVM_DEV_ATTR_RO(read_typ);
>> @@ -1085,6 +1098,7 @@ static NVM_DEV_ATTR_12_RO(max_phys_secs);
>>static struct attribute *nvm_dev_attrs_12[] = {
>>  _attr_version.attr,
>> +_attr_subversion.attr,
>>  _attr_media_capabilities.attr,
>>  _attr_vendor_opcode.attr,
>> @@ -1134,6 +1148,7 @@ static NVM_DEV_ATTR_20_RO(reset_max);
>>static struct attribute *nvm_dev_attrs_20[] = {
>>  _attr_version.attr,
>> +_attr_subversion.attr,
>>  _attr_media_capabilities.attr,
>>  _attr_groups.attr,
>> @@ -1167,7 +1182,7 @@ int nvme_nvm_register_sysfs(struct nvme_ns *ns)
>>  if (!ndev)
>>  return -EINVAL;
>>  -   switch (dev_geo->ver_id) {
>> +switch (dev_geo->major_ver_id) {
>>  case 1:
>>  return sysfs_create_group(_to_dev(ns->disk)->kobj,
>>  _dev_attr_group_12);
>> @@ -1184,7 +1199,7 @@ void nvme_nvm_unregister_sysfs(struct nvme_ns *ns)
>>  struct nvm_dev *ndev = ns->ndev;
>>  struct nvm_dev_geo *dev_geo = >dev_geo;
>>  -   switch (dev_geo->ver_id) {
>> +switch (dev_geo->major_ver_id) {
>>  case 1:
>>  sysfs_remove_group(_to_dev(ns->disk)->kobj,
>>  _dev_attr_group_12);
>> diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h
>> index 18e3751b1632..5af0b8837095 100644
>> --- a/include/linux/lightnvm.h
>> +++ b/include/linux/lightnvm.h
>> @@ -242,7 +242,8 @@ struct nvm_common_geo {
>>  /* Device identified geometry */
>>  struct nvm_dev_geo {
>>  /* device reported version */
>> -u8  ver_id;
>> +u8  major_ver_id;
>> +u8  

Re: [PATCH net v2 2/2] tuntap: correctly add the missing xdp flush

2018-02-21 Thread Sergei Shtylyov

Hello!

On 2/22/2018 9:24 AM, Jason Wang wrote:


Commit 762c330d670e ("tuntap: add missing xdp flush") tries to fix the
devmap stall caused by missed xdp flush by counting the pending xdp
redirected packets and flush when it exceeds NAPI_POLL_WEIGHT or
MSG_MORE is clear. This may lead BUG() since xdp_do_flush() was


   Lead to BUG().


called under process context with preemption enabled. Simply disable


   s/under/in the/?


preemption may silent the warning but be not enough since process may


   Silence.


move between different CPUS during a batch which cause xdp_do_flush()
misses some CPU where the process run previously. Consider the several
fallouts, that commit was reverted. To fix the issue correctly, we can
simply calling xdp_do_flush() immediately after xdp_do_redirect(),


   Call.


a side effect is that this removes any possibility of batching which
could be addressed in the future.

Reported-by: Christoffer Dall 
Fixes: 762c330d670e ("tuntap: add missing xdp flush")
Signed-off-by: Jason Wang 

[...]

MBR, Sergei


Re: [PATCH v2] iio:dummy: Replace S_IWUSR by 0200

2018-02-21 Thread Daniel Baluta
Hi Dan,

On Jo, 2018-02-22 at 10:43 +0300, Dan Carpenter wrote:
> On Wed, Feb 21, 2018 at 11:01:50PM +0200, Daniel Baluta wrote:
> > 
> > On Wed, Feb 21, 2018 at 9:28 PM, Rodrigo Siqueira
> >  wrote:
> > > 
> > > This patch fixes the checkpatch.pl warning:
> > > 
> > > drivers/iio/dummy/iio_dummy_evgen.c:151: WARNING: Symbolic permissions
> > > 'S_IWUSR' are not preferred. Consider using octal permissions '0200'.
> > > 
> > > ... Why this "..." :)?
> > Commit subject could be done better. It is pretty obvious from the code that
> > we change S_IWUSR with 0200.
> > 
> > Better message:
> > 
> > iio:dummy: Fix poke_evN file permissions
> Please stop telling people to say "Fix" when it's not a bug fix...
> 

I agree with you that here "Fix" is an overstatement.

> Also who cares?  The commit message is perfectly clear.

I do care about newcomers really learning on how to write a proper
commit message.

The commit messsage should really say why the patch is needed, no what the 
patch does.

After several trivial patches newcomers will get into more serious stuff and I 
wouldn't
want to see a patch with commit message like this:

iio: Change bit 1 of status register

but one that looks like this:

iio: Set power up on chip probe

thanks,
Daniel.




Re: [PATCH v2] iio:dummy: Replace S_IWUSR by 0200

2018-02-21 Thread Daniel Baluta
Hi Dan,

On Jo, 2018-02-22 at 10:43 +0300, Dan Carpenter wrote:
> On Wed, Feb 21, 2018 at 11:01:50PM +0200, Daniel Baluta wrote:
> > 
> > On Wed, Feb 21, 2018 at 9:28 PM, Rodrigo Siqueira
> >  wrote:
> > > 
> > > This patch fixes the checkpatch.pl warning:
> > > 
> > > drivers/iio/dummy/iio_dummy_evgen.c:151: WARNING: Symbolic permissions
> > > 'S_IWUSR' are not preferred. Consider using octal permissions '0200'.
> > > 
> > > ... Why this "..." :)?
> > Commit subject could be done better. It is pretty obvious from the code that
> > we change S_IWUSR with 0200.
> > 
> > Better message:
> > 
> > iio:dummy: Fix poke_evN file permissions
> Please stop telling people to say "Fix" when it's not a bug fix...
> 

I agree with you that here "Fix" is an overstatement.

> Also who cares?  The commit message is perfectly clear.

I do care about newcomers really learning on how to write a proper
commit message.

The commit messsage should really say why the patch is needed, no what the 
patch does.

After several trivial patches newcomers will get into more serious stuff and I 
wouldn't
want to see a patch with commit message like this:

iio: Change bit 1 of status register

but one that looks like this:

iio: Set power up on chip probe

thanks,
Daniel.




Re: [PATCH 09/20] lightnvm: use generic identify structure

2018-02-21 Thread Javier González
> On 22 Feb 2018, at 08.47, Matias Bjørling  wrote:
> 
> On 02/21/2018 10:26 AM, Javier González wrote:
>> Create a generic identify structure to collect the identify information
>> before knowing the spec. version. This forces different version paths to
>> cast the structure to their spec structure, thus making the code less
>> error prone and more maintainable.
>> Signed-off-by: Javier González 
>> ---
>>  drivers/nvme/host/lightnvm.c | 32 
>>  1 file changed, 20 insertions(+), 12 deletions(-)
>> diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
>> index 9c1f8225c4e1..70dc4740f0d3 100644
>> --- a/drivers/nvme/host/lightnvm.c
>> +++ b/drivers/nvme/host/lightnvm.c
>> @@ -170,6 +170,12 @@ struct nvme_nvm_id12 {
>>  __u8resv2[2880];
>>  } __packed;
>>  +/* Generic identification structure */
>> +struct nvme_nvm_id {
>> +__u8ver_id;
>> +__u8resv[4095];
>> +} __packed;
>> +
>>  struct nvme_nvm_bb_tbl {
>>  __u8tblid[4];
>>  __le16  verid;
>> @@ -279,9 +285,10 @@ static void nvme_nvm_set_addr_12(struct 
>> nvm_addr_format_12 *dst,
>>  dst->sec_mask = ((1ULL << dst->sec_len) - 1) << dst->sec_offset;
>>  }
>>  -static int nvme_nvm_setup_12(struct nvme_nvm_id12 *id,
>> +static int nvme_nvm_setup_12(struct nvme_nvm_id *gen_id,
>>   struct nvm_dev_geo *dev_geo)
>>  {
>> +struct nvme_nvm_id12 *id = (struct nvme_nvm_id12 *)gen_id;
>>  struct nvme_nvm_id12_grp *src;
>>  int sec_per_pg, sec_per_pl, pg_per_blk;
>>  @@ -380,9 +387,11 @@ static void nvme_nvm_set_addr_20(struct 
>> nvm_addr_format *dst,
>>  dst->sec_mask = ((1ULL << dst->sec_len) - 1) << dst->sec_offset;
>>  }
>>  -static int nvme_nvm_setup_20(struct nvme_nvm_id20 *id,
>> +static int nvme_nvm_setup_20(struct nvme_nvm_id *gen_id,
>>   struct nvm_dev_geo *dev_geo)
>>  {
>> +struct nvme_nvm_id20 *id = (struct nvme_nvm_id20 *)gen_id;
>> +
>>  dev_geo->major_ver_id = id->mjr;
>>  dev_geo->minor_ver_id = id->mnr;
>>  @@ -427,19 +436,19 @@ static int nvme_nvm_setup_20(struct nvme_nvm_id20 *id,
>>  static int nvme_nvm_identity(struct nvm_dev *nvmdev)
>>  {
>>  struct nvme_ns *ns = nvmdev->q->queuedata;
>> -struct nvme_nvm_id12 *id;
>> +struct nvme_nvm_id *nvme_nvm_id;
>>  struct nvme_nvm_command c = {};
>>  int ret;
>>  c.identity.opcode = nvme_nvm_admin_identity;
>>  c.identity.nsid = cpu_to_le32(ns->head->ns_id);
>>  -   id = kmalloc(sizeof(struct nvme_nvm_id12), GFP_KERNEL);
>> -if (!id)
>> +nvme_nvm_id = kmalloc(sizeof(struct nvme_nvm_id), GFP_KERNEL);
>> +if (!nvme_nvm_id)
>>  return -ENOMEM;
>>  ret = nvme_submit_sync_cmd(ns->ctrl->admin_q, (struct nvme_command *),
>> -id, sizeof(struct nvme_nvm_id12));
>> +nvme_nvm_id, sizeof(struct nvme_nvm_id));
>>  if (ret) {
>>  ret = -EIO;
>>  goto out;
>> @@ -449,22 +458,21 @@ static int nvme_nvm_identity(struct nvm_dev *nvmdev)
>>   * The 1.2 and 2.0 specifications share the first byte in their geometry
>>   * command to make it possible to know what version a device implements.
>>   */
>> -switch (id->ver_id) {
>> +switch (nvme_nvm_id->ver_id) {
>>  case 1:
>> -ret = nvme_nvm_setup_12(id, >dev_geo);
>> +ret = nvme_nvm_setup_12(nvme_nvm_id, >dev_geo);
>>  break;
>>  case 2:
>> -ret = nvme_nvm_setup_20((struct nvme_nvm_id20 *)id,
>> ->dev_geo);
>> +ret = nvme_nvm_setup_20(nvme_nvm_id, >dev_geo);
>>  break;
>>  default:
>>  dev_err(ns->ctrl->device, "OCSSD revision not supported (%d)\n",
>> -id->ver_id);
>> +nvme_nvm_id->ver_id);
>>  ret = -EINVAL;
>>  }
>>out:
>> -kfree(id);
>> +kfree(nvme_nvm_id);
>>  return ret;
>>  }
>> 
> 
> Thanks for another way to represent it. I want to keep the original
> path. If we are going that down road, then one should maybe look into
> unifying the "three" data structures, and have the version as the base
> property and the others in each their sub data structure.

That's what this structure aims to do, since the version is shared. But
you call if you want to cast unrelated structures back an forth. I'll
revert it...

Javier


signature.asc
Description: Message signed with OpenPGP


Re: [PATCH 09/20] lightnvm: use generic identify structure

2018-02-21 Thread Javier González
> On 22 Feb 2018, at 08.47, Matias Bjørling  wrote:
> 
> On 02/21/2018 10:26 AM, Javier González wrote:
>> Create a generic identify structure to collect the identify information
>> before knowing the spec. version. This forces different version paths to
>> cast the structure to their spec structure, thus making the code less
>> error prone and more maintainable.
>> Signed-off-by: Javier González 
>> ---
>>  drivers/nvme/host/lightnvm.c | 32 
>>  1 file changed, 20 insertions(+), 12 deletions(-)
>> diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
>> index 9c1f8225c4e1..70dc4740f0d3 100644
>> --- a/drivers/nvme/host/lightnvm.c
>> +++ b/drivers/nvme/host/lightnvm.c
>> @@ -170,6 +170,12 @@ struct nvme_nvm_id12 {
>>  __u8resv2[2880];
>>  } __packed;
>>  +/* Generic identification structure */
>> +struct nvme_nvm_id {
>> +__u8ver_id;
>> +__u8resv[4095];
>> +} __packed;
>> +
>>  struct nvme_nvm_bb_tbl {
>>  __u8tblid[4];
>>  __le16  verid;
>> @@ -279,9 +285,10 @@ static void nvme_nvm_set_addr_12(struct 
>> nvm_addr_format_12 *dst,
>>  dst->sec_mask = ((1ULL << dst->sec_len) - 1) << dst->sec_offset;
>>  }
>>  -static int nvme_nvm_setup_12(struct nvme_nvm_id12 *id,
>> +static int nvme_nvm_setup_12(struct nvme_nvm_id *gen_id,
>>   struct nvm_dev_geo *dev_geo)
>>  {
>> +struct nvme_nvm_id12 *id = (struct nvme_nvm_id12 *)gen_id;
>>  struct nvme_nvm_id12_grp *src;
>>  int sec_per_pg, sec_per_pl, pg_per_blk;
>>  @@ -380,9 +387,11 @@ static void nvme_nvm_set_addr_20(struct 
>> nvm_addr_format *dst,
>>  dst->sec_mask = ((1ULL << dst->sec_len) - 1) << dst->sec_offset;
>>  }
>>  -static int nvme_nvm_setup_20(struct nvme_nvm_id20 *id,
>> +static int nvme_nvm_setup_20(struct nvme_nvm_id *gen_id,
>>   struct nvm_dev_geo *dev_geo)
>>  {
>> +struct nvme_nvm_id20 *id = (struct nvme_nvm_id20 *)gen_id;
>> +
>>  dev_geo->major_ver_id = id->mjr;
>>  dev_geo->minor_ver_id = id->mnr;
>>  @@ -427,19 +436,19 @@ static int nvme_nvm_setup_20(struct nvme_nvm_id20 *id,
>>  static int nvme_nvm_identity(struct nvm_dev *nvmdev)
>>  {
>>  struct nvme_ns *ns = nvmdev->q->queuedata;
>> -struct nvme_nvm_id12 *id;
>> +struct nvme_nvm_id *nvme_nvm_id;
>>  struct nvme_nvm_command c = {};
>>  int ret;
>>  c.identity.opcode = nvme_nvm_admin_identity;
>>  c.identity.nsid = cpu_to_le32(ns->head->ns_id);
>>  -   id = kmalloc(sizeof(struct nvme_nvm_id12), GFP_KERNEL);
>> -if (!id)
>> +nvme_nvm_id = kmalloc(sizeof(struct nvme_nvm_id), GFP_KERNEL);
>> +if (!nvme_nvm_id)
>>  return -ENOMEM;
>>  ret = nvme_submit_sync_cmd(ns->ctrl->admin_q, (struct nvme_command *),
>> -id, sizeof(struct nvme_nvm_id12));
>> +nvme_nvm_id, sizeof(struct nvme_nvm_id));
>>  if (ret) {
>>  ret = -EIO;
>>  goto out;
>> @@ -449,22 +458,21 @@ static int nvme_nvm_identity(struct nvm_dev *nvmdev)
>>   * The 1.2 and 2.0 specifications share the first byte in their geometry
>>   * command to make it possible to know what version a device implements.
>>   */
>> -switch (id->ver_id) {
>> +switch (nvme_nvm_id->ver_id) {
>>  case 1:
>> -ret = nvme_nvm_setup_12(id, >dev_geo);
>> +ret = nvme_nvm_setup_12(nvme_nvm_id, >dev_geo);
>>  break;
>>  case 2:
>> -ret = nvme_nvm_setup_20((struct nvme_nvm_id20 *)id,
>> ->dev_geo);
>> +ret = nvme_nvm_setup_20(nvme_nvm_id, >dev_geo);
>>  break;
>>  default:
>>  dev_err(ns->ctrl->device, "OCSSD revision not supported (%d)\n",
>> -id->ver_id);
>> +nvme_nvm_id->ver_id);
>>  ret = -EINVAL;
>>  }
>>out:
>> -kfree(id);
>> +kfree(nvme_nvm_id);
>>  return ret;
>>  }
>> 
> 
> Thanks for another way to represent it. I want to keep the original
> path. If we are going that down road, then one should maybe look into
> unifying the "three" data structures, and have the version as the base
> property and the others in each their sub data structure.

That's what this structure aims to do, since the version is shared. But
you call if you want to cast unrelated structures back an forth. I'll
revert it...

Javier


signature.asc
Description: Message signed with OpenPGP


[PATCH v9 3/7] PCI/ERR: add mutex to synchronize recovery

2018-02-21 Thread Oza Pawandeep
This patch protects pci_do_recovery with mutex.

Signed-off-by: Oza Pawandeep 

diff --git a/drivers/pci/pcie/pcie-err.c b/drivers/pci/pcie/pcie-err.c
index a532fe0..8318c84 100644
--- a/drivers/pci/pcie/pcie-err.c
+++ b/drivers/pci/pcie/pcie-err.c
@@ -20,6 +20,8 @@
 #include 
 #include "portdrv.h"
 
+static DEFINE_MUTEX(pci_err_recovery_lock);
+
 struct aer_broadcast_data {
enum pci_channel_state state;
enum pci_ers_result result;
@@ -283,6 +285,8 @@ void pci_do_recovery(struct pci_dev *dev, int severity)
pci_ers_result_t status, result = PCI_ERS_RESULT_RECOVERED;
enum pci_channel_state state;
 
+   mutex_lock(_err_recovery_lock);
+
if (severity == AER_FATAL)
state = pci_channel_io_frozen;
else
@@ -326,9 +330,11 @@ void pci_do_recovery(struct pci_dev *dev, int severity)
report_resume);
 
dev_info(>dev, "Device recovery successful\n");
+   mutex_unlock(_err_recovery_lock);
return;
 
 failed:
/* TODO: Should kernel panic here? */
dev_info(>dev, "Device recovery failed\n");
+   mutex_unlock(_err_recovery_lock);
 }
-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm 
Technologies, Inc.,
a Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux 
Foundation Collaborative Project.



[PATCH v9 2/7] PCI/AER: factor out error reporting from AER

2018-02-21 Thread Oza Pawandeep
This patch factors out error reporting callbacks, which are currently
tightly coupled with AER.
DPC should be able to register callbacks and attmept recovery when DPC
trigger event occurs.

Signed-off-by: Oza Pawandeep 

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index fcd8191..a5a79f0 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -342,6 +342,9 @@ static inline resource_size_t pci_resource_alignment(struct 
pci_dev *dev,
 
 void pci_enable_acs(struct pci_dev *dev);
 
+/* PCI error reporting and recovery */
+void pci_do_recovery(struct pci_dev *dev, int severity);
+
 #ifdef CONFIG_PCIEASPM
 void pcie_aspm_init_link_state(struct pci_dev *pdev);
 void pcie_aspm_exit_link_state(struct pci_dev *pdev);
diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile
index 223e4c3..d669497 100644
--- a/drivers/pci/pcie/Makefile
+++ b/drivers/pci/pcie/Makefile
@@ -6,7 +6,7 @@
 # Build PCI Express ASPM if needed
 obj-$(CONFIG_PCIEASPM) += aspm.o
 
-pcieportdrv-y  := portdrv_core.o portdrv_pci.o portdrv_bus.o
+pcieportdrv-y  := portdrv_core.o portdrv_pci.o portdrv_bus.o 
pcie-err.o
 pcieportdrv-$(CONFIG_ACPI) += portdrv_acpi.o
 
 obj-$(CONFIG_PCIEPORTBUS)  += pcieportdrv.o
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h
index 5449e5c..bc9db53 100644
--- a/drivers/pci/pcie/aer/aerdrv.h
+++ b/drivers/pci/pcie/aer/aerdrv.h
@@ -76,36 +76,6 @@ struct aer_rpc {
 */
 };
 
-struct aer_broadcast_data {
-   enum pci_channel_state state;
-   enum pci_ers_result result;
-};
-
-static inline pci_ers_result_t merge_result(enum pci_ers_result orig,
-   enum pci_ers_result new)
-{
-   if (new == PCI_ERS_RESULT_NO_AER_DRIVER)
-   return PCI_ERS_RESULT_NO_AER_DRIVER;
-
-   if (new == PCI_ERS_RESULT_NONE)
-   return orig;
-
-   switch (orig) {
-   case PCI_ERS_RESULT_CAN_RECOVER:
-   case PCI_ERS_RESULT_RECOVERED:
-   orig = new;
-   break;
-   case PCI_ERS_RESULT_DISCONNECT:
-   if (new == PCI_ERS_RESULT_NEED_RESET)
-   orig = PCI_ERS_RESULT_NEED_RESET;
-   break;
-   default:
-   break;
-   }
-
-   return orig;
-}
-
 extern struct bus_type pcie_port_bus_type;
 void aer_isr(struct work_struct *work);
 void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c 
b/drivers/pci/pcie/aer/aerdrv_core.c
index 306bf2f..410d4b8 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include "aerdrv.h"
+#include "../../pci.h"
 
 #definePCI_EXP_AER_FLAGS   (PCI_EXP_DEVCTL_CERE | 
PCI_EXP_DEVCTL_NFERE | \
 PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE)
@@ -230,191 +231,6 @@ static bool find_source_device(struct pci_dev *parent,
return true;
 }
 
-static int report_error_detected(struct pci_dev *dev, void *data)
-{
-   pci_ers_result_t vote;
-   const struct pci_error_handlers *err_handler;
-   struct aer_broadcast_data *result_data;
-   result_data = (struct aer_broadcast_data *) data;
-
-   device_lock(>dev);
-   dev->error_state = result_data->state;
-
-   if (!dev->driver ||
-   !dev->driver->err_handler ||
-   !dev->driver->err_handler->error_detected) {
-   if (result_data->state == pci_channel_io_frozen &&
-   dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
-   /*
-* In case of fatal recovery, if one of down-
-* stream device has no driver. We might be
-* unable to recover because a later insmod
-* of a driver for this device is unaware of
-* its hw state.
-*/
-   pci_printk(KERN_DEBUG, dev, "device has %s\n",
-  dev->driver ?
-  "no AER-aware driver" : "no driver");
-   }
-
-   /*
-* If there's any device in the subtree that does not
-* have an error_detected callback, returning
-* PCI_ERS_RESULT_NO_AER_DRIVER prevents calling of
-* the subsequent mmio_enabled/slot_reset/resume
-* callbacks of "any" device in the subtree. All the
-* devices in the subtree are left in the error state
-* without recovery.
-*/
-
-   if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE)
-   vote = PCI_ERS_RESULT_NO_AER_DRIVER;
-   else
-   vote = PCI_ERS_RESULT_NONE;
-   } else {
-   err_handler = dev->driver->err_handler;
- 

Re: [PATCH 11/20] lightnvm: pblk: check for supported version

2018-02-21 Thread Matias Bjørling

On 02/21/2018 10:26 AM, Javier González wrote:

At this point, only 1.2 spec is supported, thus check for it. Also,
since device-side L2P is only supported in the 1.2 spec, make sure to
only check its value under 1.2.

Signed-off-by: Javier González 
---
  drivers/lightnvm/pblk-init.c | 10 --
  1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c
index 56b4afc27add..ec39800eea42 100644
--- a/drivers/lightnvm/pblk-init.c
+++ b/drivers/lightnvm/pblk-init.c
@@ -990,9 +990,15 @@ static void *pblk_init(struct nvm_tgt_dev *dev, struct 
gendisk *tdisk,
struct pblk *pblk;
int ret;
  
-	if (dev->geo.c.dom & NVM_RSP_L2P) {

+   if (geo->c.version != NVM_OCSSD_SPEC_12) {
+   pr_err("pblk: OCSSD version not supported (%u)\n",
+   geo->c.version);
+   return ERR_PTR(-EINVAL);
+   }
+
+   if (geo->c.version == NVM_OCSSD_SPEC_12 && geo->c.dom & NVM_RSP_L2P) {
pr_err("pblk: host-side L2P table not supported. (%x)\n",
-   dev->geo.c.dom);
+   geo->c.dom);
return ERR_PTR(-EINVAL);
}
  



Looks good to me. I'll pick up when rebased.


Re: [PATCH 11/20] lightnvm: pblk: check for supported version

2018-02-21 Thread Matias Bjørling

On 02/21/2018 10:26 AM, Javier González wrote:

At this point, only 1.2 spec is supported, thus check for it. Also,
since device-side L2P is only supported in the 1.2 spec, make sure to
only check its value under 1.2.

Signed-off-by: Javier González 
---
  drivers/lightnvm/pblk-init.c | 10 --
  1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c
index 56b4afc27add..ec39800eea42 100644
--- a/drivers/lightnvm/pblk-init.c
+++ b/drivers/lightnvm/pblk-init.c
@@ -990,9 +990,15 @@ static void *pblk_init(struct nvm_tgt_dev *dev, struct 
gendisk *tdisk,
struct pblk *pblk;
int ret;
  
-	if (dev->geo.c.dom & NVM_RSP_L2P) {

+   if (geo->c.version != NVM_OCSSD_SPEC_12) {
+   pr_err("pblk: OCSSD version not supported (%u)\n",
+   geo->c.version);
+   return ERR_PTR(-EINVAL);
+   }
+
+   if (geo->c.version == NVM_OCSSD_SPEC_12 && geo->c.dom & NVM_RSP_L2P) {
pr_err("pblk: host-side L2P table not supported. (%x)\n",
-   dev->geo.c.dom);
+   geo->c.dom);
return ERR_PTR(-EINVAL);
}
  



Looks good to me. I'll pick up when rebased.


[PATCH v9 3/7] PCI/ERR: add mutex to synchronize recovery

2018-02-21 Thread Oza Pawandeep
This patch protects pci_do_recovery with mutex.

Signed-off-by: Oza Pawandeep 

diff --git a/drivers/pci/pcie/pcie-err.c b/drivers/pci/pcie/pcie-err.c
index a532fe0..8318c84 100644
--- a/drivers/pci/pcie/pcie-err.c
+++ b/drivers/pci/pcie/pcie-err.c
@@ -20,6 +20,8 @@
 #include 
 #include "portdrv.h"
 
+static DEFINE_MUTEX(pci_err_recovery_lock);
+
 struct aer_broadcast_data {
enum pci_channel_state state;
enum pci_ers_result result;
@@ -283,6 +285,8 @@ void pci_do_recovery(struct pci_dev *dev, int severity)
pci_ers_result_t status, result = PCI_ERS_RESULT_RECOVERED;
enum pci_channel_state state;
 
+   mutex_lock(_err_recovery_lock);
+
if (severity == AER_FATAL)
state = pci_channel_io_frozen;
else
@@ -326,9 +330,11 @@ void pci_do_recovery(struct pci_dev *dev, int severity)
report_resume);
 
dev_info(>dev, "Device recovery successful\n");
+   mutex_unlock(_err_recovery_lock);
return;
 
 failed:
/* TODO: Should kernel panic here? */
dev_info(>dev, "Device recovery failed\n");
+   mutex_unlock(_err_recovery_lock);
 }
-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm 
Technologies, Inc.,
a Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux 
Foundation Collaborative Project.



[PATCH v9 2/7] PCI/AER: factor out error reporting from AER

2018-02-21 Thread Oza Pawandeep
This patch factors out error reporting callbacks, which are currently
tightly coupled with AER.
DPC should be able to register callbacks and attmept recovery when DPC
trigger event occurs.

Signed-off-by: Oza Pawandeep 

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index fcd8191..a5a79f0 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -342,6 +342,9 @@ static inline resource_size_t pci_resource_alignment(struct 
pci_dev *dev,
 
 void pci_enable_acs(struct pci_dev *dev);
 
+/* PCI error reporting and recovery */
+void pci_do_recovery(struct pci_dev *dev, int severity);
+
 #ifdef CONFIG_PCIEASPM
 void pcie_aspm_init_link_state(struct pci_dev *pdev);
 void pcie_aspm_exit_link_state(struct pci_dev *pdev);
diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile
index 223e4c3..d669497 100644
--- a/drivers/pci/pcie/Makefile
+++ b/drivers/pci/pcie/Makefile
@@ -6,7 +6,7 @@
 # Build PCI Express ASPM if needed
 obj-$(CONFIG_PCIEASPM) += aspm.o
 
-pcieportdrv-y  := portdrv_core.o portdrv_pci.o portdrv_bus.o
+pcieportdrv-y  := portdrv_core.o portdrv_pci.o portdrv_bus.o 
pcie-err.o
 pcieportdrv-$(CONFIG_ACPI) += portdrv_acpi.o
 
 obj-$(CONFIG_PCIEPORTBUS)  += pcieportdrv.o
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h
index 5449e5c..bc9db53 100644
--- a/drivers/pci/pcie/aer/aerdrv.h
+++ b/drivers/pci/pcie/aer/aerdrv.h
@@ -76,36 +76,6 @@ struct aer_rpc {
 */
 };
 
-struct aer_broadcast_data {
-   enum pci_channel_state state;
-   enum pci_ers_result result;
-};
-
-static inline pci_ers_result_t merge_result(enum pci_ers_result orig,
-   enum pci_ers_result new)
-{
-   if (new == PCI_ERS_RESULT_NO_AER_DRIVER)
-   return PCI_ERS_RESULT_NO_AER_DRIVER;
-
-   if (new == PCI_ERS_RESULT_NONE)
-   return orig;
-
-   switch (orig) {
-   case PCI_ERS_RESULT_CAN_RECOVER:
-   case PCI_ERS_RESULT_RECOVERED:
-   orig = new;
-   break;
-   case PCI_ERS_RESULT_DISCONNECT:
-   if (new == PCI_ERS_RESULT_NEED_RESET)
-   orig = PCI_ERS_RESULT_NEED_RESET;
-   break;
-   default:
-   break;
-   }
-
-   return orig;
-}
-
 extern struct bus_type pcie_port_bus_type;
 void aer_isr(struct work_struct *work);
 void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c 
b/drivers/pci/pcie/aer/aerdrv_core.c
index 306bf2f..410d4b8 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include "aerdrv.h"
+#include "../../pci.h"
 
 #definePCI_EXP_AER_FLAGS   (PCI_EXP_DEVCTL_CERE | 
PCI_EXP_DEVCTL_NFERE | \
 PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE)
@@ -230,191 +231,6 @@ static bool find_source_device(struct pci_dev *parent,
return true;
 }
 
-static int report_error_detected(struct pci_dev *dev, void *data)
-{
-   pci_ers_result_t vote;
-   const struct pci_error_handlers *err_handler;
-   struct aer_broadcast_data *result_data;
-   result_data = (struct aer_broadcast_data *) data;
-
-   device_lock(>dev);
-   dev->error_state = result_data->state;
-
-   if (!dev->driver ||
-   !dev->driver->err_handler ||
-   !dev->driver->err_handler->error_detected) {
-   if (result_data->state == pci_channel_io_frozen &&
-   dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
-   /*
-* In case of fatal recovery, if one of down-
-* stream device has no driver. We might be
-* unable to recover because a later insmod
-* of a driver for this device is unaware of
-* its hw state.
-*/
-   pci_printk(KERN_DEBUG, dev, "device has %s\n",
-  dev->driver ?
-  "no AER-aware driver" : "no driver");
-   }
-
-   /*
-* If there's any device in the subtree that does not
-* have an error_detected callback, returning
-* PCI_ERS_RESULT_NO_AER_DRIVER prevents calling of
-* the subsequent mmio_enabled/slot_reset/resume
-* callbacks of "any" device in the subtree. All the
-* devices in the subtree are left in the error state
-* without recovery.
-*/
-
-   if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE)
-   vote = PCI_ERS_RESULT_NO_AER_DRIVER;
-   else
-   vote = PCI_ERS_RESULT_NONE;
-   } else {
-   err_handler = dev->driver->err_handler;
-   vote = 

Re: [PATCH v7 0/5] Add Intel IOMMU debugfs support

2018-02-21 Thread Yves-Alexis Perez
On Tue, 2018-02-20 at 14:25 -0800, Jacob Pan wrote:
> I didn't know about chipsec but reading the code seems to rely on an
> out-of-tree kernel module. I don't think it matches what we need here.

Yes good indeed, I had forgot about that. Maybe the userland part is still
useful, but there's definitely a need for (protected) access to privileged
memory (and access to /dev/mem is less practical than debugfs, I guess).

Regards,
-- 
Yves-Alexis

signature.asc
Description: This is a digitally signed message part


Re: [PATCH v7 0/5] Add Intel IOMMU debugfs support

2018-02-21 Thread Yves-Alexis Perez
On Tue, 2018-02-20 at 14:25 -0800, Jacob Pan wrote:
> I didn't know about chipsec but reading the code seems to rely on an
> out-of-tree kernel module. I don't think it matches what we need here.

Yes good indeed, I had forgot about that. Maybe the userland part is still
useful, but there's definitely a need for (protected) access to privileged
memory (and access to /dev/mem is less practical than debugfs, I guess).

Regards,
-- 
Yves-Alexis

signature.asc
Description: This is a digitally signed message part


[PATCH v9 4/7] PCI/DPC: Unify and plumb error handling into DPC

2018-02-21 Thread Oza Pawandeep
Current DPC driver does not do recovery, e.g. calling end-point's driver's
callbacks, which sanitize the sw.

DPC driver implements link_reset callback, and calls pci_do_recovery.

Signed-off-by: Oza Pawandeep 

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index a5a79f0..124f42e 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -343,6 +343,8 @@ static inline resource_size_t pci_resource_alignment(struct 
pci_dev *dev,
 void pci_enable_acs(struct pci_dev *dev);
 
 /* PCI error reporting and recovery */
+#define DPC_FATAL  4
+
 void pci_do_recovery(struct pci_dev *dev, int severity);
 
 #ifdef CONFIG_PCIEASPM
diff --git a/drivers/pci/pcie/pcie-dpc.c b/drivers/pci/pcie/pcie-dpc.c
index 38e40c6..208b427 100644
--- a/drivers/pci/pcie/pcie-dpc.c
+++ b/drivers/pci/pcie/pcie-dpc.c
@@ -13,6 +13,7 @@
 #include 
 #include "../pci.h"
 #include "aer/aerdrv.h"
+#include "portdrv.h"
 
 struct dpc_dev {
struct pcie_device  *dev;
@@ -45,6 +46,60 @@ struct dpc_dev {
"Memory Request Completion Timeout", /* Bit Position 18 */
 };
 
+static int find_dpc_dev_iter(struct device *device, void *data)
+{
+   struct pcie_port_service_driver *service_driver;
+   struct device **dev;
+
+   dev = (struct device **) data;
+
+   if (device->bus == _port_bus_type && device->driver) {
+   service_driver = to_service_driver(device->driver);
+   if (service_driver->service == PCIE_PORT_SERVICE_DPC) {
+   *dev = device;
+   return 1;
+   }
+   }
+
+   return 0;
+}
+
+static struct device *pci_find_dpc_dev(struct pci_dev *pdev)
+{
+   struct device *dev = NULL;
+
+   device_for_each_child(>dev, , find_dpc_dev_iter);
+
+   return dev;
+}
+
+static int find_dpc_service_iter(struct device *device, void *data)
+{
+   struct pcie_port_service_driver *service_driver, **drv;
+
+   drv = (struct pcie_port_service_driver **) data;
+
+   if (device->bus == _port_bus_type && device->driver) {
+   service_driver = to_service_driver(device->driver);
+   if (service_driver->service == PCIE_PORT_SERVICE_DPC) {
+   *drv = service_driver;
+   return 1;
+   }
+   }
+
+   return 0;
+}
+
+struct pcie_port_service_driver *pci_find_dpc_service(struct pci_dev *dev)
+{
+   struct pcie_port_service_driver *drv = NULL;
+
+   device_for_each_child(>dev, , find_dpc_service_iter);
+
+   return drv;
+}
+EXPORT_SYMBOL(pci_find_dpc_service);
+
 static int dpc_wait_rp_inactive(struct dpc_dev *dpc)
 {
unsigned long timeout = jiffies + HZ;
@@ -82,12 +137,25 @@ static void dpc_wait_link_inactive(struct dpc_dev *dpc)
dev_warn(dev, "Link state not disabled for DPC event\n");
 }
 
-static void dpc_work(struct work_struct *work)
+/**
+ * dpc_reset_link - reset link DPC  routine
+ * @dev: pointer to Root Port's pci_dev data structure
+ *
+ * Invoked by Port Bus driver when performing link reset at Root Port.
+ */
+static pci_ers_result_t dpc_reset_link(struct pci_dev *pdev)
 {
-   struct dpc_dev *dpc = container_of(work, struct dpc_dev, work);
-   struct pci_dev *dev, *temp, *pdev = dpc->dev->port;
struct pci_bus *parent = pdev->subordinate;
-   u16 cap = dpc->cap_pos, ctl;
+   struct pci_dev *dev, *temp;
+   struct dpc_dev *dpc;
+   struct pcie_device *pciedev;
+   struct device *devdpc;
+   u16 cap, ctl;
+
+   devdpc = pci_find_dpc_dev(pdev);
+   pciedev = to_pcie_device(devdpc);
+   dpc = get_service_data(pciedev);
+   cap = dpc->cap_pos;
 
pci_lock_rescan_remove();
list_for_each_entry_safe_reverse(dev, temp, >devices,
@@ -104,21 +172,31 @@ static void dpc_work(struct work_struct *work)
 
dpc_wait_link_inactive(dpc);
if (dpc->rp_extensions && dpc_wait_rp_inactive(dpc))
-   return;
+   return PCI_ERS_RESULT_DISCONNECT;
if (dpc->rp_extensions && dpc->rp_pio_status) {
pci_write_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_STATUS,
   dpc->rp_pio_status);
dpc->rp_pio_status = 0;
}
 
-   pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS,
+   pci_write_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS,
PCI_EXP_DPC_STATUS_TRIGGER | PCI_EXP_DPC_STATUS_INTERRUPT);
 
pci_read_config_word(pdev, cap + PCI_EXP_DPC_CTL, );
pci_write_config_word(pdev, cap + PCI_EXP_DPC_CTL,
- ctl | PCI_EXP_DPC_CTL_INT_EN);
+   ctl | PCI_EXP_DPC_CTL_INT_EN);
+
+   return PCI_ERS_RESULT_RECOVERED;
 }
 
+static void dpc_work(struct work_struct *work)
+{
+   struct dpc_dev *dpc = container_of(work, struct dpc_dev, work);
+   struct pci_dev *pdev = dpc->dev->port;
+
+   /* From DPC point of view error 

[PATCH v9 4/7] PCI/DPC: Unify and plumb error handling into DPC

2018-02-21 Thread Oza Pawandeep
Current DPC driver does not do recovery, e.g. calling end-point's driver's
callbacks, which sanitize the sw.

DPC driver implements link_reset callback, and calls pci_do_recovery.

Signed-off-by: Oza Pawandeep 

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index a5a79f0..124f42e 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -343,6 +343,8 @@ static inline resource_size_t pci_resource_alignment(struct 
pci_dev *dev,
 void pci_enable_acs(struct pci_dev *dev);
 
 /* PCI error reporting and recovery */
+#define DPC_FATAL  4
+
 void pci_do_recovery(struct pci_dev *dev, int severity);
 
 #ifdef CONFIG_PCIEASPM
diff --git a/drivers/pci/pcie/pcie-dpc.c b/drivers/pci/pcie/pcie-dpc.c
index 38e40c6..208b427 100644
--- a/drivers/pci/pcie/pcie-dpc.c
+++ b/drivers/pci/pcie/pcie-dpc.c
@@ -13,6 +13,7 @@
 #include 
 #include "../pci.h"
 #include "aer/aerdrv.h"
+#include "portdrv.h"
 
 struct dpc_dev {
struct pcie_device  *dev;
@@ -45,6 +46,60 @@ struct dpc_dev {
"Memory Request Completion Timeout", /* Bit Position 18 */
 };
 
+static int find_dpc_dev_iter(struct device *device, void *data)
+{
+   struct pcie_port_service_driver *service_driver;
+   struct device **dev;
+
+   dev = (struct device **) data;
+
+   if (device->bus == _port_bus_type && device->driver) {
+   service_driver = to_service_driver(device->driver);
+   if (service_driver->service == PCIE_PORT_SERVICE_DPC) {
+   *dev = device;
+   return 1;
+   }
+   }
+
+   return 0;
+}
+
+static struct device *pci_find_dpc_dev(struct pci_dev *pdev)
+{
+   struct device *dev = NULL;
+
+   device_for_each_child(>dev, , find_dpc_dev_iter);
+
+   return dev;
+}
+
+static int find_dpc_service_iter(struct device *device, void *data)
+{
+   struct pcie_port_service_driver *service_driver, **drv;
+
+   drv = (struct pcie_port_service_driver **) data;
+
+   if (device->bus == _port_bus_type && device->driver) {
+   service_driver = to_service_driver(device->driver);
+   if (service_driver->service == PCIE_PORT_SERVICE_DPC) {
+   *drv = service_driver;
+   return 1;
+   }
+   }
+
+   return 0;
+}
+
+struct pcie_port_service_driver *pci_find_dpc_service(struct pci_dev *dev)
+{
+   struct pcie_port_service_driver *drv = NULL;
+
+   device_for_each_child(>dev, , find_dpc_service_iter);
+
+   return drv;
+}
+EXPORT_SYMBOL(pci_find_dpc_service);
+
 static int dpc_wait_rp_inactive(struct dpc_dev *dpc)
 {
unsigned long timeout = jiffies + HZ;
@@ -82,12 +137,25 @@ static void dpc_wait_link_inactive(struct dpc_dev *dpc)
dev_warn(dev, "Link state not disabled for DPC event\n");
 }
 
-static void dpc_work(struct work_struct *work)
+/**
+ * dpc_reset_link - reset link DPC  routine
+ * @dev: pointer to Root Port's pci_dev data structure
+ *
+ * Invoked by Port Bus driver when performing link reset at Root Port.
+ */
+static pci_ers_result_t dpc_reset_link(struct pci_dev *pdev)
 {
-   struct dpc_dev *dpc = container_of(work, struct dpc_dev, work);
-   struct pci_dev *dev, *temp, *pdev = dpc->dev->port;
struct pci_bus *parent = pdev->subordinate;
-   u16 cap = dpc->cap_pos, ctl;
+   struct pci_dev *dev, *temp;
+   struct dpc_dev *dpc;
+   struct pcie_device *pciedev;
+   struct device *devdpc;
+   u16 cap, ctl;
+
+   devdpc = pci_find_dpc_dev(pdev);
+   pciedev = to_pcie_device(devdpc);
+   dpc = get_service_data(pciedev);
+   cap = dpc->cap_pos;
 
pci_lock_rescan_remove();
list_for_each_entry_safe_reverse(dev, temp, >devices,
@@ -104,21 +172,31 @@ static void dpc_work(struct work_struct *work)
 
dpc_wait_link_inactive(dpc);
if (dpc->rp_extensions && dpc_wait_rp_inactive(dpc))
-   return;
+   return PCI_ERS_RESULT_DISCONNECT;
if (dpc->rp_extensions && dpc->rp_pio_status) {
pci_write_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_STATUS,
   dpc->rp_pio_status);
dpc->rp_pio_status = 0;
}
 
-   pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS,
+   pci_write_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS,
PCI_EXP_DPC_STATUS_TRIGGER | PCI_EXP_DPC_STATUS_INTERRUPT);
 
pci_read_config_word(pdev, cap + PCI_EXP_DPC_CTL, );
pci_write_config_word(pdev, cap + PCI_EXP_DPC_CTL,
- ctl | PCI_EXP_DPC_CTL_INT_EN);
+   ctl | PCI_EXP_DPC_CTL_INT_EN);
+
+   return PCI_ERS_RESULT_RECOVERED;
 }
 
+static void dpc_work(struct work_struct *work)
+{
+   struct dpc_dev *dpc = container_of(work, struct dpc_dev, work);
+   struct pci_dev *pdev = dpc->dev->port;
+
+   /* From DPC point of view error is always FATAL. */
+ 

Re: [PATCH v3 1/7] ARM: sun8i: smp: Add support for A83T

2018-02-21 Thread Mylène Josserand
Hello Chen-Yu,

On Tue, 20 Feb 2018 11:32:03 +0800
Chen-Yu Tsai  wrote:

> On Mon, Feb 19, 2018 at 4:18 PM, Mylène Josserand
>  wrote:
> > Add the support for A83T.
> >
> > A83T SoC has an additional register than A80 to handle CPU configurations:
> > R_CPUS_CFG. Information about the register comes from Allwinner's BSP
> > driver.
> > An important difference is the Power Off Gating register for clusters
> > which is BIT(4) in case of SUN9I-A80 and BIT(0) in case of SUN8I-A83T.
> >
> > Signed-off-by: Mylène Josserand 
> > ---
> >  arch/arm/mach-sunxi/Kconfig  |   2 +-
> >  arch/arm/mach-sunxi/mc_smp.c | 239 
> > +++  
> 
> The same high-level comments as Maxime. Splitting the patch
> will make this much easier to understand.

Yep, I will do it in next version.

> 
> >  2 files changed, 198 insertions(+), 43 deletions(-)
> >
> > diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> > index ce53ceaf4cc5..a0ad35c41c02 100644
> > --- a/arch/arm/mach-sunxi/Kconfig
> > +++ b/arch/arm/mach-sunxi/Kconfig
> > @@ -51,7 +51,7 @@ config MACH_SUN9I
> >  config ARCH_SUNXI_MC_SMP
> > bool
> > depends on SMP
> > -   default MACH_SUN9I
> > +   default y if MACH_SUN9I || MACH_SUN8I
> > select ARM_CCI400_PORT_CTRL
> > select ARM_CPU_SUSPEND
> >
> > diff --git a/arch/arm/mach-sunxi/mc_smp.c b/arch/arm/mach-sunxi/mc_smp.c
> > index 11e46c6efb90..fec592bf68b4 100644
> > --- a/arch/arm/mach-sunxi/mc_smp.c
> > +++ b/arch/arm/mach-sunxi/mc_smp.c
> > @@ -55,20 +55,29 @@
> >  #define CPUCFG_CX_RST_CTRL_L2_RST  BIT(8)
> >  #define CPUCFG_CX_RST_CTRL_CX_RST(n)   BIT(4 + (n))
> >  #define CPUCFG_CX_RST_CTRL_CORE_RST(n) BIT(n)
> > +#define CPUCFG_CX_RST_CTRL_CORE_RST_ALL(0xf << 0)
> >
> >  #define PRCM_CPU_PO_RST_CTRL(c)(0x4 + 0x4 * (c))
> >  #define PRCM_CPU_PO_RST_CTRL_CORE(n)   BIT(n)
> >  #define PRCM_CPU_PO_RST_CTRL_CORE_ALL  0xf
> >  #define PRCM_PWROFF_GATING_REG(c)  (0x100 + 0x4 * (c))
> > -#define PRCM_PWROFF_GATING_REG_CLUSTER BIT(4)
> > +/* The power off register for clusters are different from SUN9I and SUN8I 
> > */
> > +#define PRCM_PWROFF_GATING_REG_CLUSTER_SUN8I   BIT(0)
> > +#define PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I   BIT(4)
> >  #define PRCM_PWROFF_GATING_REG_CORE(n) BIT(n)
> >  #define PRCM_PWR_SWITCH_REG(c, cpu)(0x140 + 0x10 * (c) + 0x4 * (cpu))
> >  #define PRCM_CPU_SOFT_ENTRY_REG0x164
> >
> > +/* R_CPUCFG registers, specific to SUN8I */
> > +#define R_CPUCFG_CLUSTER_PO_RST_CTRL(c)(0x30 + (c) * 0x4)
> > +#define R_CPUCFG_CLUSTER_PO_RST_CTRL_CORE(n)   BIT(n)
> > +#define R_CPUCFG_CPU_SOFT_ENTRY_REG0x01a4
> > +
> >  #define CPU0_SUPPORT_HOTPLUG_MAGIC00xFA50392F
> >  #define CPU0_SUPPORT_HOTPLUG_MAGIC10x790DCA3A
> >
> >  static void __iomem *cpucfg_base;
> > +static void __iomem *r_cpucfg_base;
> >  static void __iomem *prcm_base;
> >  static void __iomem *sram_b_smp_base;
> >
> > @@ -157,6 +166,16 @@ static int sunxi_cpu_powerup(unsigned int cpu, 
> > unsigned int cluster)
> > reg &= ~PRCM_CPU_PO_RST_CTRL_CORE(cpu);
> > writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster));
> >
> > +   if (r_cpucfg_base) {
> > +   /* assert cpu power-on reset */
> > +   reg  = readl(r_cpucfg_base +
> > +R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster));
> > +   reg &= ~(R_CPUCFG_CLUSTER_PO_RST_CTRL_CORE(cpu));
> > +   writel(reg, r_cpucfg_base +
> > +  R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster));
> > +   udelay(10);
> > +   }
> > +
> > /* Cortex-A7: hold L1 reset disable signal low */
> > if (!sunxi_core_is_cortex_a15(cpu, cluster)) {
> > reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG0(cluster));
> > @@ -180,17 +199,37 @@ static int sunxi_cpu_powerup(unsigned int cpu, 
> > unsigned int cluster)
> > /* open power switch */
> > sunxi_cpu_power_switch_set(cpu, cluster, true);
> >
> > +   /* Handle A83T bit swap */
> > +   if (of_machine_is_compatible("allwinner,sun8i-a83t")) {
> > +   if (cpu == 0)
> > +   cpu = 4;
> > +   }
> > +
> > /* clear processor power gate */
> > reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster));
> > reg &= ~PRCM_PWROFF_GATING_REG_CORE(cpu);
> > writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster));
> > udelay(20);
> >
> > +   if (of_machine_is_compatible("allwinner,sun8i-a83t")) {
> > +   if (cpu == 4)
> > +   cpu = 0;
> > +   }
> > +
> > /* de-assert processor power-on reset */
> > reg = readl(prcm_base + PRCM_CPU_PO_RST_CTRL(cluster));
> > reg |= PRCM_CPU_PO_RST_CTRL_CORE(cpu);
> > writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster));
> >
> 

Re: [PATCH 10/20] lightnvm: pblk: rename ppaf* to addrf*

2018-02-21 Thread Matias Bjørling

On 02/21/2018 10:26 AM, Javier González wrote:

In preparation for 2.0 support in pblk, rename variables referring to
the address format to addrf and reserve ppaf for the 1.2 path.

Signed-off-by: Javier González 
---
  drivers/lightnvm/pblk-init.c  |  8 
  drivers/lightnvm/pblk-sysfs.c |  4 ++--
  drivers/lightnvm/pblk.h   | 16 
  3 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c
index 6bf51ef8f516..56b4afc27add 100644
--- a/drivers/lightnvm/pblk-init.c
+++ b/drivers/lightnvm/pblk-init.c
@@ -80,7 +80,7 @@ static size_t pblk_trans_map_size(struct pblk *pblk)
  {
int entry_size = 8;
  
-	if (pblk->ppaf_bitsize < 32)

+   if (pblk->addrf_len < 32)
entry_size = 4;
  
  	return entry_size * pblk->rl.nr_secs;

@@ -198,7 +198,7 @@ static int pblk_set_addrf_12(struct nvm_geo *geo,
return dst->blk_offset + src->blk_len;
  }
  
-static int pblk_set_ppaf(struct pblk *pblk)

+static int pblk_set_addrf(struct pblk *pblk)
  {
struct nvm_tgt_dev *dev = pblk->dev;
struct nvm_geo *geo = >geo;
@@ -210,7 +210,7 @@ static int pblk_set_ppaf(struct pblk *pblk)
return -EINVAL;
}
  
-	pblk->ppaf_bitsize = pblk_set_addrf_12(geo, (void *)>ppaf);

+   pblk->addrf_len = pblk_set_addrf_12(geo, (void *)>addrf);
  
  	return 0;

  }
@@ -319,7 +319,7 @@ static int pblk_core_init(struct pblk *pblk)
if (!pblk->r_end_wq)
goto free_bb_wq;
  
-	if (pblk_set_ppaf(pblk))

+   if (pblk_set_addrf(pblk))
goto free_r_end_wq;
  
  	if (pblk_rwb_init(pblk))

diff --git a/drivers/lightnvm/pblk-sysfs.c b/drivers/lightnvm/pblk-sysfs.c
index 81288aa9162a..d3b50741b691 100644
--- a/drivers/lightnvm/pblk-sysfs.c
+++ b/drivers/lightnvm/pblk-sysfs.c
@@ -117,12 +117,12 @@ static ssize_t pblk_sysfs_ppaf(struct pblk *pblk, char 
*page)
struct nvm_addr_format_12 *geo_ppaf;
ssize_t sz = 0;
  
-	ppaf = (struct nvm_addr_format_12 *)>ppaf;

+   ppaf = (struct nvm_addr_format_12 *)>addrf;
geo_ppaf = (struct nvm_addr_format_12 *)>c.addrf;
  
  	sz = snprintf(page, PAGE_SIZE,


"pblk:(s:%d)ch:%d/%d,lun:%d/%d,blk:%d/%d,pg:%d/%d,pl:%d/%d,sec:%d/%d\n",
-   pblk->ppaf_bitsize,
+   pblk->addrf_len,
ppaf->ch_offset, ppaf->ch_len,
ppaf->lun_offset, ppaf->lun_len,
ppaf->blk_offset, ppaf->blk_len,
diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h
index 4f7a365436f1..46b29a492f74 100644
--- a/drivers/lightnvm/pblk.h
+++ b/drivers/lightnvm/pblk.h
@@ -570,8 +570,8 @@ struct pblk {
struct pblk_line_mgmt l_mg; /* Line management */
struct pblk_line_meta lm;   /* Line metadata */
  
-	struct nvm_addr_format ppaf;

-   int ppaf_bitsize;
+   struct nvm_addr_format addrf;
+   int addrf_len;
  
  	struct pblk_rb rwb;
  
@@ -948,7 +948,7 @@ static inline struct ppa_addr addr_to_gen_ppa(struct pblk *pblk, u64 paddr,

  u64 line_id)
  {
struct nvm_addr_format_12 *ppaf =
-   (struct nvm_addr_format_12 *)>ppaf;
+   (struct nvm_addr_format_12 *)>addrf;
struct ppa_addr ppa;
  
  	ppa.ppa = 0;

@@ -966,7 +966,7 @@ static inline u64 pblk_dev_ppa_to_line_addr(struct pblk 
*pblk,
struct ppa_addr p)
  {
struct nvm_addr_format_12 *ppaf =
-   (struct nvm_addr_format_12 *)>ppaf;
+   (struct nvm_addr_format_12 *)>addrf;
u64 paddr;
  
  	paddr = (u64)p.g.ch << ppaf->ch_offset;

@@ -991,7 +991,7 @@ static inline struct ppa_addr pblk_ppa32_to_ppa64(struct 
pblk *pblk, u32 ppa32)
ppa64.c.is_cached = 1;
} else {
struct nvm_addr_format_12 *ppaf =
-   (struct nvm_addr_format_12 *)>ppaf;
+   (struct nvm_addr_format_12 *)>addrf;
  
  		ppa64.g.ch = (ppa32 & ppaf->ch_mask) >> ppaf->ch_offset;

ppa64.g.lun = (ppa32 & ppaf->lun_mask) >> ppaf->lun_offset;
@@ -1015,7 +1015,7 @@ static inline u32 pblk_ppa64_to_ppa32(struct pblk *pblk, 
struct ppa_addr ppa64)
ppa32 |= 1U << 31;
} else {
struct nvm_addr_format_12 *ppaf =
-   (struct nvm_addr_format_12 *)>ppaf;
+   (struct nvm_addr_format_12 *)>addrf;
  
  		ppa32 |= ppa64.g.ch << ppaf->ch_offset;

ppa32 |= ppa64.g.lun << ppaf->lun_offset;
@@ -1033,7 +1033,7 @@ static inline struct ppa_addr pblk_trans_map_get(struct 
pblk *pblk,
  {
struct ppa_addr ppa;
  
-	if (pblk->ppaf_bitsize < 32) {

+   if (pblk->addrf_len < 32) {

Re: [PATCH v3 1/7] ARM: sun8i: smp: Add support for A83T

2018-02-21 Thread Mylène Josserand
Hello Chen-Yu,

On Tue, 20 Feb 2018 11:32:03 +0800
Chen-Yu Tsai  wrote:

> On Mon, Feb 19, 2018 at 4:18 PM, Mylène Josserand
>  wrote:
> > Add the support for A83T.
> >
> > A83T SoC has an additional register than A80 to handle CPU configurations:
> > R_CPUS_CFG. Information about the register comes from Allwinner's BSP
> > driver.
> > An important difference is the Power Off Gating register for clusters
> > which is BIT(4) in case of SUN9I-A80 and BIT(0) in case of SUN8I-A83T.
> >
> > Signed-off-by: Mylène Josserand 
> > ---
> >  arch/arm/mach-sunxi/Kconfig  |   2 +-
> >  arch/arm/mach-sunxi/mc_smp.c | 239 
> > +++  
> 
> The same high-level comments as Maxime. Splitting the patch
> will make this much easier to understand.

Yep, I will do it in next version.

> 
> >  2 files changed, 198 insertions(+), 43 deletions(-)
> >
> > diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> > index ce53ceaf4cc5..a0ad35c41c02 100644
> > --- a/arch/arm/mach-sunxi/Kconfig
> > +++ b/arch/arm/mach-sunxi/Kconfig
> > @@ -51,7 +51,7 @@ config MACH_SUN9I
> >  config ARCH_SUNXI_MC_SMP
> > bool
> > depends on SMP
> > -   default MACH_SUN9I
> > +   default y if MACH_SUN9I || MACH_SUN8I
> > select ARM_CCI400_PORT_CTRL
> > select ARM_CPU_SUSPEND
> >
> > diff --git a/arch/arm/mach-sunxi/mc_smp.c b/arch/arm/mach-sunxi/mc_smp.c
> > index 11e46c6efb90..fec592bf68b4 100644
> > --- a/arch/arm/mach-sunxi/mc_smp.c
> > +++ b/arch/arm/mach-sunxi/mc_smp.c
> > @@ -55,20 +55,29 @@
> >  #define CPUCFG_CX_RST_CTRL_L2_RST  BIT(8)
> >  #define CPUCFG_CX_RST_CTRL_CX_RST(n)   BIT(4 + (n))
> >  #define CPUCFG_CX_RST_CTRL_CORE_RST(n) BIT(n)
> > +#define CPUCFG_CX_RST_CTRL_CORE_RST_ALL(0xf << 0)
> >
> >  #define PRCM_CPU_PO_RST_CTRL(c)(0x4 + 0x4 * (c))
> >  #define PRCM_CPU_PO_RST_CTRL_CORE(n)   BIT(n)
> >  #define PRCM_CPU_PO_RST_CTRL_CORE_ALL  0xf
> >  #define PRCM_PWROFF_GATING_REG(c)  (0x100 + 0x4 * (c))
> > -#define PRCM_PWROFF_GATING_REG_CLUSTER BIT(4)
> > +/* The power off register for clusters are different from SUN9I and SUN8I 
> > */
> > +#define PRCM_PWROFF_GATING_REG_CLUSTER_SUN8I   BIT(0)
> > +#define PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I   BIT(4)
> >  #define PRCM_PWROFF_GATING_REG_CORE(n) BIT(n)
> >  #define PRCM_PWR_SWITCH_REG(c, cpu)(0x140 + 0x10 * (c) + 0x4 * (cpu))
> >  #define PRCM_CPU_SOFT_ENTRY_REG0x164
> >
> > +/* R_CPUCFG registers, specific to SUN8I */
> > +#define R_CPUCFG_CLUSTER_PO_RST_CTRL(c)(0x30 + (c) * 0x4)
> > +#define R_CPUCFG_CLUSTER_PO_RST_CTRL_CORE(n)   BIT(n)
> > +#define R_CPUCFG_CPU_SOFT_ENTRY_REG0x01a4
> > +
> >  #define CPU0_SUPPORT_HOTPLUG_MAGIC00xFA50392F
> >  #define CPU0_SUPPORT_HOTPLUG_MAGIC10x790DCA3A
> >
> >  static void __iomem *cpucfg_base;
> > +static void __iomem *r_cpucfg_base;
> >  static void __iomem *prcm_base;
> >  static void __iomem *sram_b_smp_base;
> >
> > @@ -157,6 +166,16 @@ static int sunxi_cpu_powerup(unsigned int cpu, 
> > unsigned int cluster)
> > reg &= ~PRCM_CPU_PO_RST_CTRL_CORE(cpu);
> > writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster));
> >
> > +   if (r_cpucfg_base) {
> > +   /* assert cpu power-on reset */
> > +   reg  = readl(r_cpucfg_base +
> > +R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster));
> > +   reg &= ~(R_CPUCFG_CLUSTER_PO_RST_CTRL_CORE(cpu));
> > +   writel(reg, r_cpucfg_base +
> > +  R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster));
> > +   udelay(10);
> > +   }
> > +
> > /* Cortex-A7: hold L1 reset disable signal low */
> > if (!sunxi_core_is_cortex_a15(cpu, cluster)) {
> > reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG0(cluster));
> > @@ -180,17 +199,37 @@ static int sunxi_cpu_powerup(unsigned int cpu, 
> > unsigned int cluster)
> > /* open power switch */
> > sunxi_cpu_power_switch_set(cpu, cluster, true);
> >
> > +   /* Handle A83T bit swap */
> > +   if (of_machine_is_compatible("allwinner,sun8i-a83t")) {
> > +   if (cpu == 0)
> > +   cpu = 4;
> > +   }
> > +
> > /* clear processor power gate */
> > reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster));
> > reg &= ~PRCM_PWROFF_GATING_REG_CORE(cpu);
> > writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster));
> > udelay(20);
> >
> > +   if (of_machine_is_compatible("allwinner,sun8i-a83t")) {
> > +   if (cpu == 4)
> > +   cpu = 0;
> > +   }
> > +
> > /* de-assert processor power-on reset */
> > reg = readl(prcm_base + PRCM_CPU_PO_RST_CTRL(cluster));
> > reg |= PRCM_CPU_PO_RST_CTRL_CORE(cpu);
> > writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster));
> >
> > +   if (r_cpucfg_base) {
> > +   reg  = 

Re: [PATCH 10/20] lightnvm: pblk: rename ppaf* to addrf*

2018-02-21 Thread Matias Bjørling

On 02/21/2018 10:26 AM, Javier González wrote:

In preparation for 2.0 support in pblk, rename variables referring to
the address format to addrf and reserve ppaf for the 1.2 path.

Signed-off-by: Javier González 
---
  drivers/lightnvm/pblk-init.c  |  8 
  drivers/lightnvm/pblk-sysfs.c |  4 ++--
  drivers/lightnvm/pblk.h   | 16 
  3 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c
index 6bf51ef8f516..56b4afc27add 100644
--- a/drivers/lightnvm/pblk-init.c
+++ b/drivers/lightnvm/pblk-init.c
@@ -80,7 +80,7 @@ static size_t pblk_trans_map_size(struct pblk *pblk)
  {
int entry_size = 8;
  
-	if (pblk->ppaf_bitsize < 32)

+   if (pblk->addrf_len < 32)
entry_size = 4;
  
  	return entry_size * pblk->rl.nr_secs;

@@ -198,7 +198,7 @@ static int pblk_set_addrf_12(struct nvm_geo *geo,
return dst->blk_offset + src->blk_len;
  }
  
-static int pblk_set_ppaf(struct pblk *pblk)

+static int pblk_set_addrf(struct pblk *pblk)
  {
struct nvm_tgt_dev *dev = pblk->dev;
struct nvm_geo *geo = >geo;
@@ -210,7 +210,7 @@ static int pblk_set_ppaf(struct pblk *pblk)
return -EINVAL;
}
  
-	pblk->ppaf_bitsize = pblk_set_addrf_12(geo, (void *)>ppaf);

+   pblk->addrf_len = pblk_set_addrf_12(geo, (void *)>addrf);
  
  	return 0;

  }
@@ -319,7 +319,7 @@ static int pblk_core_init(struct pblk *pblk)
if (!pblk->r_end_wq)
goto free_bb_wq;
  
-	if (pblk_set_ppaf(pblk))

+   if (pblk_set_addrf(pblk))
goto free_r_end_wq;
  
  	if (pblk_rwb_init(pblk))

diff --git a/drivers/lightnvm/pblk-sysfs.c b/drivers/lightnvm/pblk-sysfs.c
index 81288aa9162a..d3b50741b691 100644
--- a/drivers/lightnvm/pblk-sysfs.c
+++ b/drivers/lightnvm/pblk-sysfs.c
@@ -117,12 +117,12 @@ static ssize_t pblk_sysfs_ppaf(struct pblk *pblk, char 
*page)
struct nvm_addr_format_12 *geo_ppaf;
ssize_t sz = 0;
  
-	ppaf = (struct nvm_addr_format_12 *)>ppaf;

+   ppaf = (struct nvm_addr_format_12 *)>addrf;
geo_ppaf = (struct nvm_addr_format_12 *)>c.addrf;
  
  	sz = snprintf(page, PAGE_SIZE,


"pblk:(s:%d)ch:%d/%d,lun:%d/%d,blk:%d/%d,pg:%d/%d,pl:%d/%d,sec:%d/%d\n",
-   pblk->ppaf_bitsize,
+   pblk->addrf_len,
ppaf->ch_offset, ppaf->ch_len,
ppaf->lun_offset, ppaf->lun_len,
ppaf->blk_offset, ppaf->blk_len,
diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h
index 4f7a365436f1..46b29a492f74 100644
--- a/drivers/lightnvm/pblk.h
+++ b/drivers/lightnvm/pblk.h
@@ -570,8 +570,8 @@ struct pblk {
struct pblk_line_mgmt l_mg; /* Line management */
struct pblk_line_meta lm;   /* Line metadata */
  
-	struct nvm_addr_format ppaf;

-   int ppaf_bitsize;
+   struct nvm_addr_format addrf;
+   int addrf_len;
  
  	struct pblk_rb rwb;
  
@@ -948,7 +948,7 @@ static inline struct ppa_addr addr_to_gen_ppa(struct pblk *pblk, u64 paddr,

  u64 line_id)
  {
struct nvm_addr_format_12 *ppaf =
-   (struct nvm_addr_format_12 *)>ppaf;
+   (struct nvm_addr_format_12 *)>addrf;
struct ppa_addr ppa;
  
  	ppa.ppa = 0;

@@ -966,7 +966,7 @@ static inline u64 pblk_dev_ppa_to_line_addr(struct pblk 
*pblk,
struct ppa_addr p)
  {
struct nvm_addr_format_12 *ppaf =
-   (struct nvm_addr_format_12 *)>ppaf;
+   (struct nvm_addr_format_12 *)>addrf;
u64 paddr;
  
  	paddr = (u64)p.g.ch << ppaf->ch_offset;

@@ -991,7 +991,7 @@ static inline struct ppa_addr pblk_ppa32_to_ppa64(struct 
pblk *pblk, u32 ppa32)
ppa64.c.is_cached = 1;
} else {
struct nvm_addr_format_12 *ppaf =
-   (struct nvm_addr_format_12 *)>ppaf;
+   (struct nvm_addr_format_12 *)>addrf;
  
  		ppa64.g.ch = (ppa32 & ppaf->ch_mask) >> ppaf->ch_offset;

ppa64.g.lun = (ppa32 & ppaf->lun_mask) >> ppaf->lun_offset;
@@ -1015,7 +1015,7 @@ static inline u32 pblk_ppa64_to_ppa32(struct pblk *pblk, 
struct ppa_addr ppa64)
ppa32 |= 1U << 31;
} else {
struct nvm_addr_format_12 *ppaf =
-   (struct nvm_addr_format_12 *)>ppaf;
+   (struct nvm_addr_format_12 *)>addrf;
  
  		ppa32 |= ppa64.g.ch << ppaf->ch_offset;

ppa32 |= ppa64.g.lun << ppaf->lun_offset;
@@ -1033,7 +1033,7 @@ static inline struct ppa_addr pblk_trans_map_get(struct 
pblk *pblk,
  {
struct ppa_addr ppa;
  
-	if (pblk->ppaf_bitsize < 32) {

+   if (pblk->addrf_len < 32) {
u32 *map = (u32 

Re: [PATCH 03/20] lightnvm: fix capabilities for 2.0 sysfs

2018-02-21 Thread Javier Gonzalez
> On 22 Feb 2018, at 08.28, Matias Bjørling  wrote:
> 
> On 02/21/2018 10:26 AM, Javier González wrote:
>> Both 1.2 and 2.0 specs define a field for media and controller
>> capabilities. Also, 1.2 defines a separate field dedicated to device
>> capabilities.
>> In 2.0 sysfs, this values have been mixed. Revert them to the right
>> value.
>> Signed-off-by: Javier González 
>> ---
>>  drivers/nvme/host/lightnvm.c | 18 +-
>>  1 file changed, 9 insertions(+), 9 deletions(-)
>> diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
>> index 969bb874850c..598abba66f52 100644
>> --- a/drivers/nvme/host/lightnvm.c
>> +++ b/drivers/nvme/host/lightnvm.c
>> @@ -914,8 +914,8 @@ static ssize_t nvm_dev_attr_show(struct device *dev,
>>  if (strcmp(attr->name, "version") == 0) {
>>  return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->ver_id);
>> -} else if (strcmp(attr->name, "capabilities") == 0) {
>> -return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->c.cap);
>> +} else if (strcmp(attr->name, "media_capabilities") == 0) {
>> +return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->c.mccap);
>>  } else if (strcmp(attr->name, "read_typ") == 0) {
>>  return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->c.trdt);
>>  } else if (strcmp(attr->name, "read_max") == 0) {
>> @@ -993,8 +993,8 @@ static ssize_t nvm_dev_attr_show_12(struct device *dev,
>>  return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->c.tbem);
>>  } else if (strcmp(attr->name, "multiplane_modes") == 0) {
>>  return scnprintf(page, PAGE_SIZE, "0x%08x\n", dev_geo->c.mpos);
>> -} else if (strcmp(attr->name, "media_capabilities") == 0) {
>> -return scnprintf(page, PAGE_SIZE, "0x%08x\n", dev_geo->c.mccap);
>> +} else if (strcmp(attr->name, "capabilities") == 0) {
>> +return scnprintf(page, PAGE_SIZE, "0x%08x\n", dev_geo->c.cap);
>>  } else if (strcmp(attr->name, "max_phys_secs") == 0) {
>>  return scnprintf(page, PAGE_SIZE, "%u\n", NVM_MAX_VLBA);
>>  } else {
>> @@ -1055,7 +1055,7 @@ static ssize_t nvm_dev_attr_show_20(struct device *dev,
>>/* general attributes */
>>  static NVM_DEV_ATTR_RO(version);
>> -static NVM_DEV_ATTR_RO(capabilities);
>> +static NVM_DEV_ATTR_RO(media_capabilities);
>>static NVM_DEV_ATTR_RO(read_typ);
>>  static NVM_DEV_ATTR_RO(read_max);
>> @@ -1080,12 +1080,12 @@ static NVM_DEV_ATTR_12_RO(prog_max);
>>  static NVM_DEV_ATTR_12_RO(erase_typ);
>>  static NVM_DEV_ATTR_12_RO(erase_max);
>>  static NVM_DEV_ATTR_12_RO(multiplane_modes);
>> -static NVM_DEV_ATTR_12_RO(media_capabilities);
>> +static NVM_DEV_ATTR_12_RO(capabilities);
>>  static NVM_DEV_ATTR_12_RO(max_phys_secs);
>>static struct attribute *nvm_dev_attrs_12[] = {
>>  _attr_version.attr,
>> -_attr_capabilities.attr,
>> +_attr_media_capabilities.attr,
>>  _attr_vendor_opcode.attr,
>>  _attr_device_mode.attr,
>> @@ -1108,7 +1108,7 @@ static struct attribute *nvm_dev_attrs_12[] = {
>>  _attr_erase_typ.attr,
>>  _attr_erase_max.attr,
>>  _attr_multiplane_modes.attr,
>> -_attr_media_capabilities.attr,
>> +_attr_capabilities.attr,
>>  _attr_max_phys_secs.attr,
>>  NULL,
>> @@ -1134,7 +1134,7 @@ static NVM_DEV_ATTR_20_RO(reset_max);
>>static struct attribute *nvm_dev_attrs_20[] = {
>>  _attr_version.attr,
>> -_attr_capabilities.attr,
>> +_attr_media_capabilities.attr,
>>  _attr_groups.attr,
>>  _attr_punits.attr,
> 
> With the mccap changes, it should make sense to keep the capabilities
> as is.

The change adds mccap, but sysfs points to cap, which is wrong. This
patch is needed. Otherwise, we change the name of mccap to cap, which
is _very_ confusing to people familiar to both specs. We can change
the name of mccap to cap in a future spec revision.

Javier


signature.asc
Description: Message signed with OpenPGP


Re: [PATCH 03/20] lightnvm: fix capabilities for 2.0 sysfs

2018-02-21 Thread Javier Gonzalez
> On 22 Feb 2018, at 08.28, Matias Bjørling  wrote:
> 
> On 02/21/2018 10:26 AM, Javier González wrote:
>> Both 1.2 and 2.0 specs define a field for media and controller
>> capabilities. Also, 1.2 defines a separate field dedicated to device
>> capabilities.
>> In 2.0 sysfs, this values have been mixed. Revert them to the right
>> value.
>> Signed-off-by: Javier González 
>> ---
>>  drivers/nvme/host/lightnvm.c | 18 +-
>>  1 file changed, 9 insertions(+), 9 deletions(-)
>> diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
>> index 969bb874850c..598abba66f52 100644
>> --- a/drivers/nvme/host/lightnvm.c
>> +++ b/drivers/nvme/host/lightnvm.c
>> @@ -914,8 +914,8 @@ static ssize_t nvm_dev_attr_show(struct device *dev,
>>  if (strcmp(attr->name, "version") == 0) {
>>  return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->ver_id);
>> -} else if (strcmp(attr->name, "capabilities") == 0) {
>> -return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->c.cap);
>> +} else if (strcmp(attr->name, "media_capabilities") == 0) {
>> +return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->c.mccap);
>>  } else if (strcmp(attr->name, "read_typ") == 0) {
>>  return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->c.trdt);
>>  } else if (strcmp(attr->name, "read_max") == 0) {
>> @@ -993,8 +993,8 @@ static ssize_t nvm_dev_attr_show_12(struct device *dev,
>>  return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->c.tbem);
>>  } else if (strcmp(attr->name, "multiplane_modes") == 0) {
>>  return scnprintf(page, PAGE_SIZE, "0x%08x\n", dev_geo->c.mpos);
>> -} else if (strcmp(attr->name, "media_capabilities") == 0) {
>> -return scnprintf(page, PAGE_SIZE, "0x%08x\n", dev_geo->c.mccap);
>> +} else if (strcmp(attr->name, "capabilities") == 0) {
>> +return scnprintf(page, PAGE_SIZE, "0x%08x\n", dev_geo->c.cap);
>>  } else if (strcmp(attr->name, "max_phys_secs") == 0) {
>>  return scnprintf(page, PAGE_SIZE, "%u\n", NVM_MAX_VLBA);
>>  } else {
>> @@ -1055,7 +1055,7 @@ static ssize_t nvm_dev_attr_show_20(struct device *dev,
>>/* general attributes */
>>  static NVM_DEV_ATTR_RO(version);
>> -static NVM_DEV_ATTR_RO(capabilities);
>> +static NVM_DEV_ATTR_RO(media_capabilities);
>>static NVM_DEV_ATTR_RO(read_typ);
>>  static NVM_DEV_ATTR_RO(read_max);
>> @@ -1080,12 +1080,12 @@ static NVM_DEV_ATTR_12_RO(prog_max);
>>  static NVM_DEV_ATTR_12_RO(erase_typ);
>>  static NVM_DEV_ATTR_12_RO(erase_max);
>>  static NVM_DEV_ATTR_12_RO(multiplane_modes);
>> -static NVM_DEV_ATTR_12_RO(media_capabilities);
>> +static NVM_DEV_ATTR_12_RO(capabilities);
>>  static NVM_DEV_ATTR_12_RO(max_phys_secs);
>>static struct attribute *nvm_dev_attrs_12[] = {
>>  _attr_version.attr,
>> -_attr_capabilities.attr,
>> +_attr_media_capabilities.attr,
>>  _attr_vendor_opcode.attr,
>>  _attr_device_mode.attr,
>> @@ -1108,7 +1108,7 @@ static struct attribute *nvm_dev_attrs_12[] = {
>>  _attr_erase_typ.attr,
>>  _attr_erase_max.attr,
>>  _attr_multiplane_modes.attr,
>> -_attr_media_capabilities.attr,
>> +_attr_capabilities.attr,
>>  _attr_max_phys_secs.attr,
>>  NULL,
>> @@ -1134,7 +1134,7 @@ static NVM_DEV_ATTR_20_RO(reset_max);
>>static struct attribute *nvm_dev_attrs_20[] = {
>>  _attr_version.attr,
>> -_attr_capabilities.attr,
>> +_attr_media_capabilities.attr,
>>  _attr_groups.attr,
>>  _attr_punits.attr,
> 
> With the mccap changes, it should make sense to keep the capabilities
> as is.

The change adds mccap, but sysfs points to cap, which is wrong. This
patch is needed. Otherwise, we change the name of mccap to cap, which
is _very_ confusing to people familiar to both specs. We can change
the name of mccap to cap in a future spec revision.

Javier


signature.asc
Description: Message signed with OpenPGP


[PATCH v9 5/7] PCI/AER: Unify aer error defines at single space

2018-02-21 Thread Oza Pawandeep
This patch moves AER error defines to drivers/pci/pci.h.
So that it unifies the error repoting codes at single place along with dpc

Signed-off-by: Oza Pawandeep 

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 1efefe9..7ae9bb3 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -56,6 +56,7 @@
 #include 
 
 #include "apei-internal.h"
+#include "../../pci/pci.h"
 
 #define GHES_PFX   "GHES: "
 
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 124f42e..b0e63b5 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -343,7 +343,11 @@ static inline resource_size_t 
pci_resource_alignment(struct pci_dev *dev,
 void pci_enable_acs(struct pci_dev *dev);
 
 /* PCI error reporting and recovery */
-#define DPC_FATAL  4
+#define AER_NONFATAL   0
+#define AER_FATAL  1
+#define AER_CORRECTABLE2
+
+#define DPC_FATAL  4
 
 void pci_do_recovery(struct pci_dev *dev, int severity);
 
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c 
b/drivers/pci/pcie/aer/aerdrv_errprint.c
index 6a352e6..4c59f37 100644
--- a/drivers/pci/pcie/aer/aerdrv_errprint.c
+++ b/drivers/pci/pcie/aer/aerdrv_errprint.c
@@ -19,6 +19,7 @@
 #include 
 
 #include "aerdrv.h"
+#include "../../pci.h"
 #include 
 
 #define AER_AGENT_RECEIVER 0
diff --git a/include/linux/aer.h b/include/linux/aer.h
index 8f87bbe..3eac8ed 100644
--- a/include/linux/aer.h
+++ b/include/linux/aer.h
@@ -11,10 +11,6 @@
 #include 
 #include 
 
-#define AER_NONFATAL   0
-#define AER_FATAL  1
-#define AER_CORRECTABLE2
-
 struct pci_dev;
 
 struct aer_header_log_regs {
diff --git a/include/ras/ras_event.h b/include/ras/ras_event.h
index 9c68986..d75c75b 100644
--- a/include/ras/ras_event.h
+++ b/include/ras/ras_event.h
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include "../../../drivers/pci/pci.h"
 
 /*
  * MCE Extended Error Log trace event
-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm 
Technologies, Inc.,
a Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux 
Foundation Collaborative Project.



[PATCH v9 5/7] PCI/AER: Unify aer error defines at single space

2018-02-21 Thread Oza Pawandeep
This patch moves AER error defines to drivers/pci/pci.h.
So that it unifies the error repoting codes at single place along with dpc

Signed-off-by: Oza Pawandeep 

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 1efefe9..7ae9bb3 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -56,6 +56,7 @@
 #include 
 
 #include "apei-internal.h"
+#include "../../pci/pci.h"
 
 #define GHES_PFX   "GHES: "
 
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 124f42e..b0e63b5 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -343,7 +343,11 @@ static inline resource_size_t 
pci_resource_alignment(struct pci_dev *dev,
 void pci_enable_acs(struct pci_dev *dev);
 
 /* PCI error reporting and recovery */
-#define DPC_FATAL  4
+#define AER_NONFATAL   0
+#define AER_FATAL  1
+#define AER_CORRECTABLE2
+
+#define DPC_FATAL  4
 
 void pci_do_recovery(struct pci_dev *dev, int severity);
 
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c 
b/drivers/pci/pcie/aer/aerdrv_errprint.c
index 6a352e6..4c59f37 100644
--- a/drivers/pci/pcie/aer/aerdrv_errprint.c
+++ b/drivers/pci/pcie/aer/aerdrv_errprint.c
@@ -19,6 +19,7 @@
 #include 
 
 #include "aerdrv.h"
+#include "../../pci.h"
 #include 
 
 #define AER_AGENT_RECEIVER 0
diff --git a/include/linux/aer.h b/include/linux/aer.h
index 8f87bbe..3eac8ed 100644
--- a/include/linux/aer.h
+++ b/include/linux/aer.h
@@ -11,10 +11,6 @@
 #include 
 #include 
 
-#define AER_NONFATAL   0
-#define AER_FATAL  1
-#define AER_CORRECTABLE2
-
 struct pci_dev;
 
 struct aer_header_log_regs {
diff --git a/include/ras/ras_event.h b/include/ras/ras_event.h
index 9c68986..d75c75b 100644
--- a/include/ras/ras_event.h
+++ b/include/ras/ras_event.h
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include "../../../drivers/pci/pci.h"
 
 /*
  * MCE Extended Error Log trace event
-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm 
Technologies, Inc.,
a Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux 
Foundation Collaborative Project.



[PATCH v9 6/7] PCI: Unify wait for link active into generic pci

2018-02-21 Thread Oza Pawandeep
Clients such as pciehp, dpc are using pcie_wait_link_active, which waits
till the link becomes active or inactive.

Made generic function and moved it to drivers/pci/pci.c

Signed-off-by: Oza Pawandeep 

diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 18a42f8..a133b8b 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -231,25 +231,12 @@ bool pciehp_check_link_active(struct controller *ctrl)
return ret;
 }
 
-static void __pcie_wait_link_active(struct controller *ctrl, bool active)
+static bool pcie_wait_link_active(struct controller *ctrl)
 {
-   int timeout = 1000;
-
-   if (pciehp_check_link_active(ctrl) == active)
-   return;
-   while (timeout > 0) {
-   msleep(10);
-   timeout -= 10;
-   if (pciehp_check_link_active(ctrl) == active)
-   return;
-   }
-   ctrl_dbg(ctrl, "Data Link Layer Link Active not %s in 1000 msec\n",
-   active ? "set" : "cleared");
-}
+   struct pci_dev *pdev = ctrl_dev(ctrl);
+   bool active = true;
 
-static void pcie_wait_link_active(struct controller *ctrl)
-{
-   __pcie_wait_link_active(ctrl, true);
+   return pci_wait_for_link(pdev, active);
 }
 
 static bool pci_bus_check_dev(struct pci_bus *bus, int devfn)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index f6a4dd1..5440696 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4176,6 +4176,40 @@ static int pci_pm_reset(struct pci_dev *dev, int probe)
return 0;
 }
 
+/**
+ * pci__wait_for_link - Wait for link till its active/inactive
+ * @pdev: Bridge device
+ * @active: waiting for active or inactive ?
+ *
+ * Use this to wait till link becomes active or inactive.
+ */
+bool pci_wait_for_link(struct pci_dev *pdev, bool active)
+{
+   int timeout = 1000;
+   bool ret;
+   u16 lnk_status;
+
+   pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, _status);
+   ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA);
+
+   while ((ret != active) && (timeout > 0)) {
+   msleep(10);
+   timeout -= 10;
+   pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, _status);
+   ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA);
+   }
+
+   if (ret == active)
+   return true;
+
+   dev_printk(KERN_DEBUG, >dev,
+  "Data Link Layer Link Active not %s in 1000 msec\n",
+  active ? "set" : "cleared");
+
+   return false;
+}
+EXPORT_SYMBOL(pci_wait_for_link);
+
 void pci_reset_secondary_bus(struct pci_dev *dev)
 {
u16 ctrl;
diff --git a/drivers/pci/pcie/pcie-dpc.c b/drivers/pci/pcie/pcie-dpc.c
index 208b427..fce4518 100644
--- a/drivers/pci/pcie/pcie-dpc.c
+++ b/drivers/pci/pcie/pcie-dpc.c
@@ -122,19 +122,10 @@ static int dpc_wait_rp_inactive(struct dpc_dev *dpc)
 
 static void dpc_wait_link_inactive(struct dpc_dev *dpc)
 {
-   unsigned long timeout = jiffies + HZ;
struct pci_dev *pdev = dpc->dev->port;
-   struct device *dev = >dev->device;
-   u16 lnk_status;
+   bool active = false;
 
-   pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, _status);
-   while (lnk_status & PCI_EXP_LNKSTA_DLLLA &&
-   !time_after(jiffies, timeout)) {
-   msleep(10);
-   pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, _status);
-   }
-   if (lnk_status & PCI_EXP_LNKSTA_DLLLA)
-   dev_warn(dev, "Link state not disabled for DPC event\n");
+   pci_wait_for_link(pdev, active);
 }
 
 /**
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 024a1be..cb674c3 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1195,6 +1195,7 @@ int pci_add_ext_cap_save_buffer(struct pci_dev *dev,
 int pci_request_selected_regions(struct pci_dev *, int, const char *);
 int pci_request_selected_regions_exclusive(struct pci_dev *, int, const char 
*);
 void pci_release_selected_regions(struct pci_dev *, int);
+bool pci_wait_for_link(struct pci_dev *pdev, bool active);
 
 /* drivers/pci/bus.c */
 struct pci_bus *pci_bus_get(struct pci_bus *bus);
-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm 
Technologies, Inc.,
a Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux 
Foundation Collaborative Project.



[PATCH v9 7/7] PCI/DPC: Enumerate the devices after DPC trigger event

2018-02-21 Thread Oza Pawandeep
Implement error_resume callback in DPC so, after DPC trigger event
enumerates the devices beneath.

Signed-off-by: Oza Pawandeep 

diff --git a/drivers/pci/pcie/pcie-dpc.c b/drivers/pci/pcie/pcie-dpc.c
index fce4518..59c01c7 100644
--- a/drivers/pci/pcie/pcie-dpc.c
+++ b/drivers/pci/pcie/pcie-dpc.c
@@ -129,6 +129,23 @@ static void dpc_wait_link_inactive(struct dpc_dev *dpc)
 }
 
 /**
+ * dpc_error_resume - enumerate the devices beneath
+ * @dev: pointer to Root Port's pci_dev data structure
+ *
+ * Invoked by Port Bus driver during nonfatal recovery.
+ */
+static void dpc_error_resume(struct pci_dev *pdev)
+{
+   bool active = true;
+
+   if (pci_wait_for_link(pdev, active)) {
+   pci_lock_rescan_remove();
+   pci_rescan_bus(pdev->bus);
+   pci_unlock_rescan_remove();
+   }
+}
+
+/**
  * dpc_reset_link - reset link DPC  routine
  * @dev: pointer to Root Port's pci_dev data structure
  *
@@ -366,6 +383,7 @@ static void dpc_remove(struct pcie_device *dev)
.service= PCIE_PORT_SERVICE_DPC,
.probe  = dpc_probe,
.remove = dpc_remove,
+   .error_resume   = dpc_error_resume,
.reset_link = dpc_reset_link,
 };
 
diff --git a/drivers/pci/pcie/pcie-err.c b/drivers/pci/pcie/pcie-err.c
index 6844347..4950f49 100644
--- a/drivers/pci/pcie/pcie-err.c
+++ b/drivers/pci/pcie/pcie-err.c
@@ -236,6 +236,7 @@ static pci_ers_result_t reset_link(struct pci_dev *dev, int 
severity)
  * @state: error state
  * @error_mesg: message to print
  * @cb: callback to be broadcasted
+ * @severity: error severity
  *
  * Invoked during error recovery process. Once being invoked, the content
  * of error severity will be broadcasted to all downstream drivers in a
@@ -244,7 +245,8 @@ static pci_ers_result_t reset_link(struct pci_dev *dev, int 
severity)
 static pci_ers_result_t broadcast_error_message(struct pci_dev *dev,
enum pci_channel_state state,
char *error_mesg,
-   int (*cb)(struct pci_dev *, void *))
+   int (*cb)(struct pci_dev *, void *),
+   int severity)
 {
struct aer_broadcast_data result_data;
 
@@ -256,6 +258,15 @@ static pci_ers_result_t broadcast_error_message(struct 
pci_dev *dev,
result_data.result = PCI_ERS_RESULT_RECOVERED;
 
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+   /* If DPC is triggered, call resume error hanlder
+* because, at this point we can safely assume that
+* link recovery has happened.
+*/
+   if ((severity == DPC_FATAL) &&
+   (cb == report_resume)) {
+   cb(dev, NULL);
+   return PCI_ERS_RESULT_RECOVERED;
+   }
/*
 * If the error is reported by a bridge, we think this error
 * is related to the downstream link of the bridge, so we
@@ -305,7 +316,8 @@ void pci_do_recovery(struct pci_dev *dev, int severity)
status = broadcast_error_message(dev,
state,
"error_detected",
-   report_error_detected);
+   report_error_detected,
+   severity);
 
if ((severity == AER_FATAL) ||
(severity == DPC_FATAL)) {
@@ -321,7 +333,8 @@ void pci_do_recovery(struct pci_dev *dev, int severity)
status = broadcast_error_message(dev,
state,
"mmio_enabled",
-   report_mmio_enabled);
+   report_mmio_enabled,
+   severity);
 
if (status == PCI_ERS_RESULT_NEED_RESET) {
/*
@@ -332,7 +345,8 @@ void pci_do_recovery(struct pci_dev *dev, int severity)
status = broadcast_error_message(dev,
state,
"slot_reset",
-   report_slot_reset);
+   report_slot_reset,
+   severity);
}
 
if (status != PCI_ERS_RESULT_RECOVERED)
@@ -342,7 +356,8 @@ void pci_do_recovery(struct pci_dev *dev, int severity)
broadcast_error_message(dev,
state,
"resume",
-   report_resume);
+   report_resume,
+   severity);
 
dev_info(>dev, "Device recovery successful\n");
mutex_unlock(_err_recovery_lock);
-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm 
Technologies, Inc.,
a Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux 
Foundation Collaborative Project.



[PATCH v9 6/7] PCI: Unify wait for link active into generic pci

2018-02-21 Thread Oza Pawandeep
Clients such as pciehp, dpc are using pcie_wait_link_active, which waits
till the link becomes active or inactive.

Made generic function and moved it to drivers/pci/pci.c

Signed-off-by: Oza Pawandeep 

diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 18a42f8..a133b8b 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -231,25 +231,12 @@ bool pciehp_check_link_active(struct controller *ctrl)
return ret;
 }
 
-static void __pcie_wait_link_active(struct controller *ctrl, bool active)
+static bool pcie_wait_link_active(struct controller *ctrl)
 {
-   int timeout = 1000;
-
-   if (pciehp_check_link_active(ctrl) == active)
-   return;
-   while (timeout > 0) {
-   msleep(10);
-   timeout -= 10;
-   if (pciehp_check_link_active(ctrl) == active)
-   return;
-   }
-   ctrl_dbg(ctrl, "Data Link Layer Link Active not %s in 1000 msec\n",
-   active ? "set" : "cleared");
-}
+   struct pci_dev *pdev = ctrl_dev(ctrl);
+   bool active = true;
 
-static void pcie_wait_link_active(struct controller *ctrl)
-{
-   __pcie_wait_link_active(ctrl, true);
+   return pci_wait_for_link(pdev, active);
 }
 
 static bool pci_bus_check_dev(struct pci_bus *bus, int devfn)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index f6a4dd1..5440696 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4176,6 +4176,40 @@ static int pci_pm_reset(struct pci_dev *dev, int probe)
return 0;
 }
 
+/**
+ * pci__wait_for_link - Wait for link till its active/inactive
+ * @pdev: Bridge device
+ * @active: waiting for active or inactive ?
+ *
+ * Use this to wait till link becomes active or inactive.
+ */
+bool pci_wait_for_link(struct pci_dev *pdev, bool active)
+{
+   int timeout = 1000;
+   bool ret;
+   u16 lnk_status;
+
+   pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, _status);
+   ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA);
+
+   while ((ret != active) && (timeout > 0)) {
+   msleep(10);
+   timeout -= 10;
+   pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, _status);
+   ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA);
+   }
+
+   if (ret == active)
+   return true;
+
+   dev_printk(KERN_DEBUG, >dev,
+  "Data Link Layer Link Active not %s in 1000 msec\n",
+  active ? "set" : "cleared");
+
+   return false;
+}
+EXPORT_SYMBOL(pci_wait_for_link);
+
 void pci_reset_secondary_bus(struct pci_dev *dev)
 {
u16 ctrl;
diff --git a/drivers/pci/pcie/pcie-dpc.c b/drivers/pci/pcie/pcie-dpc.c
index 208b427..fce4518 100644
--- a/drivers/pci/pcie/pcie-dpc.c
+++ b/drivers/pci/pcie/pcie-dpc.c
@@ -122,19 +122,10 @@ static int dpc_wait_rp_inactive(struct dpc_dev *dpc)
 
 static void dpc_wait_link_inactive(struct dpc_dev *dpc)
 {
-   unsigned long timeout = jiffies + HZ;
struct pci_dev *pdev = dpc->dev->port;
-   struct device *dev = >dev->device;
-   u16 lnk_status;
+   bool active = false;
 
-   pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, _status);
-   while (lnk_status & PCI_EXP_LNKSTA_DLLLA &&
-   !time_after(jiffies, timeout)) {
-   msleep(10);
-   pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, _status);
-   }
-   if (lnk_status & PCI_EXP_LNKSTA_DLLLA)
-   dev_warn(dev, "Link state not disabled for DPC event\n");
+   pci_wait_for_link(pdev, active);
 }
 
 /**
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 024a1be..cb674c3 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1195,6 +1195,7 @@ int pci_add_ext_cap_save_buffer(struct pci_dev *dev,
 int pci_request_selected_regions(struct pci_dev *, int, const char *);
 int pci_request_selected_regions_exclusive(struct pci_dev *, int, const char 
*);
 void pci_release_selected_regions(struct pci_dev *, int);
+bool pci_wait_for_link(struct pci_dev *pdev, bool active);
 
 /* drivers/pci/bus.c */
 struct pci_bus *pci_bus_get(struct pci_bus *bus);
-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm 
Technologies, Inc.,
a Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux 
Foundation Collaborative Project.



[PATCH v9 7/7] PCI/DPC: Enumerate the devices after DPC trigger event

2018-02-21 Thread Oza Pawandeep
Implement error_resume callback in DPC so, after DPC trigger event
enumerates the devices beneath.

Signed-off-by: Oza Pawandeep 

diff --git a/drivers/pci/pcie/pcie-dpc.c b/drivers/pci/pcie/pcie-dpc.c
index fce4518..59c01c7 100644
--- a/drivers/pci/pcie/pcie-dpc.c
+++ b/drivers/pci/pcie/pcie-dpc.c
@@ -129,6 +129,23 @@ static void dpc_wait_link_inactive(struct dpc_dev *dpc)
 }
 
 /**
+ * dpc_error_resume - enumerate the devices beneath
+ * @dev: pointer to Root Port's pci_dev data structure
+ *
+ * Invoked by Port Bus driver during nonfatal recovery.
+ */
+static void dpc_error_resume(struct pci_dev *pdev)
+{
+   bool active = true;
+
+   if (pci_wait_for_link(pdev, active)) {
+   pci_lock_rescan_remove();
+   pci_rescan_bus(pdev->bus);
+   pci_unlock_rescan_remove();
+   }
+}
+
+/**
  * dpc_reset_link - reset link DPC  routine
  * @dev: pointer to Root Port's pci_dev data structure
  *
@@ -366,6 +383,7 @@ static void dpc_remove(struct pcie_device *dev)
.service= PCIE_PORT_SERVICE_DPC,
.probe  = dpc_probe,
.remove = dpc_remove,
+   .error_resume   = dpc_error_resume,
.reset_link = dpc_reset_link,
 };
 
diff --git a/drivers/pci/pcie/pcie-err.c b/drivers/pci/pcie/pcie-err.c
index 6844347..4950f49 100644
--- a/drivers/pci/pcie/pcie-err.c
+++ b/drivers/pci/pcie/pcie-err.c
@@ -236,6 +236,7 @@ static pci_ers_result_t reset_link(struct pci_dev *dev, int 
severity)
  * @state: error state
  * @error_mesg: message to print
  * @cb: callback to be broadcasted
+ * @severity: error severity
  *
  * Invoked during error recovery process. Once being invoked, the content
  * of error severity will be broadcasted to all downstream drivers in a
@@ -244,7 +245,8 @@ static pci_ers_result_t reset_link(struct pci_dev *dev, int 
severity)
 static pci_ers_result_t broadcast_error_message(struct pci_dev *dev,
enum pci_channel_state state,
char *error_mesg,
-   int (*cb)(struct pci_dev *, void *))
+   int (*cb)(struct pci_dev *, void *),
+   int severity)
 {
struct aer_broadcast_data result_data;
 
@@ -256,6 +258,15 @@ static pci_ers_result_t broadcast_error_message(struct 
pci_dev *dev,
result_data.result = PCI_ERS_RESULT_RECOVERED;
 
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+   /* If DPC is triggered, call resume error hanlder
+* because, at this point we can safely assume that
+* link recovery has happened.
+*/
+   if ((severity == DPC_FATAL) &&
+   (cb == report_resume)) {
+   cb(dev, NULL);
+   return PCI_ERS_RESULT_RECOVERED;
+   }
/*
 * If the error is reported by a bridge, we think this error
 * is related to the downstream link of the bridge, so we
@@ -305,7 +316,8 @@ void pci_do_recovery(struct pci_dev *dev, int severity)
status = broadcast_error_message(dev,
state,
"error_detected",
-   report_error_detected);
+   report_error_detected,
+   severity);
 
if ((severity == AER_FATAL) ||
(severity == DPC_FATAL)) {
@@ -321,7 +333,8 @@ void pci_do_recovery(struct pci_dev *dev, int severity)
status = broadcast_error_message(dev,
state,
"mmio_enabled",
-   report_mmio_enabled);
+   report_mmio_enabled,
+   severity);
 
if (status == PCI_ERS_RESULT_NEED_RESET) {
/*
@@ -332,7 +345,8 @@ void pci_do_recovery(struct pci_dev *dev, int severity)
status = broadcast_error_message(dev,
state,
"slot_reset",
-   report_slot_reset);
+   report_slot_reset,
+   severity);
}
 
if (status != PCI_ERS_RESULT_RECOVERED)
@@ -342,7 +356,8 @@ void pci_do_recovery(struct pci_dev *dev, int severity)
broadcast_error_message(dev,
state,
"resume",
-   report_resume);
+   report_resume,
+   severity);
 
dev_info(>dev, "Device recovery successful\n");
mutex_unlock(_err_recovery_lock);
-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm 
Technologies, Inc.,
a Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux 
Foundation Collaborative Project.



Re: [PATCH 09/20] lightnvm: use generic identify structure

2018-02-21 Thread Matias Bjørling

On 02/21/2018 10:26 AM, Javier González wrote:

Create a generic identify structure to collect the identify information
before knowing the spec. version. This forces different version paths to
cast the structure to their spec structure, thus making the code less
error prone and more maintainable.

Signed-off-by: Javier González 
---
  drivers/nvme/host/lightnvm.c | 32 
  1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
index 9c1f8225c4e1..70dc4740f0d3 100644
--- a/drivers/nvme/host/lightnvm.c
+++ b/drivers/nvme/host/lightnvm.c
@@ -170,6 +170,12 @@ struct nvme_nvm_id12 {
__u8resv2[2880];
  } __packed;
  
+/* Generic identification structure */

+struct nvme_nvm_id {
+   __u8ver_id;
+   __u8resv[4095];
+} __packed;
+
  struct nvme_nvm_bb_tbl {
__u8tblid[4];
__le16  verid;
@@ -279,9 +285,10 @@ static void nvme_nvm_set_addr_12(struct nvm_addr_format_12 
*dst,
dst->sec_mask = ((1ULL << dst->sec_len) - 1) << dst->sec_offset;
  }
  
-static int nvme_nvm_setup_12(struct nvme_nvm_id12 *id,

+static int nvme_nvm_setup_12(struct nvme_nvm_id *gen_id,
 struct nvm_dev_geo *dev_geo)
  {
+   struct nvme_nvm_id12 *id = (struct nvme_nvm_id12 *)gen_id;
struct nvme_nvm_id12_grp *src;
int sec_per_pg, sec_per_pl, pg_per_blk;
  
@@ -380,9 +387,11 @@ static void nvme_nvm_set_addr_20(struct nvm_addr_format *dst,

dst->sec_mask = ((1ULL << dst->sec_len) - 1) << dst->sec_offset;
  }
  
-static int nvme_nvm_setup_20(struct nvme_nvm_id20 *id,

+static int nvme_nvm_setup_20(struct nvme_nvm_id *gen_id,
 struct nvm_dev_geo *dev_geo)
  {
+   struct nvme_nvm_id20 *id = (struct nvme_nvm_id20 *)gen_id;
+
dev_geo->major_ver_id = id->mjr;
dev_geo->minor_ver_id = id->mnr;
  
@@ -427,19 +436,19 @@ static int nvme_nvm_setup_20(struct nvme_nvm_id20 *id,

  static int nvme_nvm_identity(struct nvm_dev *nvmdev)
  {
struct nvme_ns *ns = nvmdev->q->queuedata;
-   struct nvme_nvm_id12 *id;
+   struct nvme_nvm_id *nvme_nvm_id;
struct nvme_nvm_command c = {};
int ret;
  
  	c.identity.opcode = nvme_nvm_admin_identity;

c.identity.nsid = cpu_to_le32(ns->head->ns_id);
  
-	id = kmalloc(sizeof(struct nvme_nvm_id12), GFP_KERNEL);

-   if (!id)
+   nvme_nvm_id = kmalloc(sizeof(struct nvme_nvm_id), GFP_KERNEL);
+   if (!nvme_nvm_id)
return -ENOMEM;
  
  	ret = nvme_submit_sync_cmd(ns->ctrl->admin_q, (struct nvme_command *),

-   id, sizeof(struct nvme_nvm_id12));
+   nvme_nvm_id, sizeof(struct nvme_nvm_id));
if (ret) {
ret = -EIO;
goto out;
@@ -449,22 +458,21 @@ static int nvme_nvm_identity(struct nvm_dev *nvmdev)
 * The 1.2 and 2.0 specifications share the first byte in their geometry
 * command to make it possible to know what version a device implements.
 */
-   switch (id->ver_id) {
+   switch (nvme_nvm_id->ver_id) {
case 1:
-   ret = nvme_nvm_setup_12(id, >dev_geo);
+   ret = nvme_nvm_setup_12(nvme_nvm_id, >dev_geo);
break;
case 2:
-   ret = nvme_nvm_setup_20((struct nvme_nvm_id20 *)id,
-   >dev_geo);
+   ret = nvme_nvm_setup_20(nvme_nvm_id, >dev_geo);
break;
default:
dev_err(ns->ctrl->device, "OCSSD revision not supported (%d)\n",
-   id->ver_id);
+   nvme_nvm_id->ver_id);
ret = -EINVAL;
}
  
  out:

-   kfree(id);
+   kfree(nvme_nvm_id);
return ret;
  }
  



Thanks for another way to represent it. I want to keep the original 
path. If we are going that down road, then one should maybe look into 
unifying the "three" data structures, and have the version as the base 
property and the others in each their sub data structure.


Re: [PATCH 09/20] lightnvm: use generic identify structure

2018-02-21 Thread Matias Bjørling

On 02/21/2018 10:26 AM, Javier González wrote:

Create a generic identify structure to collect the identify information
before knowing the spec. version. This forces different version paths to
cast the structure to their spec structure, thus making the code less
error prone and more maintainable.

Signed-off-by: Javier González 
---
  drivers/nvme/host/lightnvm.c | 32 
  1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
index 9c1f8225c4e1..70dc4740f0d3 100644
--- a/drivers/nvme/host/lightnvm.c
+++ b/drivers/nvme/host/lightnvm.c
@@ -170,6 +170,12 @@ struct nvme_nvm_id12 {
__u8resv2[2880];
  } __packed;
  
+/* Generic identification structure */

+struct nvme_nvm_id {
+   __u8ver_id;
+   __u8resv[4095];
+} __packed;
+
  struct nvme_nvm_bb_tbl {
__u8tblid[4];
__le16  verid;
@@ -279,9 +285,10 @@ static void nvme_nvm_set_addr_12(struct nvm_addr_format_12 
*dst,
dst->sec_mask = ((1ULL << dst->sec_len) - 1) << dst->sec_offset;
  }
  
-static int nvme_nvm_setup_12(struct nvme_nvm_id12 *id,

+static int nvme_nvm_setup_12(struct nvme_nvm_id *gen_id,
 struct nvm_dev_geo *dev_geo)
  {
+   struct nvme_nvm_id12 *id = (struct nvme_nvm_id12 *)gen_id;
struct nvme_nvm_id12_grp *src;
int sec_per_pg, sec_per_pl, pg_per_blk;
  
@@ -380,9 +387,11 @@ static void nvme_nvm_set_addr_20(struct nvm_addr_format *dst,

dst->sec_mask = ((1ULL << dst->sec_len) - 1) << dst->sec_offset;
  }
  
-static int nvme_nvm_setup_20(struct nvme_nvm_id20 *id,

+static int nvme_nvm_setup_20(struct nvme_nvm_id *gen_id,
 struct nvm_dev_geo *dev_geo)
  {
+   struct nvme_nvm_id20 *id = (struct nvme_nvm_id20 *)gen_id;
+
dev_geo->major_ver_id = id->mjr;
dev_geo->minor_ver_id = id->mnr;
  
@@ -427,19 +436,19 @@ static int nvme_nvm_setup_20(struct nvme_nvm_id20 *id,

  static int nvme_nvm_identity(struct nvm_dev *nvmdev)
  {
struct nvme_ns *ns = nvmdev->q->queuedata;
-   struct nvme_nvm_id12 *id;
+   struct nvme_nvm_id *nvme_nvm_id;
struct nvme_nvm_command c = {};
int ret;
  
  	c.identity.opcode = nvme_nvm_admin_identity;

c.identity.nsid = cpu_to_le32(ns->head->ns_id);
  
-	id = kmalloc(sizeof(struct nvme_nvm_id12), GFP_KERNEL);

-   if (!id)
+   nvme_nvm_id = kmalloc(sizeof(struct nvme_nvm_id), GFP_KERNEL);
+   if (!nvme_nvm_id)
return -ENOMEM;
  
  	ret = nvme_submit_sync_cmd(ns->ctrl->admin_q, (struct nvme_command *),

-   id, sizeof(struct nvme_nvm_id12));
+   nvme_nvm_id, sizeof(struct nvme_nvm_id));
if (ret) {
ret = -EIO;
goto out;
@@ -449,22 +458,21 @@ static int nvme_nvm_identity(struct nvm_dev *nvmdev)
 * The 1.2 and 2.0 specifications share the first byte in their geometry
 * command to make it possible to know what version a device implements.
 */
-   switch (id->ver_id) {
+   switch (nvme_nvm_id->ver_id) {
case 1:
-   ret = nvme_nvm_setup_12(id, >dev_geo);
+   ret = nvme_nvm_setup_12(nvme_nvm_id, >dev_geo);
break;
case 2:
-   ret = nvme_nvm_setup_20((struct nvme_nvm_id20 *)id,
-   >dev_geo);
+   ret = nvme_nvm_setup_20(nvme_nvm_id, >dev_geo);
break;
default:
dev_err(ns->ctrl->device, "OCSSD revision not supported (%d)\n",
-   id->ver_id);
+   nvme_nvm_id->ver_id);
ret = -EINVAL;
}
  
  out:

-   kfree(id);
+   kfree(nvme_nvm_id);
return ret;
  }
  



Thanks for another way to represent it. I want to keep the original 
path. If we are going that down road, then one should maybe look into 
unifying the "three" data structures, and have the version as the base 
property and the others in each their sub data structure.


[PATCH v9 0/7] Address error and recovery for AER and DPC

2018-02-21 Thread Oza Pawandeep
This patch set brings in error handling support for DPC

The current implementation of AER and error message broadcasting to the
EP driver is tightly coupled and limited to AER service driver.
It is important to factor out broadcasting and other link handling
callbacks. So that not only when AER gets triggered, but also when DPC get
triggered (for e.g. ERR_FATAL), callbacks are handled appropriately.

DPC should enumerate the devices after recovering the link, which is
achieved by implementing error_resume callback.

Changes since v8:
Fixed Kbuild errors.
Changes since v7:
Rebased the code on pci master.
> https://kernel.googlesource.com/pub/scm/linux/kernel/git/helgaas/pci
Changes since v6:
Sinan's and Stefan's comments implemented.
> reordered patch 6 and 7
> cleaned up
Changes since v5:
Sinan's and Keith's comments incorporated.
> made separate patch for mutex
> unified error repotting codes into driver/pci/pci.h
> got rid of wait link active/inactive and
  made generic function in driver/pci/pci.c
Changes since v4:
Bjorn's comments incorporated.
> Renamed only do_recovery.
> moved the things more locally to drivers/pci/pci.h
Changes since v3:
Bjorn's comments incorporated.
> Made separate patch renaming generic pci_err.c
> Introduce pci_err.h to contain all the error types and recovery
> removed all the dependencies on pci.h
Changes since v2:
Based on feedback from Keith:
"
When DPC is triggered due to receipt of an uncorrectable error Message,
the Requester ID from the Message is recorded in the DPC Error
Source ID register and that Message is discarded and not forwarded Upstream.
"
Removed the patch where AER checks if DPC service is active
Changes since v1:
Kbuild errors fixed:
> pci_find_dpc_dev made static
> ras_event.h updated
> pci_find_aer_service call with CONFIG check
> pci_find_dpc_service call with CONFIG check

Oza Pawandeep (7):
  PCI/AER: Rename error recovery to generic pci naming
  PCI/AER: factor out error reporting from AER
  PCI/ERR: add mutex to synchronize recovery
  PCI/DPC: Unify and plumb error handling into DPC
  PCI/AER: Unify aer error defines at single space
  PCI/DPC: Enumerate the devices after DPC trigger event
  PCI: Unify wait for link active into generic pci

 drivers/acpi/apei/ghes.c   |   1 +
 drivers/pci/hotplug/pciehp_hpc.c   |  21 +-
 drivers/pci/pci.c  |  39 +++-
 drivers/pci/pci.h  |  11 +
 drivers/pci/pcie/Makefile  |   2 +-
 drivers/pci/pcie/aer/aerdrv.h  |  30 ---
 drivers/pci/pcie/aer/aerdrv_core.c | 293 +-
 drivers/pci/pcie/aer/aerdrv_errprint.c |   1 +
 drivers/pci/pcie/pcie-dpc.c| 115 ++-
 drivers/pci/pcie/pcie-err.c| 366 +
 drivers/pci/pcie/portdrv.h |   2 +
 include/linux/aer.h|   4 -
 include/linux/pci.h|   1 +
 13 files changed, 534 insertions(+), 352 deletions(-)
 create mode 100644 drivers/pci/pcie/pcie-err.c

-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm 
Technologies, Inc.,
a Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux 
Foundation Collaborative Project.



[PATCH v9 0/7] Address error and recovery for AER and DPC

2018-02-21 Thread Oza Pawandeep
This patch set brings in error handling support for DPC

The current implementation of AER and error message broadcasting to the
EP driver is tightly coupled and limited to AER service driver.
It is important to factor out broadcasting and other link handling
callbacks. So that not only when AER gets triggered, but also when DPC get
triggered (for e.g. ERR_FATAL), callbacks are handled appropriately.

DPC should enumerate the devices after recovering the link, which is
achieved by implementing error_resume callback.

Changes since v8:
Fixed Kbuild errors.
Changes since v7:
Rebased the code on pci master.
> https://kernel.googlesource.com/pub/scm/linux/kernel/git/helgaas/pci
Changes since v6:
Sinan's and Stefan's comments implemented.
> reordered patch 6 and 7
> cleaned up
Changes since v5:
Sinan's and Keith's comments incorporated.
> made separate patch for mutex
> unified error repotting codes into driver/pci/pci.h
> got rid of wait link active/inactive and
  made generic function in driver/pci/pci.c
Changes since v4:
Bjorn's comments incorporated.
> Renamed only do_recovery.
> moved the things more locally to drivers/pci/pci.h
Changes since v3:
Bjorn's comments incorporated.
> Made separate patch renaming generic pci_err.c
> Introduce pci_err.h to contain all the error types and recovery
> removed all the dependencies on pci.h
Changes since v2:
Based on feedback from Keith:
"
When DPC is triggered due to receipt of an uncorrectable error Message,
the Requester ID from the Message is recorded in the DPC Error
Source ID register and that Message is discarded and not forwarded Upstream.
"
Removed the patch where AER checks if DPC service is active
Changes since v1:
Kbuild errors fixed:
> pci_find_dpc_dev made static
> ras_event.h updated
> pci_find_aer_service call with CONFIG check
> pci_find_dpc_service call with CONFIG check

Oza Pawandeep (7):
  PCI/AER: Rename error recovery to generic pci naming
  PCI/AER: factor out error reporting from AER
  PCI/ERR: add mutex to synchronize recovery
  PCI/DPC: Unify and plumb error handling into DPC
  PCI/AER: Unify aer error defines at single space
  PCI/DPC: Enumerate the devices after DPC trigger event
  PCI: Unify wait for link active into generic pci

 drivers/acpi/apei/ghes.c   |   1 +
 drivers/pci/hotplug/pciehp_hpc.c   |  21 +-
 drivers/pci/pci.c  |  39 +++-
 drivers/pci/pci.h  |  11 +
 drivers/pci/pcie/Makefile  |   2 +-
 drivers/pci/pcie/aer/aerdrv.h  |  30 ---
 drivers/pci/pcie/aer/aerdrv_core.c | 293 +-
 drivers/pci/pcie/aer/aerdrv_errprint.c |   1 +
 drivers/pci/pcie/pcie-dpc.c| 115 ++-
 drivers/pci/pcie/pcie-err.c| 366 +
 drivers/pci/pcie/portdrv.h |   2 +
 include/linux/aer.h|   4 -
 include/linux/pci.h|   1 +
 13 files changed, 534 insertions(+), 352 deletions(-)
 create mode 100644 drivers/pci/pcie/pcie-err.c

-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm 
Technologies, Inc.,
a Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux 
Foundation Collaborative Project.



[PATCH v9 1/7] PCI/AER: Rename error recovery to generic pci naming

2018-02-21 Thread Oza Pawandeep
This patch renames error recovery to generic name with pci prefix

Signed-off-by: Oza Pawandeep 

diff --git a/drivers/pci/pcie/aer/aerdrv_core.c 
b/drivers/pci/pcie/aer/aerdrv_core.c
index a4bfea5..306bf2f 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -478,7 +478,7 @@ static pci_ers_result_t reset_link(struct pci_dev *dev)
 }
 
 /**
- * do_recovery - handle nonfatal/fatal error recovery process
+ * pci_do_recovery - handle nonfatal/fatal error recovery process
  * @dev: pointer to a pci_dev data structure of agent detecting an error
  * @severity: error severity type
  *
@@ -486,7 +486,7 @@ static pci_ers_result_t reset_link(struct pci_dev *dev)
  * error detected message to all downstream drivers within a hierarchy in
  * question and return the returned code.
  */
-static void do_recovery(struct pci_dev *dev, int severity)
+static void pci_do_recovery(struct pci_dev *dev, int severity)
 {
pci_ers_result_t status, result = PCI_ERS_RESULT_RECOVERED;
enum pci_channel_state state;
@@ -566,7 +566,7 @@ static void handle_error_source(struct pcie_device *aerdev,
pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS,
info->status);
} else
-   do_recovery(dev, info->severity);
+   pci_do_recovery(dev, info->severity);
 }
 
 #ifdef CONFIG_ACPI_APEI_PCIEAER
@@ -631,7 +631,7 @@ static void aer_recover_work_func(struct work_struct *work)
}
cper_print_aer(pdev, entry.severity, entry.regs);
if (entry.severity != AER_CORRECTABLE)
-   do_recovery(pdev, entry.severity);
+   pci_do_recovery(pdev, entry.severity);
pci_dev_put(pdev);
}
 }
-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm 
Technologies, Inc.,
a Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux 
Foundation Collaborative Project.



[PATCH v9 1/7] PCI/AER: Rename error recovery to generic pci naming

2018-02-21 Thread Oza Pawandeep
This patch renames error recovery to generic name with pci prefix

Signed-off-by: Oza Pawandeep 

diff --git a/drivers/pci/pcie/aer/aerdrv_core.c 
b/drivers/pci/pcie/aer/aerdrv_core.c
index a4bfea5..306bf2f 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -478,7 +478,7 @@ static pci_ers_result_t reset_link(struct pci_dev *dev)
 }
 
 /**
- * do_recovery - handle nonfatal/fatal error recovery process
+ * pci_do_recovery - handle nonfatal/fatal error recovery process
  * @dev: pointer to a pci_dev data structure of agent detecting an error
  * @severity: error severity type
  *
@@ -486,7 +486,7 @@ static pci_ers_result_t reset_link(struct pci_dev *dev)
  * error detected message to all downstream drivers within a hierarchy in
  * question and return the returned code.
  */
-static void do_recovery(struct pci_dev *dev, int severity)
+static void pci_do_recovery(struct pci_dev *dev, int severity)
 {
pci_ers_result_t status, result = PCI_ERS_RESULT_RECOVERED;
enum pci_channel_state state;
@@ -566,7 +566,7 @@ static void handle_error_source(struct pcie_device *aerdev,
pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS,
info->status);
} else
-   do_recovery(dev, info->severity);
+   pci_do_recovery(dev, info->severity);
 }
 
 #ifdef CONFIG_ACPI_APEI_PCIEAER
@@ -631,7 +631,7 @@ static void aer_recover_work_func(struct work_struct *work)
}
cper_print_aer(pdev, entry.severity, entry.regs);
if (entry.severity != AER_CORRECTABLE)
-   do_recovery(pdev, entry.severity);
+   pci_do_recovery(pdev, entry.severity);
pci_dev_put(pdev);
}
 }
-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm 
Technologies, Inc.,
a Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux 
Foundation Collaborative Project.



Re: [PATCH 08/20] lightnvm: complete geo structure with maxoc*

2018-02-21 Thread Matias Bjørling

On 02/21/2018 10:26 AM, Javier González wrote:

Complete the generic geometry structure with the maxoc and maxocpu
felds, present in the 2.0 spec.

Signed-off-by: Javier González 
---
  drivers/nvme/host/lightnvm.c | 4 
  include/linux/lightnvm.h | 2 ++
  2 files changed, 6 insertions(+)

diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
index cca32da05316..9c1f8225c4e1 100644
--- a/drivers/nvme/host/lightnvm.c
+++ b/drivers/nvme/host/lightnvm.c
@@ -318,6 +318,8 @@ static int nvme_nvm_setup_12(struct nvme_nvm_id12 *id,
dev_geo->c.ws_min = sec_per_pg;
dev_geo->c.ws_opt = sec_per_pg;
dev_geo->c.mw_cunits = 8;/* default to MLC safe values */
+   dev_geo->c.maxoc = dev_geo->all_luns; /* default to 1 chunk per LUN 
*/
+   dev_geo->c.maxocpu = 1;  /* default to 1 chunk per 
LUN */


One can't assume that it is 1 open chunk per lun. If you need this for 
specific hardware, make a quirk for it.


  
  	dev_geo->c.mccap = le32_to_cpu(src->mccap);
  
@@ -405,6 +407,8 @@ static int nvme_nvm_setup_20(struct nvme_nvm_id20 *id,

dev_geo->c.ws_min = le32_to_cpu(id->ws_min);
dev_geo->c.ws_opt = le32_to_cpu(id->ws_opt);
dev_geo->c.mw_cunits = le32_to_cpu(id->mw_cunits);
+   dev_geo->c.maxoc = le32_to_cpu(id->maxoc);
+   dev_geo->c.maxocpu = le32_to_cpu(id->maxocpu);
  
  	dev_geo->c.mccap = le32_to_cpu(id->mccap);
  
diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h

index ccc5faa63cb7..e1c4292ea33d 100644
--- a/include/linux/lightnvm.h
+++ b/include/linux/lightnvm.h
@@ -215,6 +215,8 @@ struct nvm_common_geo {
u32 ws_min; /* minimum write size */
u32 ws_opt; /* optimal write size */
u32 mw_cunits;  /* distance required for successful read */
+   u32 maxoc;  /* maximum open chunks */
+   u32 maxocpu;/* maximum open chunks per parallel unit */
  
  	/* device capabilities */

u32 mccap;





Re: [PATCH 08/20] lightnvm: complete geo structure with maxoc*

2018-02-21 Thread Matias Bjørling

On 02/21/2018 10:26 AM, Javier González wrote:

Complete the generic geometry structure with the maxoc and maxocpu
felds, present in the 2.0 spec.

Signed-off-by: Javier González 
---
  drivers/nvme/host/lightnvm.c | 4 
  include/linux/lightnvm.h | 2 ++
  2 files changed, 6 insertions(+)

diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
index cca32da05316..9c1f8225c4e1 100644
--- a/drivers/nvme/host/lightnvm.c
+++ b/drivers/nvme/host/lightnvm.c
@@ -318,6 +318,8 @@ static int nvme_nvm_setup_12(struct nvme_nvm_id12 *id,
dev_geo->c.ws_min = sec_per_pg;
dev_geo->c.ws_opt = sec_per_pg;
dev_geo->c.mw_cunits = 8;/* default to MLC safe values */
+   dev_geo->c.maxoc = dev_geo->all_luns; /* default to 1 chunk per LUN 
*/
+   dev_geo->c.maxocpu = 1;  /* default to 1 chunk per 
LUN */


One can't assume that it is 1 open chunk per lun. If you need this for 
specific hardware, make a quirk for it.


  
  	dev_geo->c.mccap = le32_to_cpu(src->mccap);
  
@@ -405,6 +407,8 @@ static int nvme_nvm_setup_20(struct nvme_nvm_id20 *id,

dev_geo->c.ws_min = le32_to_cpu(id->ws_min);
dev_geo->c.ws_opt = le32_to_cpu(id->ws_opt);
dev_geo->c.mw_cunits = le32_to_cpu(id->mw_cunits);
+   dev_geo->c.maxoc = le32_to_cpu(id->maxoc);
+   dev_geo->c.maxocpu = le32_to_cpu(id->maxocpu);
  
  	dev_geo->c.mccap = le32_to_cpu(id->mccap);
  
diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h

index ccc5faa63cb7..e1c4292ea33d 100644
--- a/include/linux/lightnvm.h
+++ b/include/linux/lightnvm.h
@@ -215,6 +215,8 @@ struct nvm_common_geo {
u32 ws_min; /* minimum write size */
u32 ws_opt; /* optimal write size */
u32 mw_cunits;  /* distance required for successful read */
+   u32 maxoc;  /* maximum open chunks */
+   u32 maxocpu;/* maximum open chunks per parallel unit */
  
  	/* device capabilities */

u32 mccap;





[BUGFIX PATCH v2.1] tracing: probeevent: Fix to support minus offset from symbol

2018-02-21 Thread Masami Hiramatsu
In Documentation/trace/kprobetrace.txt, it says

 @SYM[+|-offs] : Fetch memory at SYM +|- offs (SYM should be a data symbol)

However, the parser doesn't parse minus offset correctly, since
commit 2fba0c8867af ("tracing/kprobes: Fix probe offset to be
unsigned") drops minus ("-") offset support for kprobe probe
address usage.

This fixes the traceprobe_split_symbol_offset() to parse minus
offset again with checking the offset range, and add a minus
offset check in kprobe probe address usage.

Fixes: 2fba0c8867af ("tracing/kprobes: Fix probe offset to be unsigned")
Signed-off-by: Masami Hiramatsu 
---
 Changes in v2.1:
  - Fix to ensure the offset value is less than LONG_MAX.
  - Fail if the offset is minus when traceprobe_split_symbol_offset()
is used for the probe address.
  - Add Fixes tag.
---
 kernel/trace/trace_kprobe.c |4 ++--
 kernel/trace/trace_probe.c  |   15 ++-
 kernel/trace/trace_probe.h  |2 +-
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 5ce9b8cf7be3..b5b1d8aa47d6 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -667,7 +667,7 @@ static int create_trace_kprobe(int argc, char **argv)
char *symbol = NULL, *event = NULL, *group = NULL;
int maxactive = 0;
char *arg;
-   unsigned long offset = 0;
+   long offset = 0;
void *addr = NULL;
char buf[MAX_EVENT_NAME_LEN];
 
@@ -755,7 +755,7 @@ static int create_trace_kprobe(int argc, char **argv)
symbol = argv[1];
/* TODO: support .init module functions */
ret = traceprobe_split_symbol_offset(symbol, );
-   if (ret) {
+   if (ret || offset < 0) {
pr_info("Failed to parse either an address or a 
symbol.\n");
return ret;
}
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index d59357308677..ec3856147fdd 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -320,21 +320,26 @@ static fetch_func_t get_fetch_size_function(const struct 
fetch_type *type,
 }
 
 /* Split symbol and offset. */
-int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset)
+int traceprobe_split_symbol_offset(char *symbol, long *offset)
 {
+   unsigned long ul;
char *tmp;
int ret;
 
if (!offset)
return -EINVAL;
 
-   tmp = strchr(symbol, '+');
+   tmp = strpbrk(symbol, "+-");
if (tmp) {
-   /* skip sign because kstrtoul doesn't accept '+' */
-   ret = kstrtoul(tmp + 1, 0, offset);
+   ret = kstrtoul(tmp + 1, 0, );
if (ret)
return ret;
-
+   if (ul > LONG_MAX)
+   return -E2BIG;
+   if (*tmp == '-')
+   *offset = -ul;
+   else
+   *offset = ul;
*tmp = '\0';
} else
*offset = 0;
diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h
index 0745f895f780..75daff22ccea 100644
--- a/kernel/trace/trace_probe.h
+++ b/kernel/trace/trace_probe.h
@@ -365,7 +365,7 @@ extern int traceprobe_conflict_field_name(const char *name,
 extern void traceprobe_update_arg(struct probe_arg *arg);
 extern void traceprobe_free_probe_arg(struct probe_arg *arg);
 
-extern int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset);
+extern int traceprobe_split_symbol_offset(char *symbol, long *offset);
 
 /* Sum up total data length for dynamic arraies (strings) */
 static nokprobe_inline int



[BUGFIX PATCH v2.1] tracing: probeevent: Fix to support minus offset from symbol

2018-02-21 Thread Masami Hiramatsu
In Documentation/trace/kprobetrace.txt, it says

 @SYM[+|-offs] : Fetch memory at SYM +|- offs (SYM should be a data symbol)

However, the parser doesn't parse minus offset correctly, since
commit 2fba0c8867af ("tracing/kprobes: Fix probe offset to be
unsigned") drops minus ("-") offset support for kprobe probe
address usage.

This fixes the traceprobe_split_symbol_offset() to parse minus
offset again with checking the offset range, and add a minus
offset check in kprobe probe address usage.

Fixes: 2fba0c8867af ("tracing/kprobes: Fix probe offset to be unsigned")
Signed-off-by: Masami Hiramatsu 
---
 Changes in v2.1:
  - Fix to ensure the offset value is less than LONG_MAX.
  - Fail if the offset is minus when traceprobe_split_symbol_offset()
is used for the probe address.
  - Add Fixes tag.
---
 kernel/trace/trace_kprobe.c |4 ++--
 kernel/trace/trace_probe.c  |   15 ++-
 kernel/trace/trace_probe.h  |2 +-
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 5ce9b8cf7be3..b5b1d8aa47d6 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -667,7 +667,7 @@ static int create_trace_kprobe(int argc, char **argv)
char *symbol = NULL, *event = NULL, *group = NULL;
int maxactive = 0;
char *arg;
-   unsigned long offset = 0;
+   long offset = 0;
void *addr = NULL;
char buf[MAX_EVENT_NAME_LEN];
 
@@ -755,7 +755,7 @@ static int create_trace_kprobe(int argc, char **argv)
symbol = argv[1];
/* TODO: support .init module functions */
ret = traceprobe_split_symbol_offset(symbol, );
-   if (ret) {
+   if (ret || offset < 0) {
pr_info("Failed to parse either an address or a 
symbol.\n");
return ret;
}
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index d59357308677..ec3856147fdd 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -320,21 +320,26 @@ static fetch_func_t get_fetch_size_function(const struct 
fetch_type *type,
 }
 
 /* Split symbol and offset. */
-int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset)
+int traceprobe_split_symbol_offset(char *symbol, long *offset)
 {
+   unsigned long ul;
char *tmp;
int ret;
 
if (!offset)
return -EINVAL;
 
-   tmp = strchr(symbol, '+');
+   tmp = strpbrk(symbol, "+-");
if (tmp) {
-   /* skip sign because kstrtoul doesn't accept '+' */
-   ret = kstrtoul(tmp + 1, 0, offset);
+   ret = kstrtoul(tmp + 1, 0, );
if (ret)
return ret;
-
+   if (ul > LONG_MAX)
+   return -E2BIG;
+   if (*tmp == '-')
+   *offset = -ul;
+   else
+   *offset = ul;
*tmp = '\0';
} else
*offset = 0;
diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h
index 0745f895f780..75daff22ccea 100644
--- a/kernel/trace/trace_probe.h
+++ b/kernel/trace/trace_probe.h
@@ -365,7 +365,7 @@ extern int traceprobe_conflict_field_name(const char *name,
 extern void traceprobe_update_arg(struct probe_arg *arg);
 extern void traceprobe_free_probe_arg(struct probe_arg *arg);
 
-extern int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset);
+extern int traceprobe_split_symbol_offset(char *symbol, long *offset);
 
 /* Sum up total data length for dynamic arraies (strings) */
 static nokprobe_inline int



Re: [PATCH 01/20] lightnvm: simplify geometry structure.

2018-02-21 Thread Javier Gonzalez

> On 22 Feb 2018, at 08.25, Matias Bjørling  wrote:
> 
> On 02/21/2018 10:26 AM, Javier González wrote:
>> Currently, the device geometry is stored redundantly in the nvm_id and
>> nvm_geo structures at a device level. Moreover, when instantiating
>> targets on a specific number of LUNs, these structures are replicated
>> and manually modified to fit the instance channel and LUN partitioning.
>> Instead, create a generic geometry around two base structures:
>> nvm_dev_geo, which describes the geometry of the whole device and
>> nvm_geo, which describes the geometry of the instance. Since these share
>> a big part of the geometry, create a nvm_common_geo structure that keeps
>> the static geoometry values that are shared across instances.
>> As we introduce support for 2.0, these structures allow to abstract
>> spec. specific values and present a common geometry to targets.
>> Signed-off-by: Javier González 
>> ---
>>  drivers/lightnvm/core.c  | 137 +++-
>>  drivers/lightnvm/pblk-core.c |  16 +-
>>  drivers/lightnvm/pblk-gc.c   |   2 +-
>>  drivers/lightnvm/pblk-init.c | 123 +++---
>>  drivers/lightnvm/pblk-read.c |   2 +-
>>  drivers/lightnvm/pblk-recovery.c |  14 +-
>>  drivers/lightnvm/pblk-rl.c   |   2 +-
>>  drivers/lightnvm/pblk-sysfs.c|  39 +++--
>>  drivers/lightnvm/pblk-write.c|   2 +-
>>  drivers/lightnvm/pblk.h  |  93 +--
>>  drivers/nvme/host/lightnvm.c | 339 
>> +++
>>  include/linux/lightnvm.h | 204 ---
>>  12 files changed, 514 insertions(+), 459 deletions(-)
>> diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
>> index 689c97b97775..42596afdf64c 100644
>> --- a/drivers/lightnvm/core.c
>> +++ b/drivers/lightnvm/core.c
>> @@ -111,6 +111,7 @@ static void nvm_release_luns_err(struct nvm_dev *dev, 
>> int lun_begin,
>>  static void nvm_remove_tgt_dev(struct nvm_tgt_dev *tgt_dev, int clear)
>>  {
>>  struct nvm_dev *dev = tgt_dev->parent;
>> +struct nvm_dev_geo *dev_geo = >dev_geo;
>>  struct nvm_dev_map *dev_map = tgt_dev->map;
>>  int i, j;
>>  @@ -122,7 +123,7 @@ static void nvm_remove_tgt_dev(struct nvm_tgt_dev 
>> *tgt_dev, int clear)
>>  if (clear) {
>>  for (j = 0; j < ch_map->nr_luns; j++) {
>>  int lun = j + lun_offs[j];
>> -int lunid = (ch * dev->geo.nr_luns) + lun;
>> +int lunid = (ch * dev_geo->nr_luns) + lun;
>>  WARN_ON(!test_and_clear_bit(lunid,
>>  dev->lun_map));
>> @@ -143,19 +144,20 @@ static struct nvm_tgt_dev *nvm_create_tgt_dev(struct 
>> nvm_dev *dev,
>>u16 lun_begin, u16 lun_end,
>>u16 op)
>>  {
>> +struct nvm_dev_geo *dev_geo = >dev_geo;
>>  struct nvm_tgt_dev *tgt_dev = NULL;
>>  struct nvm_dev_map *dev_rmap = dev->rmap;
>>  struct nvm_dev_map *dev_map;
>>  struct ppa_addr *luns;
>>  int nr_luns = lun_end - lun_begin + 1;
>>  int luns_left = nr_luns;
>> -int nr_chnls = nr_luns / dev->geo.nr_luns;
>> -int nr_chnls_mod = nr_luns % dev->geo.nr_luns;
>> -int bch = lun_begin / dev->geo.nr_luns;
>> -int blun = lun_begin % dev->geo.nr_luns;
>> +int nr_chnls = nr_luns / dev_geo->nr_luns;
>> +int nr_chnls_mod = nr_luns % dev_geo->nr_luns;
>> +int bch = lun_begin / dev_geo->nr_luns;
>> +int blun = lun_begin % dev_geo->nr_luns;
>>  int lunid = 0;
>>  int lun_balanced = 1;
>> -int prev_nr_luns;
>> +int sec_per_lun, prev_nr_luns;
>>  int i, j;
>>  nr_chnls = (nr_chnls_mod == 0) ? nr_chnls : nr_chnls + 1;
>> @@ -173,15 +175,15 @@ static struct nvm_tgt_dev *nvm_create_tgt_dev(struct 
>> nvm_dev *dev,
>>  if (!luns)
>>  goto err_luns;
>>  -   prev_nr_luns = (luns_left > dev->geo.nr_luns) ?
>> -dev->geo.nr_luns : luns_left;
>> +prev_nr_luns = (luns_left > dev_geo->nr_luns) ?
>> +dev_geo->nr_luns : luns_left;
>>  for (i = 0; i < nr_chnls; i++) {
>>  struct nvm_ch_map *ch_rmap = _rmap->chnls[i + bch];
>>  int *lun_roffs = ch_rmap->lun_offs;
>>  struct nvm_ch_map *ch_map = _map->chnls[i];
>>  int *lun_offs;
>> -int luns_in_chnl = (luns_left > dev->geo.nr_luns) ?
>> -dev->geo.nr_luns : luns_left;
>> +int luns_in_chnl = (luns_left > dev_geo->nr_luns) ?
>> +dev_geo->nr_luns : luns_left;
>>  if (lun_balanced && prev_nr_luns != luns_in_chnl)
>>  lun_balanced = 0;
>> @@ -215,18 +217,22 @@ static struct nvm_tgt_dev *nvm_create_tgt_dev(struct 
>> nvm_dev *dev,
>>

Re: [PATCH 01/20] lightnvm: simplify geometry structure.

2018-02-21 Thread Javier Gonzalez

> On 22 Feb 2018, at 08.25, Matias Bjørling  wrote:
> 
> On 02/21/2018 10:26 AM, Javier González wrote:
>> Currently, the device geometry is stored redundantly in the nvm_id and
>> nvm_geo structures at a device level. Moreover, when instantiating
>> targets on a specific number of LUNs, these structures are replicated
>> and manually modified to fit the instance channel and LUN partitioning.
>> Instead, create a generic geometry around two base structures:
>> nvm_dev_geo, which describes the geometry of the whole device and
>> nvm_geo, which describes the geometry of the instance. Since these share
>> a big part of the geometry, create a nvm_common_geo structure that keeps
>> the static geoometry values that are shared across instances.
>> As we introduce support for 2.0, these structures allow to abstract
>> spec. specific values and present a common geometry to targets.
>> Signed-off-by: Javier González 
>> ---
>>  drivers/lightnvm/core.c  | 137 +++-
>>  drivers/lightnvm/pblk-core.c |  16 +-
>>  drivers/lightnvm/pblk-gc.c   |   2 +-
>>  drivers/lightnvm/pblk-init.c | 123 +++---
>>  drivers/lightnvm/pblk-read.c |   2 +-
>>  drivers/lightnvm/pblk-recovery.c |  14 +-
>>  drivers/lightnvm/pblk-rl.c   |   2 +-
>>  drivers/lightnvm/pblk-sysfs.c|  39 +++--
>>  drivers/lightnvm/pblk-write.c|   2 +-
>>  drivers/lightnvm/pblk.h  |  93 +--
>>  drivers/nvme/host/lightnvm.c | 339 
>> +++
>>  include/linux/lightnvm.h | 204 ---
>>  12 files changed, 514 insertions(+), 459 deletions(-)
>> diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
>> index 689c97b97775..42596afdf64c 100644
>> --- a/drivers/lightnvm/core.c
>> +++ b/drivers/lightnvm/core.c
>> @@ -111,6 +111,7 @@ static void nvm_release_luns_err(struct nvm_dev *dev, 
>> int lun_begin,
>>  static void nvm_remove_tgt_dev(struct nvm_tgt_dev *tgt_dev, int clear)
>>  {
>>  struct nvm_dev *dev = tgt_dev->parent;
>> +struct nvm_dev_geo *dev_geo = >dev_geo;
>>  struct nvm_dev_map *dev_map = tgt_dev->map;
>>  int i, j;
>>  @@ -122,7 +123,7 @@ static void nvm_remove_tgt_dev(struct nvm_tgt_dev 
>> *tgt_dev, int clear)
>>  if (clear) {
>>  for (j = 0; j < ch_map->nr_luns; j++) {
>>  int lun = j + lun_offs[j];
>> -int lunid = (ch * dev->geo.nr_luns) + lun;
>> +int lunid = (ch * dev_geo->nr_luns) + lun;
>>  WARN_ON(!test_and_clear_bit(lunid,
>>  dev->lun_map));
>> @@ -143,19 +144,20 @@ static struct nvm_tgt_dev *nvm_create_tgt_dev(struct 
>> nvm_dev *dev,
>>u16 lun_begin, u16 lun_end,
>>u16 op)
>>  {
>> +struct nvm_dev_geo *dev_geo = >dev_geo;
>>  struct nvm_tgt_dev *tgt_dev = NULL;
>>  struct nvm_dev_map *dev_rmap = dev->rmap;
>>  struct nvm_dev_map *dev_map;
>>  struct ppa_addr *luns;
>>  int nr_luns = lun_end - lun_begin + 1;
>>  int luns_left = nr_luns;
>> -int nr_chnls = nr_luns / dev->geo.nr_luns;
>> -int nr_chnls_mod = nr_luns % dev->geo.nr_luns;
>> -int bch = lun_begin / dev->geo.nr_luns;
>> -int blun = lun_begin % dev->geo.nr_luns;
>> +int nr_chnls = nr_luns / dev_geo->nr_luns;
>> +int nr_chnls_mod = nr_luns % dev_geo->nr_luns;
>> +int bch = lun_begin / dev_geo->nr_luns;
>> +int blun = lun_begin % dev_geo->nr_luns;
>>  int lunid = 0;
>>  int lun_balanced = 1;
>> -int prev_nr_luns;
>> +int sec_per_lun, prev_nr_luns;
>>  int i, j;
>>  nr_chnls = (nr_chnls_mod == 0) ? nr_chnls : nr_chnls + 1;
>> @@ -173,15 +175,15 @@ static struct nvm_tgt_dev *nvm_create_tgt_dev(struct 
>> nvm_dev *dev,
>>  if (!luns)
>>  goto err_luns;
>>  -   prev_nr_luns = (luns_left > dev->geo.nr_luns) ?
>> -dev->geo.nr_luns : luns_left;
>> +prev_nr_luns = (luns_left > dev_geo->nr_luns) ?
>> +dev_geo->nr_luns : luns_left;
>>  for (i = 0; i < nr_chnls; i++) {
>>  struct nvm_ch_map *ch_rmap = _rmap->chnls[i + bch];
>>  int *lun_roffs = ch_rmap->lun_offs;
>>  struct nvm_ch_map *ch_map = _map->chnls[i];
>>  int *lun_offs;
>> -int luns_in_chnl = (luns_left > dev->geo.nr_luns) ?
>> -dev->geo.nr_luns : luns_left;
>> +int luns_in_chnl = (luns_left > dev_geo->nr_luns) ?
>> +dev_geo->nr_luns : luns_left;
>>  if (lun_balanced && prev_nr_luns != luns_in_chnl)
>>  lun_balanced = 0;
>> @@ -215,18 +217,22 @@ static struct nvm_tgt_dev *nvm_create_tgt_dev(struct 
>> nvm_dev *dev,
>>  if (!tgt_dev)
>>  goto 

Re: [PATCH v2] iio:dummy: Replace S_IWUSR by 0200

2018-02-21 Thread Dan Carpenter
On Wed, Feb 21, 2018 at 11:01:50PM +0200, Daniel Baluta wrote:
> On Wed, Feb 21, 2018 at 9:28 PM, Rodrigo Siqueira
>  wrote:
> > This patch fixes the checkpatch.pl warning:
> >
> > drivers/iio/dummy/iio_dummy_evgen.c:151: WARNING: Symbolic permissions
> > 'S_IWUSR' are not preferred. Consider using octal permissions '0200'.
> 
> > ... Why this "..." :)?
> 
> Commit subject could be done better. It is pretty obvious from the code that
> we change S_IWUSR with 0200.
> 
> Better message:
> 
> iio:dummy: Fix poke_evN file permissions

Please stop telling people to say "Fix" when it's not a bug fix...

Also who cares?  The commit message is perfectly clear.

regards,
dan carpenter




Re: [PATCH v2] iio:dummy: Replace S_IWUSR by 0200

2018-02-21 Thread Dan Carpenter
On Wed, Feb 21, 2018 at 11:01:50PM +0200, Daniel Baluta wrote:
> On Wed, Feb 21, 2018 at 9:28 PM, Rodrigo Siqueira
>  wrote:
> > This patch fixes the checkpatch.pl warning:
> >
> > drivers/iio/dummy/iio_dummy_evgen.c:151: WARNING: Symbolic permissions
> > 'S_IWUSR' are not preferred. Consider using octal permissions '0200'.
> 
> > ... Why this "..." :)?
> 
> Commit subject could be done better. It is pretty obvious from the code that
> we change S_IWUSR with 0200.
> 
> Better message:
> 
> iio:dummy: Fix poke_evN file permissions

Please stop telling people to say "Fix" when it's not a bug fix...

Also who cares?  The commit message is perfectly clear.

regards,
dan carpenter




Re: [PATCH 07/20] lightnvm: rename sect_* to sec_*

2018-02-21 Thread Matias Bjørling

On 02/21/2018 10:26 AM, Javier González wrote:

Rename abbreviations for sector from sect_* to sec_* as most of the code
uses this format and it is confusing when using the different
structures.

Signed-off-by: Javier González 
---
  drivers/lightnvm/pblk-init.c  | 8 
  drivers/lightnvm/pblk-sysfs.c | 4 ++--
  drivers/lightnvm/pblk.h   | 8 
  drivers/nvme/host/lightnvm.c  | 8 
  include/linux/lightnvm.h  | 8 
  5 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c
index 455fc63a9409..6bf51ef8f516 100644
--- a/drivers/lightnvm/pblk-init.c
+++ b/drivers/lightnvm/pblk-init.c
@@ -179,16 +179,16 @@ static int pblk_set_addrf_12(struct nvm_geo *geo,
dst->blk_len = src->blk_len;
dst->pg_len = src->pg_len;
dst->pln_len = src->pln_len;
-   dst->sect_len = src->sect_len;
+   dst->sec_len = src->sec_len;
  
-	dst->sect_offset = 0;

-   dst->pln_offset = dst->sect_len;
+   dst->sec_offset = 0;
+   dst->pln_offset = dst->sec_len;
dst->ch_offset = dst->pln_offset + dst->pln_len;
dst->lun_offset = dst->ch_offset + dst->ch_len;
dst->pg_offset = dst->lun_offset + dst->lun_len;
dst->blk_offset = dst->pg_offset + dst->pg_len;
  
-	dst->sec_mask = ((1ULL << dst->sect_len) - 1) << dst->sect_offset;

+   dst->sec_mask = ((1ULL << dst->sec_len) - 1) << dst->sec_offset;
dst->pln_mask = ((1ULL << dst->pln_len) - 1) << dst->pln_offset;
dst->ch_mask = ((1ULL << dst->ch_len) - 1) << dst->ch_offset;
dst->lun_mask = ((1ULL << dst->lun_len) - 1) << dst->lun_offset;
diff --git a/drivers/lightnvm/pblk-sysfs.c b/drivers/lightnvm/pblk-sysfs.c
index 5eb21a279361..81288aa9162a 100644
--- a/drivers/lightnvm/pblk-sysfs.c
+++ b/drivers/lightnvm/pblk-sysfs.c
@@ -128,7 +128,7 @@ static ssize_t pblk_sysfs_ppaf(struct pblk *pblk, char 
*page)
ppaf->blk_offset, ppaf->blk_len,
ppaf->pg_offset, ppaf->pg_len,
ppaf->pln_offset, ppaf->pln_len,
-   ppaf->sect_offset, ppaf->sect_len);
+   ppaf->sec_offset, ppaf->sec_len);
  
  	sz += snprintf(page + sz, PAGE_SIZE - sz,


"device:ch:%d/%d,lun:%d/%d,blk:%d/%d,pg:%d/%d,pl:%d/%d,sec:%d/%d\n",
@@ -137,7 +137,7 @@ static ssize_t pblk_sysfs_ppaf(struct pblk *pblk, char 
*page)
geo_ppaf->blk_offset, geo_ppaf->blk_len,
geo_ppaf->pg_offset, geo_ppaf->pg_len,
geo_ppaf->pln_offset, geo_ppaf->pln_len,
-   geo_ppaf->sect_offset, geo_ppaf->sect_len);
+   geo_ppaf->sec_offset, geo_ppaf->sec_len);
  
  	return sz;

  }
diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h
index 1f32284b0aec..4f7a365436f1 100644
--- a/drivers/lightnvm/pblk.h
+++ b/drivers/lightnvm/pblk.h
@@ -957,7 +957,7 @@ static inline struct ppa_addr addr_to_gen_ppa(struct pblk 
*pblk, u64 paddr,
ppa.g.lun = (paddr & ppaf->lun_mask) >> ppaf->lun_offset;
ppa.g.ch = (paddr & ppaf->ch_mask) >> ppaf->ch_offset;
ppa.g.pl = (paddr & ppaf->pln_mask) >> ppaf->pln_offset;
-   ppa.g.sec = (paddr & ppaf->sec_mask) >> ppaf->sect_offset;
+   ppa.g.sec = (paddr & ppaf->sec_mask) >> ppaf->sec_offset;
  
  	return ppa;

  }
@@ -973,7 +973,7 @@ static inline u64 pblk_dev_ppa_to_line_addr(struct pblk 
*pblk,
paddr |= (u64)p.g.lun << ppaf->lun_offset;
paddr |= (u64)p.g.pg << ppaf->pg_offset;
paddr |= (u64)p.g.pl << ppaf->pln_offset;
-   paddr |= (u64)p.g.sec << ppaf->sect_offset;
+   paddr |= (u64)p.g.sec << ppaf->sec_offset;
  
  	return paddr;

  }
@@ -998,7 +998,7 @@ static inline struct ppa_addr pblk_ppa32_to_ppa64(struct 
pblk *pblk, u32 ppa32)
ppa64.g.blk = (ppa32 & ppaf->blk_mask) >> ppaf->blk_offset;
ppa64.g.pg = (ppa32 & ppaf->pg_mask) >> ppaf->pg_offset;
ppa64.g.pl = (ppa32 & ppaf->pln_mask) >> ppaf->pln_offset;
-   ppa64.g.sec = (ppa32 & ppaf->sec_mask) >> ppaf->sect_offset;
+   ppa64.g.sec = (ppa32 & ppaf->sec_mask) >> ppaf->sec_offset;
}
  
  	return ppa64;

@@ -1022,7 +1022,7 @@ static inline u32 pblk_ppa64_to_ppa32(struct pblk *pblk, 
struct ppa_addr ppa64)
ppa32 |= ppa64.g.blk << ppaf->blk_offset;
ppa32 |= ppa64.g.pg << ppaf->pg_offset;
ppa32 |= ppa64.g.pl << ppaf->pln_offset;
-   ppa32 |= ppa64.g.sec << ppaf->sect_offset;
+   ppa32 |= ppa64.g.sec << ppaf->sec_offset;
}
  
  	return ppa32;

diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
index bd97672e0b4f..cca32da05316 100644
--- a/drivers/nvme/host/lightnvm.c
+++ b/drivers/nvme/host/lightnvm.c
@@ -262,21 +262,21 @@ static void nvme_nvm_set_addr_12(struct 
nvm_addr_format_12 *dst,
  

Re: [PATCH 07/20] lightnvm: rename sect_* to sec_*

2018-02-21 Thread Matias Bjørling

On 02/21/2018 10:26 AM, Javier González wrote:

Rename abbreviations for sector from sect_* to sec_* as most of the code
uses this format and it is confusing when using the different
structures.

Signed-off-by: Javier González 
---
  drivers/lightnvm/pblk-init.c  | 8 
  drivers/lightnvm/pblk-sysfs.c | 4 ++--
  drivers/lightnvm/pblk.h   | 8 
  drivers/nvme/host/lightnvm.c  | 8 
  include/linux/lightnvm.h  | 8 
  5 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c
index 455fc63a9409..6bf51ef8f516 100644
--- a/drivers/lightnvm/pblk-init.c
+++ b/drivers/lightnvm/pblk-init.c
@@ -179,16 +179,16 @@ static int pblk_set_addrf_12(struct nvm_geo *geo,
dst->blk_len = src->blk_len;
dst->pg_len = src->pg_len;
dst->pln_len = src->pln_len;
-   dst->sect_len = src->sect_len;
+   dst->sec_len = src->sec_len;
  
-	dst->sect_offset = 0;

-   dst->pln_offset = dst->sect_len;
+   dst->sec_offset = 0;
+   dst->pln_offset = dst->sec_len;
dst->ch_offset = dst->pln_offset + dst->pln_len;
dst->lun_offset = dst->ch_offset + dst->ch_len;
dst->pg_offset = dst->lun_offset + dst->lun_len;
dst->blk_offset = dst->pg_offset + dst->pg_len;
  
-	dst->sec_mask = ((1ULL << dst->sect_len) - 1) << dst->sect_offset;

+   dst->sec_mask = ((1ULL << dst->sec_len) - 1) << dst->sec_offset;
dst->pln_mask = ((1ULL << dst->pln_len) - 1) << dst->pln_offset;
dst->ch_mask = ((1ULL << dst->ch_len) - 1) << dst->ch_offset;
dst->lun_mask = ((1ULL << dst->lun_len) - 1) << dst->lun_offset;
diff --git a/drivers/lightnvm/pblk-sysfs.c b/drivers/lightnvm/pblk-sysfs.c
index 5eb21a279361..81288aa9162a 100644
--- a/drivers/lightnvm/pblk-sysfs.c
+++ b/drivers/lightnvm/pblk-sysfs.c
@@ -128,7 +128,7 @@ static ssize_t pblk_sysfs_ppaf(struct pblk *pblk, char 
*page)
ppaf->blk_offset, ppaf->blk_len,
ppaf->pg_offset, ppaf->pg_len,
ppaf->pln_offset, ppaf->pln_len,
-   ppaf->sect_offset, ppaf->sect_len);
+   ppaf->sec_offset, ppaf->sec_len);
  
  	sz += snprintf(page + sz, PAGE_SIZE - sz,


"device:ch:%d/%d,lun:%d/%d,blk:%d/%d,pg:%d/%d,pl:%d/%d,sec:%d/%d\n",
@@ -137,7 +137,7 @@ static ssize_t pblk_sysfs_ppaf(struct pblk *pblk, char 
*page)
geo_ppaf->blk_offset, geo_ppaf->blk_len,
geo_ppaf->pg_offset, geo_ppaf->pg_len,
geo_ppaf->pln_offset, geo_ppaf->pln_len,
-   geo_ppaf->sect_offset, geo_ppaf->sect_len);
+   geo_ppaf->sec_offset, geo_ppaf->sec_len);
  
  	return sz;

  }
diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h
index 1f32284b0aec..4f7a365436f1 100644
--- a/drivers/lightnvm/pblk.h
+++ b/drivers/lightnvm/pblk.h
@@ -957,7 +957,7 @@ static inline struct ppa_addr addr_to_gen_ppa(struct pblk 
*pblk, u64 paddr,
ppa.g.lun = (paddr & ppaf->lun_mask) >> ppaf->lun_offset;
ppa.g.ch = (paddr & ppaf->ch_mask) >> ppaf->ch_offset;
ppa.g.pl = (paddr & ppaf->pln_mask) >> ppaf->pln_offset;
-   ppa.g.sec = (paddr & ppaf->sec_mask) >> ppaf->sect_offset;
+   ppa.g.sec = (paddr & ppaf->sec_mask) >> ppaf->sec_offset;
  
  	return ppa;

  }
@@ -973,7 +973,7 @@ static inline u64 pblk_dev_ppa_to_line_addr(struct pblk 
*pblk,
paddr |= (u64)p.g.lun << ppaf->lun_offset;
paddr |= (u64)p.g.pg << ppaf->pg_offset;
paddr |= (u64)p.g.pl << ppaf->pln_offset;
-   paddr |= (u64)p.g.sec << ppaf->sect_offset;
+   paddr |= (u64)p.g.sec << ppaf->sec_offset;
  
  	return paddr;

  }
@@ -998,7 +998,7 @@ static inline struct ppa_addr pblk_ppa32_to_ppa64(struct 
pblk *pblk, u32 ppa32)
ppa64.g.blk = (ppa32 & ppaf->blk_mask) >> ppaf->blk_offset;
ppa64.g.pg = (ppa32 & ppaf->pg_mask) >> ppaf->pg_offset;
ppa64.g.pl = (ppa32 & ppaf->pln_mask) >> ppaf->pln_offset;
-   ppa64.g.sec = (ppa32 & ppaf->sec_mask) >> ppaf->sect_offset;
+   ppa64.g.sec = (ppa32 & ppaf->sec_mask) >> ppaf->sec_offset;
}
  
  	return ppa64;

@@ -1022,7 +1022,7 @@ static inline u32 pblk_ppa64_to_ppa32(struct pblk *pblk, 
struct ppa_addr ppa64)
ppa32 |= ppa64.g.blk << ppaf->blk_offset;
ppa32 |= ppa64.g.pg << ppaf->pg_offset;
ppa32 |= ppa64.g.pl << ppaf->pln_offset;
-   ppa32 |= ppa64.g.sec << ppaf->sect_offset;
+   ppa32 |= ppa64.g.sec << ppaf->sec_offset;
}
  
  	return ppa32;

diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
index bd97672e0b4f..cca32da05316 100644
--- a/drivers/nvme/host/lightnvm.c
+++ b/drivers/nvme/host/lightnvm.c
@@ -262,21 +262,21 @@ static void nvme_nvm_set_addr_12(struct 
nvm_addr_format_12 *dst,
dst->blk_len = 

Re: [PATCH V15 06/22] mmc: block: Add blk-mq support

2018-02-21 Thread Adrian Hunter
On 21/02/18 22:50, Dmitry Osipenko wrote:
> On 29.11.2017 16:41, Adrian Hunter wrote:
>> Define and use a blk-mq queue. Discards and flushes are processed
>> synchronously, but reads and writes asynchronously. In order to support
>> slow DMA unmapping, DMA unmapping is not done until after the next request
>> is started. That means the request is not completed until then. If there is
>> no next request then the completion is done by queued work.
> 
> Hello,
> 
> I'm using (running linux-next and doing some upstream development for) some 
> old
> NVIDIA Tegra tablet that has built-in (internal) and external MMC's and with 
> the
> blk-mq being enabled I'm observing a soft lockup. The lockup seems is
> reproducible quite reliably by running fsck on any MMC partition, sometimes
> kernels lockups on boot during probing partitions table (weirdly only when 
> both
> SDHCI's are present, i.e. internal storage enabled in DT and external SD is
> inserted/enabled) and it also lockups pretty quickly in a case of just a 
> general
> use. Reverting mmc/ commits up to 1bec43a3b18 ("Remove option not to use
> blk-mq") and disabling CONFIG_MMC_MQ_DEFAULT makes everything working fine
> again. There is also a third SDHCI populated with built-in WiFi/Bluetooth SDIO
> and I'm observing odd MMC timeouts with the blk-mq enabled, disabling
> CONFIG_MMC_MQ_DEFAULT fixes these timeouts as well.
> 
> Any thoughts?

SDIO (unless it is a combo card) should be unaffected by changes to the
block driver.

I don't have any ideas.  Adding more NVIDIA people.

> 
> WiFi issue
> 
> 
> [   38.247006] mmc2: Timeout waiting for hardware interrupt.
> [   38.247027] brcmfmac: brcmf_escan_timeout: timer expired
> [   38.247036] mmc2: sdhci:  SDHCI REGISTER DUMP ===
> [   38.247047] mmc2: sdhci: Sys addr:  0x | Version:  0x0001
> [   38.247055] mmc2: sdhci: Blk size:  0x7008 | Blk cnt:  0x
> [   38.247062] mmc2: sdhci: Argument:  0x2108 | Trn mode: 0x0013
> [   38.247070] mmc2: sdhci: Present:   0x01d7 | Host ctl: 0x0013
> [   38.247077] mmc2: sdhci: Power: 0x0001 | Blk gap:  0x
> [   38.247084] mmc2: sdhci: Wake-up:   0x | Clock:0x0007
> [   38.247091] mmc2: sdhci: Timeout:   0x000e | Int stat: 0x
> [   38.247098] mmc2: sdhci: Int enab:  0x02ff000b | Sig enab: 0x02fc000b
> [   38.247105] mmc2: sdhci: AC12 err:  0x | Slot int: 0x
> [   38.247112] mmc2: sdhci: Caps:  0x61ff30b0 | Caps_1:   0x
> [   38.247119] mmc2: sdhci: Cmd:   0x353a | Max curr: 0x0001
> [   38.247126] mmc2: sdhci: Resp[0]:   0x1800 | Resp[1]:  0x08002db5
> [   38.247133] mmc2: sdhci: Resp[2]:   0x16da8000 | Resp[3]:  0x0400
> [   38.247139] mmc2: sdhci: Host ctl2: 0x
> [   38.247146] mmc2: sdhci: ADMA Err:  0x | ADMA Ptr: 0x17c47200
> [   38.247152] mmc2: sdhci: 
> [   38.247250] brcmfmac: brcmf_sdio_readframes: read 520 bytes from channel 1
> failed: -84
> [   38.247274] brcmfmac: brcmf_sdio_rxfail: abort command, terminate frame, 
> send NAK
> [   40.807019] brcmfmac: brcmf_sdio_bus_rxctl: resumed on timeout
> [   40.807042] brcmfmac: brcmf_notify_escan_complete: Scan abort failed
> [   48.487007] mmc2: Timeout waiting for hardware interrupt.
> [   48.487057] mmc2: sdhci:  SDHCI REGISTER DUMP ===
> [   48.487096] mmc2: sdhci: Sys addr:  0x | Version:  0x0001
> [   48.487128] mmc2: sdhci: Blk size:  0x7040 | Blk cnt:  0x0001
> [   48.487160] mmc2: sdhci: Argument:  0x2140 | Trn mode: 0x0013
> [   48.487191] mmc2: sdhci: Present:   0x01d7 | Host ctl: 0x0013
> [   48.487221] mmc2: sdhci: Power: 0x0001 | Blk gap:  0x
> [   48.487251] mmc2: sdhci: Wake-up:   0x | Clock:0x0007
> [   48.487281] mmc2: sdhci: Timeout:   0x000e | Int stat: 0x
> [   48.487313] mmc2: sdhci: Int enab:  0x02ff000b | Sig enab: 0x02fc000b
> [   48.487343] mmc2: sdhci: AC12 err:  0x | Slot int: 0x
> [   48.487374] mmc2: sdhci: Caps:  0x61ff30b0 | Caps_1:   0x
> [   48.487404] mmc2: sdhci: Cmd:   0x353a | Max curr: 0x0001
> [   48.487435] mmc2: sdhci: Resp[0]:   0x1000 | Resp[1]:  0x08002db5
> [   48.487466] mmc2: sdhci: Resp[2]:   0x16da8000 | Resp[3]:  0x0400
> [   48.487493] mmc2: sdhci: Host ctl2: 0x
> [   48.487525] mmc2: sdhci: ADMA Err:  0x | ADMA Ptr: 0x17c47200
> [   48.487552] mmc2: sdhci: 
> [   48.487749] brcmfmac: brcmf_sdio_readframes: read 480 bytes from channel 1
> failed: -84
> [   48.487822] brcmfmac: brcmf_sdio_rxfail: abort command, terminate frame, 
> send NAK
> 
> 
> Soft lockup issue
> 
> 
> # fsck -f /dev/disk/by-uuid/6768309f-3545-49d5-9ac7-d5be24d35ef2
> fsck из util-linux 2.30.2
> e2fsck 1.43.9 (8-Feb-2018)
> Проход 1: 

Re: [PATCH V15 06/22] mmc: block: Add blk-mq support

2018-02-21 Thread Adrian Hunter
On 21/02/18 22:50, Dmitry Osipenko wrote:
> On 29.11.2017 16:41, Adrian Hunter wrote:
>> Define and use a blk-mq queue. Discards and flushes are processed
>> synchronously, but reads and writes asynchronously. In order to support
>> slow DMA unmapping, DMA unmapping is not done until after the next request
>> is started. That means the request is not completed until then. If there is
>> no next request then the completion is done by queued work.
> 
> Hello,
> 
> I'm using (running linux-next and doing some upstream development for) some 
> old
> NVIDIA Tegra tablet that has built-in (internal) and external MMC's and with 
> the
> blk-mq being enabled I'm observing a soft lockup. The lockup seems is
> reproducible quite reliably by running fsck on any MMC partition, sometimes
> kernels lockups on boot during probing partitions table (weirdly only when 
> both
> SDHCI's are present, i.e. internal storage enabled in DT and external SD is
> inserted/enabled) and it also lockups pretty quickly in a case of just a 
> general
> use. Reverting mmc/ commits up to 1bec43a3b18 ("Remove option not to use
> blk-mq") and disabling CONFIG_MMC_MQ_DEFAULT makes everything working fine
> again. There is also a third SDHCI populated with built-in WiFi/Bluetooth SDIO
> and I'm observing odd MMC timeouts with the blk-mq enabled, disabling
> CONFIG_MMC_MQ_DEFAULT fixes these timeouts as well.
> 
> Any thoughts?

SDIO (unless it is a combo card) should be unaffected by changes to the
block driver.

I don't have any ideas.  Adding more NVIDIA people.

> 
> WiFi issue
> 
> 
> [   38.247006] mmc2: Timeout waiting for hardware interrupt.
> [   38.247027] brcmfmac: brcmf_escan_timeout: timer expired
> [   38.247036] mmc2: sdhci:  SDHCI REGISTER DUMP ===
> [   38.247047] mmc2: sdhci: Sys addr:  0x | Version:  0x0001
> [   38.247055] mmc2: sdhci: Blk size:  0x7008 | Blk cnt:  0x
> [   38.247062] mmc2: sdhci: Argument:  0x2108 | Trn mode: 0x0013
> [   38.247070] mmc2: sdhci: Present:   0x01d7 | Host ctl: 0x0013
> [   38.247077] mmc2: sdhci: Power: 0x0001 | Blk gap:  0x
> [   38.247084] mmc2: sdhci: Wake-up:   0x | Clock:0x0007
> [   38.247091] mmc2: sdhci: Timeout:   0x000e | Int stat: 0x
> [   38.247098] mmc2: sdhci: Int enab:  0x02ff000b | Sig enab: 0x02fc000b
> [   38.247105] mmc2: sdhci: AC12 err:  0x | Slot int: 0x
> [   38.247112] mmc2: sdhci: Caps:  0x61ff30b0 | Caps_1:   0x
> [   38.247119] mmc2: sdhci: Cmd:   0x353a | Max curr: 0x0001
> [   38.247126] mmc2: sdhci: Resp[0]:   0x1800 | Resp[1]:  0x08002db5
> [   38.247133] mmc2: sdhci: Resp[2]:   0x16da8000 | Resp[3]:  0x0400
> [   38.247139] mmc2: sdhci: Host ctl2: 0x
> [   38.247146] mmc2: sdhci: ADMA Err:  0x | ADMA Ptr: 0x17c47200
> [   38.247152] mmc2: sdhci: 
> [   38.247250] brcmfmac: brcmf_sdio_readframes: read 520 bytes from channel 1
> failed: -84
> [   38.247274] brcmfmac: brcmf_sdio_rxfail: abort command, terminate frame, 
> send NAK
> [   40.807019] brcmfmac: brcmf_sdio_bus_rxctl: resumed on timeout
> [   40.807042] brcmfmac: brcmf_notify_escan_complete: Scan abort failed
> [   48.487007] mmc2: Timeout waiting for hardware interrupt.
> [   48.487057] mmc2: sdhci:  SDHCI REGISTER DUMP ===
> [   48.487096] mmc2: sdhci: Sys addr:  0x | Version:  0x0001
> [   48.487128] mmc2: sdhci: Blk size:  0x7040 | Blk cnt:  0x0001
> [   48.487160] mmc2: sdhci: Argument:  0x2140 | Trn mode: 0x0013
> [   48.487191] mmc2: sdhci: Present:   0x01d7 | Host ctl: 0x0013
> [   48.487221] mmc2: sdhci: Power: 0x0001 | Blk gap:  0x
> [   48.487251] mmc2: sdhci: Wake-up:   0x | Clock:0x0007
> [   48.487281] mmc2: sdhci: Timeout:   0x000e | Int stat: 0x
> [   48.487313] mmc2: sdhci: Int enab:  0x02ff000b | Sig enab: 0x02fc000b
> [   48.487343] mmc2: sdhci: AC12 err:  0x | Slot int: 0x
> [   48.487374] mmc2: sdhci: Caps:  0x61ff30b0 | Caps_1:   0x
> [   48.487404] mmc2: sdhci: Cmd:   0x353a | Max curr: 0x0001
> [   48.487435] mmc2: sdhci: Resp[0]:   0x1000 | Resp[1]:  0x08002db5
> [   48.487466] mmc2: sdhci: Resp[2]:   0x16da8000 | Resp[3]:  0x0400
> [   48.487493] mmc2: sdhci: Host ctl2: 0x
> [   48.487525] mmc2: sdhci: ADMA Err:  0x | ADMA Ptr: 0x17c47200
> [   48.487552] mmc2: sdhci: 
> [   48.487749] brcmfmac: brcmf_sdio_readframes: read 480 bytes from channel 1
> failed: -84
> [   48.487822] brcmfmac: brcmf_sdio_rxfail: abort command, terminate frame, 
> send NAK
> 
> 
> Soft lockup issue
> 
> 
> # fsck -f /dev/disk/by-uuid/6768309f-3545-49d5-9ac7-d5be24d35ef2
> fsck из util-linux 2.30.2
> e2fsck 1.43.9 (8-Feb-2018)
> Проход 1: 

Re: [PATCH 04/20] lightnvm: add minor version to generic geometry

2018-02-21 Thread Matias Bjørling

On 02/21/2018 10:26 AM, Javier González wrote:

Separate the version between major and minor on the generic geometry.
Also, add a "subversion" entry to sysfs to expose the minor version
without breaking user space.

Signed-off-by: Javier González 
---
  drivers/lightnvm/core.c  |  4 ++--
  drivers/nvme/host/lightnvm.c | 25 -
  include/linux/lightnvm.h |  3 ++-
  3 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
index 42596afdf64c..dc9ec6baff45 100644
--- a/drivers/lightnvm/core.c
+++ b/drivers/lightnvm/core.c
@@ -897,8 +897,8 @@ static int nvm_init(struct nvm_dev *dev)
goto err;
}
  
-	pr_debug("nvm: ver:%u nvm_vendor:%x\n",

-   dev_geo->ver_id,
+   pr_debug("nvm: ver:%u.%u nvm_vendor:%x\n",
+   dev_geo->major_ver_id, dev_geo->minor_ver_id,
dev_geo->c.vmnt);
  
  	ret = nvm_core_init(dev);

diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
index 598abba66f52..71b4ac57a668 100644
--- a/drivers/nvme/host/lightnvm.c
+++ b/drivers/nvme/host/lightnvm.c
@@ -296,7 +296,8 @@ static int nvme_nvm_setup_12(struct nvme_nvm_id12 *id,
}
  
  	/* 1.2 spec. only reports a single version id - unfold */

-   dev_geo->ver_id = id->ver_id;
+   dev_geo->major_ver_id = id->ver_id;
+   dev_geo->minor_ver_id = 2;
  
  	dev_geo->nr_chnls = src->num_ch;

dev_geo->nr_luns = src->num_lun;
@@ -377,7 +378,14 @@ static void nvme_nvm_set_addr_20(struct nvm_addr_format 
*dst,
  static int nvme_nvm_setup_20(struct nvme_nvm_id20 *id,
 struct nvm_dev_geo *dev_geo)
  {
-   dev_geo->ver_id = id->mjr;
+   dev_geo->major_ver_id = id->mjr;
+   dev_geo->minor_ver_id = id->mnr;
+
+   if (!(dev_geo->major_ver_id == 2 && dev_geo->minor_ver_id == 0)) {
+   pr_err("nvm: OCSSD version not supported (v%d.%d)\n",
+   dev_geo->major_ver_id, dev_geo->minor_ver_id);
+   return -EINVAL;
+   }
  
  	dev_geo->nr_chnls = le16_to_cpu(id->num_grp);

dev_geo->nr_luns = le16_to_cpu(id->num_pu);
@@ -913,7 +921,11 @@ static ssize_t nvm_dev_attr_show(struct device *dev,
attr = >attr;
  
  	if (strcmp(attr->name, "version") == 0) {

-   return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->ver_id);
+   return scnprintf(page, PAGE_SIZE, "%u\n",
+   dev_geo->major_ver_id);
+   } else if (strcmp(attr->name, "subversion") == 0) {
+   return scnprintf(page, PAGE_SIZE, "%u\n",
+   dev_geo->minor_ver_id);
} else if (strcmp(attr->name, "media_capabilities") == 0) {
return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->c.mccap);
} else if (strcmp(attr->name, "read_typ") == 0) {
@@ -1055,6 +1067,7 @@ static ssize_t nvm_dev_attr_show_20(struct device *dev,
  
  /* general attributes */

  static NVM_DEV_ATTR_RO(version);
+static NVM_DEV_ATTR_RO(subversion);
  static NVM_DEV_ATTR_RO(media_capabilities);
  
  static NVM_DEV_ATTR_RO(read_typ);

@@ -1085,6 +1098,7 @@ static NVM_DEV_ATTR_12_RO(max_phys_secs);
  
  static struct attribute *nvm_dev_attrs_12[] = {

_attr_version.attr,
+   _attr_subversion.attr,
_attr_media_capabilities.attr,
  
  	_attr_vendor_opcode.attr,

@@ -1134,6 +1148,7 @@ static NVM_DEV_ATTR_20_RO(reset_max);
  
  static struct attribute *nvm_dev_attrs_20[] = {

_attr_version.attr,
+   _attr_subversion.attr,
_attr_media_capabilities.attr,
  
  	_attr_groups.attr,

@@ -1167,7 +1182,7 @@ int nvme_nvm_register_sysfs(struct nvme_ns *ns)
if (!ndev)
return -EINVAL;
  
-	switch (dev_geo->ver_id) {

+   switch (dev_geo->major_ver_id) {
case 1:
return sysfs_create_group(_to_dev(ns->disk)->kobj,
_dev_attr_group_12);
@@ -1184,7 +1199,7 @@ void nvme_nvm_unregister_sysfs(struct nvme_ns *ns)
struct nvm_dev *ndev = ns->ndev;
struct nvm_dev_geo *dev_geo = >dev_geo;
  
-	switch (dev_geo->ver_id) {

+   switch (dev_geo->major_ver_id) {
case 1:
sysfs_remove_group(_to_dev(ns->disk)->kobj,
_dev_attr_group_12);
diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h
index 18e3751b1632..5af0b8837095 100644
--- a/include/linux/lightnvm.h
+++ b/include/linux/lightnvm.h
@@ -242,7 +242,8 @@ struct nvm_common_geo {
  /* Device identified geometry */
  struct nvm_dev_geo {
/* device reported version */
-   u8  ver_id;
+   u8  major_ver_id;
+   u8  minor_ver_id;
  
  	/* full device geometry */

u16 nr_chnls;



Looks fairly good to me. Did you consider putting in the major and minor 

Re: [PATCH 04/20] lightnvm: add minor version to generic geometry

2018-02-21 Thread Matias Bjørling

On 02/21/2018 10:26 AM, Javier González wrote:

Separate the version between major and minor on the generic geometry.
Also, add a "subversion" entry to sysfs to expose the minor version
without breaking user space.

Signed-off-by: Javier González 
---
  drivers/lightnvm/core.c  |  4 ++--
  drivers/nvme/host/lightnvm.c | 25 -
  include/linux/lightnvm.h |  3 ++-
  3 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
index 42596afdf64c..dc9ec6baff45 100644
--- a/drivers/lightnvm/core.c
+++ b/drivers/lightnvm/core.c
@@ -897,8 +897,8 @@ static int nvm_init(struct nvm_dev *dev)
goto err;
}
  
-	pr_debug("nvm: ver:%u nvm_vendor:%x\n",

-   dev_geo->ver_id,
+   pr_debug("nvm: ver:%u.%u nvm_vendor:%x\n",
+   dev_geo->major_ver_id, dev_geo->minor_ver_id,
dev_geo->c.vmnt);
  
  	ret = nvm_core_init(dev);

diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
index 598abba66f52..71b4ac57a668 100644
--- a/drivers/nvme/host/lightnvm.c
+++ b/drivers/nvme/host/lightnvm.c
@@ -296,7 +296,8 @@ static int nvme_nvm_setup_12(struct nvme_nvm_id12 *id,
}
  
  	/* 1.2 spec. only reports a single version id - unfold */

-   dev_geo->ver_id = id->ver_id;
+   dev_geo->major_ver_id = id->ver_id;
+   dev_geo->minor_ver_id = 2;
  
  	dev_geo->nr_chnls = src->num_ch;

dev_geo->nr_luns = src->num_lun;
@@ -377,7 +378,14 @@ static void nvme_nvm_set_addr_20(struct nvm_addr_format 
*dst,
  static int nvme_nvm_setup_20(struct nvme_nvm_id20 *id,
 struct nvm_dev_geo *dev_geo)
  {
-   dev_geo->ver_id = id->mjr;
+   dev_geo->major_ver_id = id->mjr;
+   dev_geo->minor_ver_id = id->mnr;
+
+   if (!(dev_geo->major_ver_id == 2 && dev_geo->minor_ver_id == 0)) {
+   pr_err("nvm: OCSSD version not supported (v%d.%d)\n",
+   dev_geo->major_ver_id, dev_geo->minor_ver_id);
+   return -EINVAL;
+   }
  
  	dev_geo->nr_chnls = le16_to_cpu(id->num_grp);

dev_geo->nr_luns = le16_to_cpu(id->num_pu);
@@ -913,7 +921,11 @@ static ssize_t nvm_dev_attr_show(struct device *dev,
attr = >attr;
  
  	if (strcmp(attr->name, "version") == 0) {

-   return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->ver_id);
+   return scnprintf(page, PAGE_SIZE, "%u\n",
+   dev_geo->major_ver_id);
+   } else if (strcmp(attr->name, "subversion") == 0) {
+   return scnprintf(page, PAGE_SIZE, "%u\n",
+   dev_geo->minor_ver_id);
} else if (strcmp(attr->name, "media_capabilities") == 0) {
return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->c.mccap);
} else if (strcmp(attr->name, "read_typ") == 0) {
@@ -1055,6 +1067,7 @@ static ssize_t nvm_dev_attr_show_20(struct device *dev,
  
  /* general attributes */

  static NVM_DEV_ATTR_RO(version);
+static NVM_DEV_ATTR_RO(subversion);
  static NVM_DEV_ATTR_RO(media_capabilities);
  
  static NVM_DEV_ATTR_RO(read_typ);

@@ -1085,6 +1098,7 @@ static NVM_DEV_ATTR_12_RO(max_phys_secs);
  
  static struct attribute *nvm_dev_attrs_12[] = {

_attr_version.attr,
+   _attr_subversion.attr,
_attr_media_capabilities.attr,
  
  	_attr_vendor_opcode.attr,

@@ -1134,6 +1148,7 @@ static NVM_DEV_ATTR_20_RO(reset_max);
  
  static struct attribute *nvm_dev_attrs_20[] = {

_attr_version.attr,
+   _attr_subversion.attr,
_attr_media_capabilities.attr,
  
  	_attr_groups.attr,

@@ -1167,7 +1182,7 @@ int nvme_nvm_register_sysfs(struct nvme_ns *ns)
if (!ndev)
return -EINVAL;
  
-	switch (dev_geo->ver_id) {

+   switch (dev_geo->major_ver_id) {
case 1:
return sysfs_create_group(_to_dev(ns->disk)->kobj,
_dev_attr_group_12);
@@ -1184,7 +1199,7 @@ void nvme_nvm_unregister_sysfs(struct nvme_ns *ns)
struct nvm_dev *ndev = ns->ndev;
struct nvm_dev_geo *dev_geo = >dev_geo;
  
-	switch (dev_geo->ver_id) {

+   switch (dev_geo->major_ver_id) {
case 1:
sysfs_remove_group(_to_dev(ns->disk)->kobj,
_dev_attr_group_12);
diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h
index 18e3751b1632..5af0b8837095 100644
--- a/include/linux/lightnvm.h
+++ b/include/linux/lightnvm.h
@@ -242,7 +242,8 @@ struct nvm_common_geo {
  /* Device identified geometry */
  struct nvm_dev_geo {
/* device reported version */
-   u8  ver_id;
+   u8  major_ver_id;
+   u8  minor_ver_id;
  
  	/* full device geometry */

u16 nr_chnls;



Looks fairly good to me. Did you consider putting in the major and minor 
version id into the 

Re: [PATCH v3 1/3] Kconfig : Remove HAS_IOMEM dependency for Graphics support

2018-02-21 Thread Christian Borntraeger


On 02/21/2018 05:39 PM, Farhan Ali wrote:
> 
> 
> On 02/21/2018 07:11 AM, Christian Borntraeger wrote:
>>
>>
>> On 02/21/2018 01:07 PM, Cornelia Huck wrote:
>> [...]
> But if you need to enable PCI to get IOMEM, I wonder why this patch here
> is needed at all? The Graphics menu / VT dummy console should be
> available in the config if IOMEM is enabled anyway?

 That is a good question. With CONFIG_PCI=y I can select virtio-gpu and 
 dummy-console.
 IIRC the issue was that with patch 3 we can have the situation where we 
 have
 CONFIG_VT = y and CONFIG_DUMMY_CONSOLE=n and this will crash early during 
 boot as
 conswitchp is NULL.
> 
> Yes, VT layer initializes very early in the boot process and looks for a 
> console. If it can't find any it will crash. I believe that was the whole 
> point of having the dummy console.
> 
>>>
>>> So in practice, CONFIG_VT depends on "there's a console available, even
>>> if it's only the dummy one"?
>>
>> Yes. Maybe we should simple move dummy_console outside of 
>> drivers/video/console/Kconfig
>> into something that is always available.
>>
> 
> I agree, but where should it go? consoles are kinda tightly tied to 
> video/Graphics Support.
> 
>>>
 This patches goal was to always enable dummy console even without
 PCI, but it obviously fails to do so.
>>>
> This patch should enable the dummy console even without PCI but we won't have 
> DRM/Virtio GPU.


All right. This patch then makes sure that VT does not crash since it guarantees
that DUMMY_CONSOLE is available. If the user want to have virtio-gpu it needs to
enable PCI due to the dependencies, but this is a different issue that we can 
fix
later.
So the patch is fine as long as you take care of these things

- add missing HAS_IOMEM dependency to VGA_CONSOLE

- extend "if HAS_IOMEM" in drivers/video/Kconfig to cover config items
  previously covered by this dependency (it should start before config
  HAVE_FB_ATMEL and end after config HDMI)

as requested by Bartlomiej 



Re: [PATCH v3 1/3] Kconfig : Remove HAS_IOMEM dependency for Graphics support

2018-02-21 Thread Christian Borntraeger


On 02/21/2018 05:39 PM, Farhan Ali wrote:
> 
> 
> On 02/21/2018 07:11 AM, Christian Borntraeger wrote:
>>
>>
>> On 02/21/2018 01:07 PM, Cornelia Huck wrote:
>> [...]
> But if you need to enable PCI to get IOMEM, I wonder why this patch here
> is needed at all? The Graphics menu / VT dummy console should be
> available in the config if IOMEM is enabled anyway?

 That is a good question. With CONFIG_PCI=y I can select virtio-gpu and 
 dummy-console.
 IIRC the issue was that with patch 3 we can have the situation where we 
 have
 CONFIG_VT = y and CONFIG_DUMMY_CONSOLE=n and this will crash early during 
 boot as
 conswitchp is NULL.
> 
> Yes, VT layer initializes very early in the boot process and looks for a 
> console. If it can't find any it will crash. I believe that was the whole 
> point of having the dummy console.
> 
>>>
>>> So in practice, CONFIG_VT depends on "there's a console available, even
>>> if it's only the dummy one"?
>>
>> Yes. Maybe we should simple move dummy_console outside of 
>> drivers/video/console/Kconfig
>> into something that is always available.
>>
> 
> I agree, but where should it go? consoles are kinda tightly tied to 
> video/Graphics Support.
> 
>>>
 This patches goal was to always enable dummy console even without
 PCI, but it obviously fails to do so.
>>>
> This patch should enable the dummy console even without PCI but we won't have 
> DRM/Virtio GPU.


All right. This patch then makes sure that VT does not crash since it guarantees
that DUMMY_CONSOLE is available. If the user want to have virtio-gpu it needs to
enable PCI due to the dependencies, but this is a different issue that we can 
fix
later.
So the patch is fine as long as you take care of these things

- add missing HAS_IOMEM dependency to VGA_CONSOLE

- extend "if HAS_IOMEM" in drivers/video/Kconfig to cover config items
  previously covered by this dependency (it should start before config
  HAVE_FB_ATMEL and end after config HDMI)

as requested by Bartlomiej 



[PATCH] fscache: fix a kernel BUG at fs/fscache/operation.c:69!

2018-02-21 Thread carmark . dlut
From: Lei Xue 

There is a potential race in fscache operation enqueuing for reading and
copying multiple pages from cachefiles to netfs.
Under some heavy load system, it will happen very often.

If this race occurs, an oops similar to the following is seen:

 kernel BUG at fs/fscache/operation.c:69!
 invalid opcode:  [#1] SMP
 …
 #0 [883fff0838d8] machine_kexec at 81051beb
 #1 [883fff083938] crash_kexec at 810f2542
 #2 [883fff083a08] oops_end at 8163e1a8
 #3 [883fff083a30] die at 8101859b
 #4 [883fff083a60] do_trap at 8163d860
 #5 [883fff083ab0] do_invalid_op at 81015204
 #6 [883fff083b60] invalid_op at 8164701e
[exception RIP: fscache_enqueue_operation+246]
RIP: a0b793c6  RSP: 883fff083c18  RFLAGS: 00010046
RAX: 0019  RBX: 8832ed1a9ec0  RCX: 0006
RDX:   RSI: 0046  RDI: 0046
RBP: 883fff083c20   R8: 0086   R9: 178f
R10: 816aeb00  R11: 883fff08392e  R12: 8802f0525620
R13: 88407ffc01d8  R14:   R15: 0003
ORIG_RAX:   CS: 0010  SS: 
 #7 [883fff083c10] fscache_enqueue_operation at a0b793c6
 #8 [883fff083c28] cachefiles_read_waiter at a0b15a48
 #9 [883fff083c48] __wake_up_common at 810af028

Signed-off-by: Lei Xue 
---
 fs/cachefiles/rdwr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c
index 883bc7bb12c5..9d5d13e150fb 100644
--- a/fs/cachefiles/rdwr.c
+++ b/fs/cachefiles/rdwr.c
@@ -58,9 +58,9 @@ static int cachefiles_read_waiter(wait_queue_entry_t *wait, 
unsigned mode,
 
spin_lock(>work_lock);
list_add_tail(>op_link, >op->to_do);
+   fscache_enqueue_retrieval(monitor->op);
spin_unlock(>work_lock);
 
-   fscache_enqueue_retrieval(monitor->op);
return 0;
 }
 
-- 
2.14.3 (Apple Git-98)



[PATCH] fscache: fix a kernel BUG at fs/fscache/operation.c:69!

2018-02-21 Thread carmark . dlut
From: Lei Xue 

There is a potential race in fscache operation enqueuing for reading and
copying multiple pages from cachefiles to netfs.
Under some heavy load system, it will happen very often.

If this race occurs, an oops similar to the following is seen:

 kernel BUG at fs/fscache/operation.c:69!
 invalid opcode:  [#1] SMP
 …
 #0 [883fff0838d8] machine_kexec at 81051beb
 #1 [883fff083938] crash_kexec at 810f2542
 #2 [883fff083a08] oops_end at 8163e1a8
 #3 [883fff083a30] die at 8101859b
 #4 [883fff083a60] do_trap at 8163d860
 #5 [883fff083ab0] do_invalid_op at 81015204
 #6 [883fff083b60] invalid_op at 8164701e
[exception RIP: fscache_enqueue_operation+246]
RIP: a0b793c6  RSP: 883fff083c18  RFLAGS: 00010046
RAX: 0019  RBX: 8832ed1a9ec0  RCX: 0006
RDX:   RSI: 0046  RDI: 0046
RBP: 883fff083c20   R8: 0086   R9: 178f
R10: 816aeb00  R11: 883fff08392e  R12: 8802f0525620
R13: 88407ffc01d8  R14:   R15: 0003
ORIG_RAX:   CS: 0010  SS: 
 #7 [883fff083c10] fscache_enqueue_operation at a0b793c6
 #8 [883fff083c28] cachefiles_read_waiter at a0b15a48
 #9 [883fff083c48] __wake_up_common at 810af028

Signed-off-by: Lei Xue 
---
 fs/cachefiles/rdwr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c
index 883bc7bb12c5..9d5d13e150fb 100644
--- a/fs/cachefiles/rdwr.c
+++ b/fs/cachefiles/rdwr.c
@@ -58,9 +58,9 @@ static int cachefiles_read_waiter(wait_queue_entry_t *wait, 
unsigned mode,
 
spin_lock(>work_lock);
list_add_tail(>op_link, >op->to_do);
+   fscache_enqueue_retrieval(monitor->op);
spin_unlock(>work_lock);
 
-   fscache_enqueue_retrieval(monitor->op);
return 0;
 }
 
-- 
2.14.3 (Apple Git-98)



Re: [PATCH 03/20] lightnvm: fix capabilities for 2.0 sysfs

2018-02-21 Thread Matias Bjørling

On 02/21/2018 10:26 AM, Javier González wrote:

Both 1.2 and 2.0 specs define a field for media and controller
capabilities. Also, 1.2 defines a separate field dedicated to device
capabilities.

In 2.0 sysfs, this values have been mixed. Revert them to the right
value.

Signed-off-by: Javier González 
---
  drivers/nvme/host/lightnvm.c | 18 +-
  1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
index 969bb874850c..598abba66f52 100644
--- a/drivers/nvme/host/lightnvm.c
+++ b/drivers/nvme/host/lightnvm.c
@@ -914,8 +914,8 @@ static ssize_t nvm_dev_attr_show(struct device *dev,
  
  	if (strcmp(attr->name, "version") == 0) {

return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->ver_id);
-   } else if (strcmp(attr->name, "capabilities") == 0) {
-   return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->c.cap);
+   } else if (strcmp(attr->name, "media_capabilities") == 0) {
+   return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->c.mccap);
} else if (strcmp(attr->name, "read_typ") == 0) {
return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->c.trdt);
} else if (strcmp(attr->name, "read_max") == 0) {
@@ -993,8 +993,8 @@ static ssize_t nvm_dev_attr_show_12(struct device *dev,
return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->c.tbem);
} else if (strcmp(attr->name, "multiplane_modes") == 0) {
return scnprintf(page, PAGE_SIZE, "0x%08x\n", dev_geo->c.mpos);
-   } else if (strcmp(attr->name, "media_capabilities") == 0) {
-   return scnprintf(page, PAGE_SIZE, "0x%08x\n", dev_geo->c.mccap);
+   } else if (strcmp(attr->name, "capabilities") == 0) {
+   return scnprintf(page, PAGE_SIZE, "0x%08x\n", dev_geo->c.cap);
} else if (strcmp(attr->name, "max_phys_secs") == 0) {
return scnprintf(page, PAGE_SIZE, "%u\n", NVM_MAX_VLBA);
} else {
@@ -1055,7 +1055,7 @@ static ssize_t nvm_dev_attr_show_20(struct device *dev,
  
  /* general attributes */

  static NVM_DEV_ATTR_RO(version);
-static NVM_DEV_ATTR_RO(capabilities);
+static NVM_DEV_ATTR_RO(media_capabilities);
  
  static NVM_DEV_ATTR_RO(read_typ);

  static NVM_DEV_ATTR_RO(read_max);
@@ -1080,12 +1080,12 @@ static NVM_DEV_ATTR_12_RO(prog_max);
  static NVM_DEV_ATTR_12_RO(erase_typ);
  static NVM_DEV_ATTR_12_RO(erase_max);
  static NVM_DEV_ATTR_12_RO(multiplane_modes);
-static NVM_DEV_ATTR_12_RO(media_capabilities);
+static NVM_DEV_ATTR_12_RO(capabilities);
  static NVM_DEV_ATTR_12_RO(max_phys_secs);
  
  static struct attribute *nvm_dev_attrs_12[] = {

_attr_version.attr,
-   _attr_capabilities.attr,
+   _attr_media_capabilities.attr,
  
  	_attr_vendor_opcode.attr,

_attr_device_mode.attr,
@@ -1108,7 +1108,7 @@ static struct attribute *nvm_dev_attrs_12[] = {
_attr_erase_typ.attr,
_attr_erase_max.attr,
_attr_multiplane_modes.attr,
-   _attr_media_capabilities.attr,
+   _attr_capabilities.attr,
_attr_max_phys_secs.attr,
  
  	NULL,

@@ -1134,7 +1134,7 @@ static NVM_DEV_ATTR_20_RO(reset_max);
  
  static struct attribute *nvm_dev_attrs_20[] = {

_attr_version.attr,
-   _attr_capabilities.attr,
+   _attr_media_capabilities.attr,
  
  	_attr_groups.attr,

_attr_punits.attr,



With the mccap changes, it should make sense to keep the capabilities as is.


Re: [PATCH 03/20] lightnvm: fix capabilities for 2.0 sysfs

2018-02-21 Thread Matias Bjørling

On 02/21/2018 10:26 AM, Javier González wrote:

Both 1.2 and 2.0 specs define a field for media and controller
capabilities. Also, 1.2 defines a separate field dedicated to device
capabilities.

In 2.0 sysfs, this values have been mixed. Revert them to the right
value.

Signed-off-by: Javier González 
---
  drivers/nvme/host/lightnvm.c | 18 +-
  1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
index 969bb874850c..598abba66f52 100644
--- a/drivers/nvme/host/lightnvm.c
+++ b/drivers/nvme/host/lightnvm.c
@@ -914,8 +914,8 @@ static ssize_t nvm_dev_attr_show(struct device *dev,
  
  	if (strcmp(attr->name, "version") == 0) {

return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->ver_id);
-   } else if (strcmp(attr->name, "capabilities") == 0) {
-   return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->c.cap);
+   } else if (strcmp(attr->name, "media_capabilities") == 0) {
+   return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->c.mccap);
} else if (strcmp(attr->name, "read_typ") == 0) {
return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->c.trdt);
} else if (strcmp(attr->name, "read_max") == 0) {
@@ -993,8 +993,8 @@ static ssize_t nvm_dev_attr_show_12(struct device *dev,
return scnprintf(page, PAGE_SIZE, "%u\n", dev_geo->c.tbem);
} else if (strcmp(attr->name, "multiplane_modes") == 0) {
return scnprintf(page, PAGE_SIZE, "0x%08x\n", dev_geo->c.mpos);
-   } else if (strcmp(attr->name, "media_capabilities") == 0) {
-   return scnprintf(page, PAGE_SIZE, "0x%08x\n", dev_geo->c.mccap);
+   } else if (strcmp(attr->name, "capabilities") == 0) {
+   return scnprintf(page, PAGE_SIZE, "0x%08x\n", dev_geo->c.cap);
} else if (strcmp(attr->name, "max_phys_secs") == 0) {
return scnprintf(page, PAGE_SIZE, "%u\n", NVM_MAX_VLBA);
} else {
@@ -1055,7 +1055,7 @@ static ssize_t nvm_dev_attr_show_20(struct device *dev,
  
  /* general attributes */

  static NVM_DEV_ATTR_RO(version);
-static NVM_DEV_ATTR_RO(capabilities);
+static NVM_DEV_ATTR_RO(media_capabilities);
  
  static NVM_DEV_ATTR_RO(read_typ);

  static NVM_DEV_ATTR_RO(read_max);
@@ -1080,12 +1080,12 @@ static NVM_DEV_ATTR_12_RO(prog_max);
  static NVM_DEV_ATTR_12_RO(erase_typ);
  static NVM_DEV_ATTR_12_RO(erase_max);
  static NVM_DEV_ATTR_12_RO(multiplane_modes);
-static NVM_DEV_ATTR_12_RO(media_capabilities);
+static NVM_DEV_ATTR_12_RO(capabilities);
  static NVM_DEV_ATTR_12_RO(max_phys_secs);
  
  static struct attribute *nvm_dev_attrs_12[] = {

_attr_version.attr,
-   _attr_capabilities.attr,
+   _attr_media_capabilities.attr,
  
  	_attr_vendor_opcode.attr,

_attr_device_mode.attr,
@@ -1108,7 +1108,7 @@ static struct attribute *nvm_dev_attrs_12[] = {
_attr_erase_typ.attr,
_attr_erase_max.attr,
_attr_multiplane_modes.attr,
-   _attr_media_capabilities.attr,
+   _attr_capabilities.attr,
_attr_max_phys_secs.attr,
  
  	NULL,

@@ -1134,7 +1134,7 @@ static NVM_DEV_ATTR_20_RO(reset_max);
  
  static struct attribute *nvm_dev_attrs_20[] = {

_attr_version.attr,
-   _attr_capabilities.attr,
+   _attr_media_capabilities.attr,
  
  	_attr_groups.attr,

_attr_punits.attr,



With the mccap changes, it should make sense to keep the capabilities as is.


Re: [PATCH 02/20] lightnvm: add controller capabilities to 2.0

2018-02-21 Thread Matias Bjørling

On 02/21/2018 10:26 AM, Javier González wrote:

Assign missing mccap value on 2.0 path

Signed-off-by: Javier González 
---
  drivers/nvme/host/lightnvm.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
index c81e64cc20d7..969bb874850c 100644
--- a/drivers/nvme/host/lightnvm.c
+++ b/drivers/nvme/host/lightnvm.c
@@ -392,6 +392,8 @@ static int nvme_nvm_setup_20(struct nvme_nvm_id20 *id,
dev_geo->c.ws_opt = le32_to_cpu(id->ws_opt);
dev_geo->c.mw_cunits = le32_to_cpu(id->mw_cunits);
  
+	dev_geo->c.mccap = le32_to_cpu(id->mccap);

+
dev_geo->c.trdt = le32_to_cpu(id->trdt);
dev_geo->c.trdm = le32_to_cpu(id->trdm);
dev_geo->c.tprt = le32_to_cpu(id->twrt);



The mccap field between 1.2 and 2.0 is orthogonal. They represent two 
different capabilities fields. The mccap has to be interpreted if used.


Re: [PATCH 02/20] lightnvm: add controller capabilities to 2.0

2018-02-21 Thread Matias Bjørling

On 02/21/2018 10:26 AM, Javier González wrote:

Assign missing mccap value on 2.0 path

Signed-off-by: Javier González 
---
  drivers/nvme/host/lightnvm.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
index c81e64cc20d7..969bb874850c 100644
--- a/drivers/nvme/host/lightnvm.c
+++ b/drivers/nvme/host/lightnvm.c
@@ -392,6 +392,8 @@ static int nvme_nvm_setup_20(struct nvme_nvm_id20 *id,
dev_geo->c.ws_opt = le32_to_cpu(id->ws_opt);
dev_geo->c.mw_cunits = le32_to_cpu(id->mw_cunits);
  
+	dev_geo->c.mccap = le32_to_cpu(id->mccap);

+
dev_geo->c.trdt = le32_to_cpu(id->trdt);
dev_geo->c.trdm = le32_to_cpu(id->trdm);
dev_geo->c.tprt = le32_to_cpu(id->twrt);



The mccap field between 1.2 and 2.0 is orthogonal. They represent two 
different capabilities fields. The mccap has to be interpreted if used.


Re: [PATCH 01/13] metag: Remove arch/metag/

2018-02-21 Thread James Hogan
On Wed, Feb 21, 2018 at 07:52:08PM -0800, Guenter Roeck wrote:
> On 02/21/2018 03:38 PM, James Hogan wrote:
> > The earliest Meta architecture port of Linux I have a record of was an
> > import of a Meta port of Linux v2.4.1 in February 2004, which was worked
> > on significantly over the next few years by Graham Whaley, Will Newton,
> > Matt Fleming, myself and others.
> > 
> > Eventually the port was merged into mainline in v3.9 in March 2013, not
> > long after Imagination Technologies bought MIPS Technologies and shifted
> > its CPU focus over to the MIPS architecture.
> > 
> > As a result, though the port was maintained for a while, kept on life
> > support for a while longer, and useful for testing a few specific
> > drivers for which I don't have ready access to the equivalent MIPS
> > hardware, it is now essentially dead with no users.
> > 
> > It is also stuck using an out-of-tree toolchain based on GCC 4.2.4 which
> > is no longer maintained, now struggles to build modern kernels due to
> > toolchain bugs, and doesn't itself build with a modern GCC. The latest
> > buildroot port is still using an old uClibc snapshot which is no longer
> > served, and the latest uClibc doesn't build with GCC 4.2.4.
> > 
> > So lets call it a day and drop the Meta architecture port from the
> > kernel. RIP Meta.
> > 
> > Signed-off-by: James Hogan 
> > Link: 
> > https://lkml.kernel.org/r/95906b76-6ce1-3f84-eaba-c29b4ae95...@roeck-us.net
> > Cc: Guenter Roeck 
> > Cc: linux-me...@vger.kernel.org
> 
> FWIW:
> 
> Reviewed-by: Guenter Roeck 

Thanks

> 
> Did you drop the definition of CPUHP_AP_PERF_METAG_STARTING ?
> I browsed through the patches but didn't find where it was dropped.

Hmm, somehow that one slipped through my grepping. Thanks for pointing
out.

> 
> Also, how did you generate this patch, and can you try to apply it yourself ?
> I tried to apply it, but neither git am nor patch worked for me. This patch
> also doesn't show up on patchwork.kernel.org which is odd.

I presume because I used -D to git format-patch, which is apparently
only intended for human consumption (the full patch is 778K). I've
pushed this version of the series here:

git://git.kernel.org/pub/scm/linux/kernel/git/jhogan/metag.git
tag: metag_remove_v1

Cheers
James


signature.asc
Description: Digital signature


Re: [PATCH 01/13] metag: Remove arch/metag/

2018-02-21 Thread James Hogan
On Wed, Feb 21, 2018 at 07:52:08PM -0800, Guenter Roeck wrote:
> On 02/21/2018 03:38 PM, James Hogan wrote:
> > The earliest Meta architecture port of Linux I have a record of was an
> > import of a Meta port of Linux v2.4.1 in February 2004, which was worked
> > on significantly over the next few years by Graham Whaley, Will Newton,
> > Matt Fleming, myself and others.
> > 
> > Eventually the port was merged into mainline in v3.9 in March 2013, not
> > long after Imagination Technologies bought MIPS Technologies and shifted
> > its CPU focus over to the MIPS architecture.
> > 
> > As a result, though the port was maintained for a while, kept on life
> > support for a while longer, and useful for testing a few specific
> > drivers for which I don't have ready access to the equivalent MIPS
> > hardware, it is now essentially dead with no users.
> > 
> > It is also stuck using an out-of-tree toolchain based on GCC 4.2.4 which
> > is no longer maintained, now struggles to build modern kernels due to
> > toolchain bugs, and doesn't itself build with a modern GCC. The latest
> > buildroot port is still using an old uClibc snapshot which is no longer
> > served, and the latest uClibc doesn't build with GCC 4.2.4.
> > 
> > So lets call it a day and drop the Meta architecture port from the
> > kernel. RIP Meta.
> > 
> > Signed-off-by: James Hogan 
> > Link: 
> > https://lkml.kernel.org/r/95906b76-6ce1-3f84-eaba-c29b4ae95...@roeck-us.net
> > Cc: Guenter Roeck 
> > Cc: linux-me...@vger.kernel.org
> 
> FWIW:
> 
> Reviewed-by: Guenter Roeck 

Thanks

> 
> Did you drop the definition of CPUHP_AP_PERF_METAG_STARTING ?
> I browsed through the patches but didn't find where it was dropped.

Hmm, somehow that one slipped through my grepping. Thanks for pointing
out.

> 
> Also, how did you generate this patch, and can you try to apply it yourself ?
> I tried to apply it, but neither git am nor patch worked for me. This patch
> also doesn't show up on patchwork.kernel.org which is odd.

I presume because I used -D to git format-patch, which is apparently
only intended for human consumption (the full patch is 778K). I've
pushed this version of the series here:

git://git.kernel.org/pub/scm/linux/kernel/git/jhogan/metag.git
tag: metag_remove_v1

Cheers
James


signature.asc
Description: Digital signature


Re: [PATCH 01/20] lightnvm: simplify geometry structure.

2018-02-21 Thread Matias Bjørling

On 02/21/2018 10:26 AM, Javier González wrote:

Currently, the device geometry is stored redundantly in the nvm_id and
nvm_geo structures at a device level. Moreover, when instantiating
targets on a specific number of LUNs, these structures are replicated
and manually modified to fit the instance channel and LUN partitioning.

Instead, create a generic geometry around two base structures:
nvm_dev_geo, which describes the geometry of the whole device and
nvm_geo, which describes the geometry of the instance. Since these share
a big part of the geometry, create a nvm_common_geo structure that keeps
the static geoometry values that are shared across instances.

As we introduce support for 2.0, these structures allow to abstract
spec. specific values and present a common geometry to targets.

Signed-off-by: Javier González 
---
  drivers/lightnvm/core.c  | 137 +++-
  drivers/lightnvm/pblk-core.c |  16 +-
  drivers/lightnvm/pblk-gc.c   |   2 +-
  drivers/lightnvm/pblk-init.c | 123 +++---
  drivers/lightnvm/pblk-read.c |   2 +-
  drivers/lightnvm/pblk-recovery.c |  14 +-
  drivers/lightnvm/pblk-rl.c   |   2 +-
  drivers/lightnvm/pblk-sysfs.c|  39 +++--
  drivers/lightnvm/pblk-write.c|   2 +-
  drivers/lightnvm/pblk.h  |  93 +--
  drivers/nvme/host/lightnvm.c | 339 +++
  include/linux/lightnvm.h | 204 ---
  12 files changed, 514 insertions(+), 459 deletions(-)

diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
index 689c97b97775..42596afdf64c 100644
--- a/drivers/lightnvm/core.c
+++ b/drivers/lightnvm/core.c
@@ -111,6 +111,7 @@ static void nvm_release_luns_err(struct nvm_dev *dev, int 
lun_begin,
  static void nvm_remove_tgt_dev(struct nvm_tgt_dev *tgt_dev, int clear)
  {
struct nvm_dev *dev = tgt_dev->parent;
+   struct nvm_dev_geo *dev_geo = >dev_geo;
struct nvm_dev_map *dev_map = tgt_dev->map;
int i, j;
  
@@ -122,7 +123,7 @@ static void nvm_remove_tgt_dev(struct nvm_tgt_dev *tgt_dev, int clear)

if (clear) {
for (j = 0; j < ch_map->nr_luns; j++) {
int lun = j + lun_offs[j];
-   int lunid = (ch * dev->geo.nr_luns) + lun;
+   int lunid = (ch * dev_geo->nr_luns) + lun;
  
  WARN_ON(!test_and_clear_bit(lunid,

dev->lun_map));
@@ -143,19 +144,20 @@ static struct nvm_tgt_dev *nvm_create_tgt_dev(struct 
nvm_dev *dev,
  u16 lun_begin, u16 lun_end,
  u16 op)
  {
+   struct nvm_dev_geo *dev_geo = >dev_geo;
struct nvm_tgt_dev *tgt_dev = NULL;
struct nvm_dev_map *dev_rmap = dev->rmap;
struct nvm_dev_map *dev_map;
struct ppa_addr *luns;
int nr_luns = lun_end - lun_begin + 1;
int luns_left = nr_luns;
-   int nr_chnls = nr_luns / dev->geo.nr_luns;
-   int nr_chnls_mod = nr_luns % dev->geo.nr_luns;
-   int bch = lun_begin / dev->geo.nr_luns;
-   int blun = lun_begin % dev->geo.nr_luns;
+   int nr_chnls = nr_luns / dev_geo->nr_luns;
+   int nr_chnls_mod = nr_luns % dev_geo->nr_luns;
+   int bch = lun_begin / dev_geo->nr_luns;
+   int blun = lun_begin % dev_geo->nr_luns;
int lunid = 0;
int lun_balanced = 1;
-   int prev_nr_luns;
+   int sec_per_lun, prev_nr_luns;
int i, j;
  
  	nr_chnls = (nr_chnls_mod == 0) ? nr_chnls : nr_chnls + 1;

@@ -173,15 +175,15 @@ static struct nvm_tgt_dev *nvm_create_tgt_dev(struct 
nvm_dev *dev,
if (!luns)
goto err_luns;
  
-	prev_nr_luns = (luns_left > dev->geo.nr_luns) ?

-   dev->geo.nr_luns : luns_left;
+   prev_nr_luns = (luns_left > dev_geo->nr_luns) ?
+   dev_geo->nr_luns : luns_left;
for (i = 0; i < nr_chnls; i++) {
struct nvm_ch_map *ch_rmap = _rmap->chnls[i + bch];
int *lun_roffs = ch_rmap->lun_offs;
struct nvm_ch_map *ch_map = _map->chnls[i];
int *lun_offs;
-   int luns_in_chnl = (luns_left > dev->geo.nr_luns) ?
-   dev->geo.nr_luns : luns_left;
+   int luns_in_chnl = (luns_left > dev_geo->nr_luns) ?
+   dev_geo->nr_luns : luns_left;
  
  		if (lun_balanced && prev_nr_luns != luns_in_chnl)

lun_balanced = 0;
@@ -215,18 +217,22 @@ static struct nvm_tgt_dev *nvm_create_tgt_dev(struct 
nvm_dev *dev,
if (!tgt_dev)
goto err_ch;
  
-	memcpy(_dev->geo, >geo, sizeof(struct nvm_geo));

/* Target device only owns a portion of the physical device */
tgt_dev->geo.nr_chnls = nr_chnls;
-

Re: [PATCH 01/20] lightnvm: simplify geometry structure.

2018-02-21 Thread Matias Bjørling

On 02/21/2018 10:26 AM, Javier González wrote:

Currently, the device geometry is stored redundantly in the nvm_id and
nvm_geo structures at a device level. Moreover, when instantiating
targets on a specific number of LUNs, these structures are replicated
and manually modified to fit the instance channel and LUN partitioning.

Instead, create a generic geometry around two base structures:
nvm_dev_geo, which describes the geometry of the whole device and
nvm_geo, which describes the geometry of the instance. Since these share
a big part of the geometry, create a nvm_common_geo structure that keeps
the static geoometry values that are shared across instances.

As we introduce support for 2.0, these structures allow to abstract
spec. specific values and present a common geometry to targets.

Signed-off-by: Javier González 
---
  drivers/lightnvm/core.c  | 137 +++-
  drivers/lightnvm/pblk-core.c |  16 +-
  drivers/lightnvm/pblk-gc.c   |   2 +-
  drivers/lightnvm/pblk-init.c | 123 +++---
  drivers/lightnvm/pblk-read.c |   2 +-
  drivers/lightnvm/pblk-recovery.c |  14 +-
  drivers/lightnvm/pblk-rl.c   |   2 +-
  drivers/lightnvm/pblk-sysfs.c|  39 +++--
  drivers/lightnvm/pblk-write.c|   2 +-
  drivers/lightnvm/pblk.h  |  93 +--
  drivers/nvme/host/lightnvm.c | 339 +++
  include/linux/lightnvm.h | 204 ---
  12 files changed, 514 insertions(+), 459 deletions(-)

diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
index 689c97b97775..42596afdf64c 100644
--- a/drivers/lightnvm/core.c
+++ b/drivers/lightnvm/core.c
@@ -111,6 +111,7 @@ static void nvm_release_luns_err(struct nvm_dev *dev, int 
lun_begin,
  static void nvm_remove_tgt_dev(struct nvm_tgt_dev *tgt_dev, int clear)
  {
struct nvm_dev *dev = tgt_dev->parent;
+   struct nvm_dev_geo *dev_geo = >dev_geo;
struct nvm_dev_map *dev_map = tgt_dev->map;
int i, j;
  
@@ -122,7 +123,7 @@ static void nvm_remove_tgt_dev(struct nvm_tgt_dev *tgt_dev, int clear)

if (clear) {
for (j = 0; j < ch_map->nr_luns; j++) {
int lun = j + lun_offs[j];
-   int lunid = (ch * dev->geo.nr_luns) + lun;
+   int lunid = (ch * dev_geo->nr_luns) + lun;
  
  WARN_ON(!test_and_clear_bit(lunid,

dev->lun_map));
@@ -143,19 +144,20 @@ static struct nvm_tgt_dev *nvm_create_tgt_dev(struct 
nvm_dev *dev,
  u16 lun_begin, u16 lun_end,
  u16 op)
  {
+   struct nvm_dev_geo *dev_geo = >dev_geo;
struct nvm_tgt_dev *tgt_dev = NULL;
struct nvm_dev_map *dev_rmap = dev->rmap;
struct nvm_dev_map *dev_map;
struct ppa_addr *luns;
int nr_luns = lun_end - lun_begin + 1;
int luns_left = nr_luns;
-   int nr_chnls = nr_luns / dev->geo.nr_luns;
-   int nr_chnls_mod = nr_luns % dev->geo.nr_luns;
-   int bch = lun_begin / dev->geo.nr_luns;
-   int blun = lun_begin % dev->geo.nr_luns;
+   int nr_chnls = nr_luns / dev_geo->nr_luns;
+   int nr_chnls_mod = nr_luns % dev_geo->nr_luns;
+   int bch = lun_begin / dev_geo->nr_luns;
+   int blun = lun_begin % dev_geo->nr_luns;
int lunid = 0;
int lun_balanced = 1;
-   int prev_nr_luns;
+   int sec_per_lun, prev_nr_luns;
int i, j;
  
  	nr_chnls = (nr_chnls_mod == 0) ? nr_chnls : nr_chnls + 1;

@@ -173,15 +175,15 @@ static struct nvm_tgt_dev *nvm_create_tgt_dev(struct 
nvm_dev *dev,
if (!luns)
goto err_luns;
  
-	prev_nr_luns = (luns_left > dev->geo.nr_luns) ?

-   dev->geo.nr_luns : luns_left;
+   prev_nr_luns = (luns_left > dev_geo->nr_luns) ?
+   dev_geo->nr_luns : luns_left;
for (i = 0; i < nr_chnls; i++) {
struct nvm_ch_map *ch_rmap = _rmap->chnls[i + bch];
int *lun_roffs = ch_rmap->lun_offs;
struct nvm_ch_map *ch_map = _map->chnls[i];
int *lun_offs;
-   int luns_in_chnl = (luns_left > dev->geo.nr_luns) ?
-   dev->geo.nr_luns : luns_left;
+   int luns_in_chnl = (luns_left > dev_geo->nr_luns) ?
+   dev_geo->nr_luns : luns_left;
  
  		if (lun_balanced && prev_nr_luns != luns_in_chnl)

lun_balanced = 0;
@@ -215,18 +217,22 @@ static struct nvm_tgt_dev *nvm_create_tgt_dev(struct 
nvm_dev *dev,
if (!tgt_dev)
goto err_ch;
  
-	memcpy(_dev->geo, >geo, sizeof(struct nvm_geo));

/* Target device only owns a portion of the physical device */
tgt_dev->geo.nr_chnls = nr_chnls;
-   

Re: mmotm 2018-02-21-14-48 uploaded (mm/page_alloc.c on UML)

2018-02-21 Thread Michal Hocko
On Wed 21-02-18 15:58:41, Randy Dunlap wrote:
> On 02/21/2018 02:48 PM, a...@linux-foundation.org wrote:
> > The mm-of-the-moment snapshot 2018-02-21-14-48 has been uploaded to
> > 
> >http://www.ozlabs.org/~akpm/mmotm/
> > 
> > mmotm-readme.txt says
> > 
> > README for mm-of-the-moment:
> > 
> > http://www.ozlabs.org/~akpm/mmotm/
> > 
> > This is a snapshot of my -mm patch queue.  Uploaded at random hopefully
> > more than once a week.
> > 
> > You will need quilt to apply these patches to the latest Linus release (4.x
> > or 4.x-rcY).  The series file is in broken-out.tar.gz and is duplicated in
> > http://ozlabs.org/~akpm/mmotm/series
> > 
> > The file broken-out.tar.gz contains two datestamp files: .DATE and
> > .DATE--mm-dd-hh-mm-ss.  Both contain the string -mm-dd-hh-mm-ss,
> > followed by the base kernel version against which this patch series is to
> > be applied.
> 
> um (or uml) defconfig on i386 and/or x86_64:
> 
> ../mm/page_alloc.c: In function 'memmap_init_zone':
> ../mm/page_alloc.c:5450:5: error: implicit declaration of function 
> 'memblock_next_valid_pfn' [-Werror=implicit-function-declaration]
>  pfn = memblock_next_valid_pfn(pfn, end_pfn) - 1;
>  ^
> 
> 
> probably (?):
> From: Eugeniu Rosca 
> Subject: mm: page_alloc: skip over regions of invalid pfns on UMA

Yes. Steven has already reported the same [1]. There are two possible
ways around this. Either provide and empty stub or use ifdef around
memblock_next_valid_pfn. I would use the later because it is less
confusing. We really do not want memblock_next_valid_pfn to be used
outside of memblock aware code.

[1] http://lkml.kernel.org/r/20180222143057.3a1b3...@canb.auug.org.au


diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 4334d3a9c6a2..2836bc9e0999 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -5446,8 +5446,9 @@ void __meminit memmap_init_zone(unsigned long size, int 
nid, unsigned long zone,
 * end_pfn), such that we hit a valid pfn (or end_pfn)
 * on our next iteration of the loop.
 */
-   if (IS_ENABLED(CONFIG_HAVE_MEMBLOCK))
-   pfn = memblock_next_valid_pfn(pfn, end_pfn) - 1;
+#ifdef CONFIG_HAVE_MEMBLOCK
+   pfn = memblock_next_valid_pfn(pfn, end_pfn) - 1;
+#endif
continue;
}
if (!early_pfn_in_nid(pfn, nid))
-- 
Michal Hocko
SUSE Labs


Re: mmotm 2018-02-21-14-48 uploaded (mm/page_alloc.c on UML)

2018-02-21 Thread Michal Hocko
On Wed 21-02-18 15:58:41, Randy Dunlap wrote:
> On 02/21/2018 02:48 PM, a...@linux-foundation.org wrote:
> > The mm-of-the-moment snapshot 2018-02-21-14-48 has been uploaded to
> > 
> >http://www.ozlabs.org/~akpm/mmotm/
> > 
> > mmotm-readme.txt says
> > 
> > README for mm-of-the-moment:
> > 
> > http://www.ozlabs.org/~akpm/mmotm/
> > 
> > This is a snapshot of my -mm patch queue.  Uploaded at random hopefully
> > more than once a week.
> > 
> > You will need quilt to apply these patches to the latest Linus release (4.x
> > or 4.x-rcY).  The series file is in broken-out.tar.gz and is duplicated in
> > http://ozlabs.org/~akpm/mmotm/series
> > 
> > The file broken-out.tar.gz contains two datestamp files: .DATE and
> > .DATE--mm-dd-hh-mm-ss.  Both contain the string -mm-dd-hh-mm-ss,
> > followed by the base kernel version against which this patch series is to
> > be applied.
> 
> um (or uml) defconfig on i386 and/or x86_64:
> 
> ../mm/page_alloc.c: In function 'memmap_init_zone':
> ../mm/page_alloc.c:5450:5: error: implicit declaration of function 
> 'memblock_next_valid_pfn' [-Werror=implicit-function-declaration]
>  pfn = memblock_next_valid_pfn(pfn, end_pfn) - 1;
>  ^
> 
> 
> probably (?):
> From: Eugeniu Rosca 
> Subject: mm: page_alloc: skip over regions of invalid pfns on UMA

Yes. Steven has already reported the same [1]. There are two possible
ways around this. Either provide and empty stub or use ifdef around
memblock_next_valid_pfn. I would use the later because it is less
confusing. We really do not want memblock_next_valid_pfn to be used
outside of memblock aware code.

[1] http://lkml.kernel.org/r/20180222143057.3a1b3...@canb.auug.org.au


diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 4334d3a9c6a2..2836bc9e0999 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -5446,8 +5446,9 @@ void __meminit memmap_init_zone(unsigned long size, int 
nid, unsigned long zone,
 * end_pfn), such that we hit a valid pfn (or end_pfn)
 * on our next iteration of the loop.
 */
-   if (IS_ENABLED(CONFIG_HAVE_MEMBLOCK))
-   pfn = memblock_next_valid_pfn(pfn, end_pfn) - 1;
+#ifdef CONFIG_HAVE_MEMBLOCK
+   pfn = memblock_next_valid_pfn(pfn, end_pfn) - 1;
+#endif
continue;
}
if (!early_pfn_in_nid(pfn, nid))
-- 
Michal Hocko
SUSE Labs


Re: [PATCH] dt-bindings: fpga: Consolidate bridge properties

2018-02-21 Thread Michal Simek
On 21.2.2018 18:33, Moritz Fischer wrote:
> Consolidate bridge properties in a single file, instead of duplicating
> the same optional property over and over again.
> 
> Signed-off-by: Moritz Fischer 
> Cc: Alan Tull 
> Cc: Rob Herring 
> ---
>  .../devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt |  5 +
>  .../devicetree/bindings/fpga/altera-freeze-bridge.txt |  5 +
>  .../devicetree/bindings/fpga/altera-hps2fpga-bridge.txt   |  5 +
>  Documentation/devicetree/bindings/fpga/fpga-bridge.txt| 15 
> +++
>  .../devicetree/bindings/fpga/xilinx-pr-decoupler.txt  |  8 ++--
>  5 files changed, 20 insertions(+), 18 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/fpga/fpga-bridge.txt
> 
> diff --git 
> a/Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt 
> b/Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt
> index 817a8d4bf903..5dd0ff0f7b4e 100644
> --- a/Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt
> +++ b/Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt
> @@ -3,10 +3,7 @@ Altera FPGA To SDRAM Bridge Driver
>  Required properties:
>  - compatible : Should contain "altr,socfpga-fpga2sdram-bridge"
>  
> -Optional properties:
> -- bridge-enable  : 0 if driver should disable bridge at startup
> -   1 if driver should enable bridge at startup
> -   Default is to leave bridge in current state.
> +See Documentation/devicetree/bindings/fpga/fpga-bridge.txt for generic 
> bindings.
>  
>  Example:
>   fpga_bridge3: fpga-bridge@ffc25080 {
> diff --git a/Documentation/devicetree/bindings/fpga/altera-freeze-bridge.txt 
> b/Documentation/devicetree/bindings/fpga/altera-freeze-bridge.txt
> index f8e288c71b2d..8b26fbcff3c6 100644
> --- a/Documentation/devicetree/bindings/fpga/altera-freeze-bridge.txt
> +++ b/Documentation/devicetree/bindings/fpga/altera-freeze-bridge.txt
> @@ -10,10 +10,7 @@ Required properties:
>  - compatible : Should contain "altr,freeze-bridge-controller"
>  - regs   : base address and size for freeze bridge module
>  
> -Optional properties:
> -- bridge-enable  : 0 if driver should disable bridge at startup
> -   1 if driver should enable bridge at startup
> -   Default is to leave bridge in current state.
> +See Documentation/devicetree/bindings/fpga/fpga-bridge.txt for generic 
> bindings.
>  
>  Example:
>   freeze-controller@10450 {
> diff --git 
> a/Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt 
> b/Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt
> index 6406f9337eeb..68cce3945b10 100644
> --- a/Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt
> +++ b/Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt
> @@ -9,10 +9,7 @@ Required properties:
>  - resets : Phandle and reset specifier for this bridge's reset
>  - clocks : Clocks used by this module.
>  
> -Optional properties:
> -- bridge-enable  : 0 if driver should disable bridge at startup.
> -   1 if driver should enable bridge at startup.
> -   Default is to leave bridge in its current state.
> +See Documentation/devicetree/bindings/fpga/fpga-bridge.txt for generic 
> bindings.
>  
>  Example:
>   fpga_bridge0: fpga-bridge@ff40 {
> diff --git a/Documentation/devicetree/bindings/fpga/fpga-bridge.txt 
> b/Documentation/devicetree/bindings/fpga/fpga-bridge.txt
> new file mode 100644
> index ..82607b23a287
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/fpga/fpga-bridge.txt
> @@ -0,0 +1,15 @@
> +FPGA Bridge Device Tree Binding
> +
> +Moritz Fischer 2018 (Consolidated from previous bindings)

nit: I would remove your name and year - it is visible from git log.

> +
> +Optional properties:
> +- bridge-enable  : 0 if driver should disable bridge at startup
> +   1 if driver should enable bridge at startup
> +   Default is to leave bridge in current state.
> +
> +Example:
> + fpga_bridge3: fpga-bridge@ffc25080 {
> + compatible = "altr,socfpga-fpga2sdram-bridge";
> + reg = <0xffc25080 0x4>;
> + bridge-enable = <0>;
> + };
> diff --git a/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt 
> b/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt
> index 8dcfba926bc7..4284d293fa61 100644
> --- a/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt
> +++ b/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt
> @@ -18,12 +18,8 @@ Required properties:
>  - clocks : input clock to IP
>  - clock-names: should contain "aclk"
>  
> -Optional properties:
> -- bridge-enable  : 0 if driver should disable bridge at 

Re: [PATCH] dt-bindings: fpga: Consolidate bridge properties

2018-02-21 Thread Michal Simek
On 21.2.2018 18:33, Moritz Fischer wrote:
> Consolidate bridge properties in a single file, instead of duplicating
> the same optional property over and over again.
> 
> Signed-off-by: Moritz Fischer 
> Cc: Alan Tull 
> Cc: Rob Herring 
> ---
>  .../devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt |  5 +
>  .../devicetree/bindings/fpga/altera-freeze-bridge.txt |  5 +
>  .../devicetree/bindings/fpga/altera-hps2fpga-bridge.txt   |  5 +
>  Documentation/devicetree/bindings/fpga/fpga-bridge.txt| 15 
> +++
>  .../devicetree/bindings/fpga/xilinx-pr-decoupler.txt  |  8 ++--
>  5 files changed, 20 insertions(+), 18 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/fpga/fpga-bridge.txt
> 
> diff --git 
> a/Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt 
> b/Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt
> index 817a8d4bf903..5dd0ff0f7b4e 100644
> --- a/Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt
> +++ b/Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt
> @@ -3,10 +3,7 @@ Altera FPGA To SDRAM Bridge Driver
>  Required properties:
>  - compatible : Should contain "altr,socfpga-fpga2sdram-bridge"
>  
> -Optional properties:
> -- bridge-enable  : 0 if driver should disable bridge at startup
> -   1 if driver should enable bridge at startup
> -   Default is to leave bridge in current state.
> +See Documentation/devicetree/bindings/fpga/fpga-bridge.txt for generic 
> bindings.
>  
>  Example:
>   fpga_bridge3: fpga-bridge@ffc25080 {
> diff --git a/Documentation/devicetree/bindings/fpga/altera-freeze-bridge.txt 
> b/Documentation/devicetree/bindings/fpga/altera-freeze-bridge.txt
> index f8e288c71b2d..8b26fbcff3c6 100644
> --- a/Documentation/devicetree/bindings/fpga/altera-freeze-bridge.txt
> +++ b/Documentation/devicetree/bindings/fpga/altera-freeze-bridge.txt
> @@ -10,10 +10,7 @@ Required properties:
>  - compatible : Should contain "altr,freeze-bridge-controller"
>  - regs   : base address and size for freeze bridge module
>  
> -Optional properties:
> -- bridge-enable  : 0 if driver should disable bridge at startup
> -   1 if driver should enable bridge at startup
> -   Default is to leave bridge in current state.
> +See Documentation/devicetree/bindings/fpga/fpga-bridge.txt for generic 
> bindings.
>  
>  Example:
>   freeze-controller@10450 {
> diff --git 
> a/Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt 
> b/Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt
> index 6406f9337eeb..68cce3945b10 100644
> --- a/Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt
> +++ b/Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt
> @@ -9,10 +9,7 @@ Required properties:
>  - resets : Phandle and reset specifier for this bridge's reset
>  - clocks : Clocks used by this module.
>  
> -Optional properties:
> -- bridge-enable  : 0 if driver should disable bridge at startup.
> -   1 if driver should enable bridge at startup.
> -   Default is to leave bridge in its current state.
> +See Documentation/devicetree/bindings/fpga/fpga-bridge.txt for generic 
> bindings.
>  
>  Example:
>   fpga_bridge0: fpga-bridge@ff40 {
> diff --git a/Documentation/devicetree/bindings/fpga/fpga-bridge.txt 
> b/Documentation/devicetree/bindings/fpga/fpga-bridge.txt
> new file mode 100644
> index ..82607b23a287
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/fpga/fpga-bridge.txt
> @@ -0,0 +1,15 @@
> +FPGA Bridge Device Tree Binding
> +
> +Moritz Fischer 2018 (Consolidated from previous bindings)

nit: I would remove your name and year - it is visible from git log.

> +
> +Optional properties:
> +- bridge-enable  : 0 if driver should disable bridge at startup
> +   1 if driver should enable bridge at startup
> +   Default is to leave bridge in current state.
> +
> +Example:
> + fpga_bridge3: fpga-bridge@ffc25080 {
> + compatible = "altr,socfpga-fpga2sdram-bridge";
> + reg = <0xffc25080 0x4>;
> + bridge-enable = <0>;
> + };
> diff --git a/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt 
> b/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt
> index 8dcfba926bc7..4284d293fa61 100644
> --- a/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt
> +++ b/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt
> @@ -18,12 +18,8 @@ Required properties:
>  - clocks : input clock to IP
>  - clock-names: should contain "aclk"
>  
> -Optional properties:
> -- bridge-enable  : 0 if driver should disable bridge at startup
> -   1 if driver should 

Re: linux-next: build failure after merge of the akpm-current tree

2018-02-21 Thread Michal Hocko
On Thu 22-02-18 14:30:57, Stephen Rothwell wrote:
> Hi Andrew,
> 
> [As reported by Randy for uml ...]
> 
> After merging the akpm-current tree, today's linux-next build (sparc
> defconfig) failed like this:
> 
> /home/sfr/next/next/mm/page_alloc.c: In function 'memmap_init_zone':
> /home/sfr/next/next/mm/page_alloc.c:5450:11: error: implicit declaration of 
> function 'memblock_next_valid_pfn'; did you mean 'memblock_virt_alloc_low'? 
> [-Werror=implicit-function-declaration]
>  pfn = memblock_next_valid_pfn(pfn, end_pfn) - 1;
>^~~
>memblock_virt_alloc_low

This is interesting. I thought that IS_ENABLED(CONFIG_HAVE_MEMBLOCK)
would have the same meaning as ifdef CONFIG_HAVE_MEMBLOCK so the branch
will never be considered. If that is not the case then I would rather
reintroduce that ifdef. We already have those in the function anyway.
-- 
Michal Hocko
SUSE Labs


Re: linux-next: build failure after merge of the akpm-current tree

2018-02-21 Thread Michal Hocko
On Thu 22-02-18 14:30:57, Stephen Rothwell wrote:
> Hi Andrew,
> 
> [As reported by Randy for uml ...]
> 
> After merging the akpm-current tree, today's linux-next build (sparc
> defconfig) failed like this:
> 
> /home/sfr/next/next/mm/page_alloc.c: In function 'memmap_init_zone':
> /home/sfr/next/next/mm/page_alloc.c:5450:11: error: implicit declaration of 
> function 'memblock_next_valid_pfn'; did you mean 'memblock_virt_alloc_low'? 
> [-Werror=implicit-function-declaration]
>  pfn = memblock_next_valid_pfn(pfn, end_pfn) - 1;
>^~~
>memblock_virt_alloc_low

This is interesting. I thought that IS_ENABLED(CONFIG_HAVE_MEMBLOCK)
would have the same meaning as ifdef CONFIG_HAVE_MEMBLOCK so the branch
will never be considered. If that is not the case then I would rather
reintroduce that ifdef. We already have those in the function anyway.
-- 
Michal Hocko
SUSE Labs


Re: [PATCH 4.15 000/163] 4.15.5-stable review

2018-02-21 Thread Greg Kroah-Hartman
On Wed, Feb 21, 2018 at 01:13:46PM -0700, Shuah Khan wrote:
> On 02/21/2018 05:47 AM, Greg Kroah-Hartman wrote:
> > This is the start of the stable review cycle for the 4.15.5 release.
> > There are 163 patches in this series, all will be posted as a response
> > to this one.  If anyone has any issues with these being applied, please
> > let me know.
> > 
> > Responses should be made by Fri Feb 23 12:44:46 UTC 2018.
> > Anything received after that time might be too late.
> > 
> > The whole patch series can be found in one patch at:
> > 
> > https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.15.5-rc1.gz
> > or in the git tree and branch at:
> > 
> > git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git 
> > linux-4.15.y
> > and the diffstat can be found below.
> > 
> > thanks,
> > 
> > greg k-h
> > 
> 
> Compiled and booted on my test system. No dmesg regressions.

Thanks for testing all of these and letting me know.

greg k-h


Re: [PATCH 4.15 000/163] 4.15.5-stable review

2018-02-21 Thread Greg Kroah-Hartman
On Wed, Feb 21, 2018 at 01:13:46PM -0700, Shuah Khan wrote:
> On 02/21/2018 05:47 AM, Greg Kroah-Hartman wrote:
> > This is the start of the stable review cycle for the 4.15.5 release.
> > There are 163 patches in this series, all will be posted as a response
> > to this one.  If anyone has any issues with these being applied, please
> > let me know.
> > 
> > Responses should be made by Fri Feb 23 12:44:46 UTC 2018.
> > Anything received after that time might be too late.
> > 
> > The whole patch series can be found in one patch at:
> > 
> > https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.15.5-rc1.gz
> > or in the git tree and branch at:
> > 
> > git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git 
> > linux-4.15.y
> > and the diffstat can be found below.
> > 
> > thanks,
> > 
> > greg k-h
> > 
> 
> Compiled and booted on my test system. No dmesg regressions.

Thanks for testing all of these and letting me know.

greg k-h


[RFC tip/locking/lockdep v5 04/17] lockdep: Introduce lock_list::dep

2018-02-21 Thread Boqun Feng
To add recursive read locks into the dependency graph, we need to store
the types of dependencies for the BFS later. There are four kinds of
dependencies:

*   Non-recursive -> Non-recursive dependencies(NN)
e.g. write_lock(prev) -> write_lock(next), we can also write
this as "prev --(NN)--> next".

*   Recursive -> Non-recursive dependencies(RN)
e.g. read_lock(prev) -> write_lock(next), we can also write this
as "prev --(RN)--> next".

*   Non-recursive -> recursive dependencies(NR)
e.g. write_lock(prev) -> read_lock(next), we can also write this
as "prev --(NR)--> next".

*   Recursive -> recursive dependencies(RR)
e.g. read_lock(prev) -> read_lock(next), we can also write this
as "prev --(RR)--> next".

Given a pair of two locks, four kinds of dependencies could all exist
between them, so we use 4 bit for the presence of each kind(stored in
lock_list::dep). Helper functions and marcos are also introduced to
convert a pair of locks into ::dep bit and maintain the addition of
different kinds of dependencies.

Signed-off-by: Boqun Feng 
---
 include/linux/lockdep.h  |  2 ++
 kernel/locking/lockdep.c | 48 +---
 2 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 6fc77d4dbdcd..ab1e5a7d8864 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -187,6 +187,8 @@ struct lock_list {
struct lock_class   *class;
struct stack_trace  trace;
int distance;
+   /* bitmap of different dependencies from head to this */
+   u16 dep;
 
/*
 * The parent field is used to implement breadth-first search, and the
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 5e6bf8d6954d..acd25bfc336d 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -859,7 +859,7 @@ static struct lock_list *alloc_list_entry(void)
  * Add a new dependency to the head of the list:
  */
 static int add_lock_to_list(struct lock_class *this, struct list_head *head,
-   unsigned long ip, int distance,
+   unsigned long ip, int distance, unsigned int dep,
struct stack_trace *trace)
 {
struct lock_list *entry;
@@ -872,6 +872,7 @@ static int add_lock_to_list(struct lock_class *this, struct 
list_head *head,
return 0;
 
entry->class = this;
+   entry->dep = dep;
entry->distance = distance;
entry->trace = *trace;
/*
@@ -1012,6 +1013,33 @@ static inline bool bfs_error(enum bfs_result res)
return res < 0;
 }
 
+#define DEP_NN_BIT 0
+#define DEP_RN_BIT 1
+#define DEP_NR_BIT 2
+#define DEP_RR_BIT 3
+
+#define DEP_NN_MASK (1U << (DEP_NN_BIT))
+#define DEP_RN_MASK (1U << (DEP_RN_BIT))
+#define DEP_NR_MASK (1U << (DEP_NR_BIT))
+#define DEP_RR_MASK (1U << (DEP_RR_BIT))
+
+static inline unsigned int __calc_dep_bit(int prev, int next)
+{
+   if (prev == 2 && next != 2)
+   return DEP_RN_BIT;
+   if (prev != 2 && next == 2)
+   return DEP_NR_BIT;
+   if (prev == 2 && next == 2)
+   return DEP_RR_BIT;
+   else
+   return DEP_NN_BIT;
+}
+
+static inline unsigned int calc_dep(int prev, int next)
+{
+   return 1U << __calc_dep_bit(prev, next);
+}
+
 static enum bfs_result __bfs(struct lock_list *source_entry,
 void *data,
 int (*match)(struct lock_list *entry, void *data),
@@ -1921,6 +1949,16 @@ check_prev_add(struct task_struct *curr, struct 
held_lock *prev,
if (entry->class == hlock_class(next)) {
if (distance == 1)
entry->distance = 1;
+   entry->dep |= calc_dep(prev->read, next->read);
+   }
+   }
+
+   /* Also, update the reverse dependency in @next's ->locks_before list */
+   list_for_each_entry(entry, _class(next)->locks_before, entry) {
+   if (entry->class == hlock_class(prev)) {
+   if (distance == 1)
+   entry->distance = 1;
+   entry->dep |= calc_dep(next->read, prev->read);
return 1;
}
}
@@ -1948,14 +1986,18 @@ check_prev_add(struct task_struct *curr, struct 
held_lock *prev,
 */
ret = add_lock_to_list(hlock_class(next),
   _class(prev)->locks_after,
-  next->acquire_ip, distance, trace);
+  next->acquire_ip, distance,
+  calc_dep(prev->read, next->read),
+  trace);
 
if (!ret)
return 0;
 
  

[RFC tip/locking/lockdep v5 02/17] lockdep: Make __bfs() visit every dependency until a match

2018-02-21 Thread Boqun Feng
Currently, __bfs() will do a breadth-first search in the dependency
graph and visit each lock class in the graph exactly once, so for
example, in the following graph:

A -> B
|^
||
+--> C

a __bfs() call starts at A, will visit B through dependency A -> B and
visit C through dependency A -> C and that's it, IOW, __bfs() will not
visit dependency C -> B.

This is OK for now, as we only have strong dependencies in the
dependency graph, so whenever there is a traverse path from A to B in
__bfs(), it means A has strong dependency to B(IOW, B depends on A
strongly). So no need to visit all dependencies in the graph.

However, as we are going to add recursive-read lock into the dependency
graph, afterwards, not all the paths mean strong dependencies, in the
same example above, dependency A -> B may be a weak dependency and
traverse A -> C -> B may be a strong dependency path. And with the old
way of __bfs()(i.e. visiting every lock class exactly once), we will
miss the strong dependency path, which will result into failing to find
a deadlock. To cure this for the future, we need to find a way for
__bfs() to visit each dependency, rather than each class, exactly once
in the search until we find a match.

The solution is simple:

We used to mark lock_class::lockdep_dependency_gen_id to indicate a
class has been visited in __bfs(), now we change the semantics a little
bit: we now mark lock_class::lockdep_dependency_gen_id to indicate _all
the dependencies_ in its lock_{after,before} have been visited in the
__bfs()(note we only take one direction in a __bfs() search). In this
way, every dependency is guaranteed to be visited until we find a match.

Signed-off-by: Boqun Feng 
---
 kernel/locking/lockdep.c | 61 +++-
 1 file changed, 34 insertions(+), 27 deletions(-)

diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 9b2e318bcc81..c80f8276ceaa 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -948,24 +948,20 @@ static inline unsigned int  __cq_get_elem_count(struct 
circular_queue *cq)
return (cq->rear - cq->front) & CQ_MASK;
 }
 
-static inline void mark_lock_accessed(struct lock_list *lock,
-   struct lock_list *parent)
+static inline void mark_lock_list_accessed(struct lock_class *class)
 {
-   unsigned long nr;
+   class->dep_gen_id = lockdep_dependency_gen_id;
+}
 
-   nr = lock - list_entries;
-   WARN_ON(nr >= nr_list_entries); /* Out-of-bounds, input fail */
+static inline void visit_lock_entry(struct lock_list *lock,
+   struct lock_list *parent)
+{
lock->parent = parent;
-   lock->class->dep_gen_id = lockdep_dependency_gen_id;
 }
 
-static inline unsigned long lock_accessed(struct lock_list *lock)
+static inline unsigned long lock_list_accessed(struct lock_class *class)
 {
-   unsigned long nr;
-
-   nr = lock - list_entries;
-   WARN_ON(nr >= nr_list_entries); /* Out-of-bounds, input fail */
-   return lock->class->dep_gen_id == lockdep_dependency_gen_id;
+   return class->dep_gen_id == lockdep_dependency_gen_id;
 }
 
 static inline struct lock_list *get_lock_parent(struct lock_list *child)
@@ -1054,6 +1050,18 @@ static enum bfs_result __bfs(struct lock_list 
*source_entry,
goto exit;
}
 
+   /*
+* If we have visited all the dependencies from this @lock to
+* others(iow, if we have visited all lock_list entries in
+* @lock->class->locks_{after,before}, we skip, otherwise go
+* and visit all the dependencies in the list and mark this
+* list accessed.
+*/
+   if (lock_list_accessed(lock->class))
+   continue;
+   else
+   mark_lock_list_accessed(lock->class);
+
if (forward)
head = >class->locks_after;
else
@@ -1062,23 +1070,22 @@ static enum bfs_result __bfs(struct lock_list 
*source_entry,
DEBUG_LOCKS_WARN_ON(!irqs_disabled());
 
list_for_each_entry_rcu(entry, head, entry) {
-   if (!lock_accessed(entry)) {
-   unsigned int cq_depth;
-   mark_lock_accessed(entry, lock);
-   if (match(entry, data)) {
-   *target_entry = entry;
-   ret = BFS_RMATCH;
-   goto exit;
-   }
+   unsigned int cq_depth;
 
-   if (__cq_enqueue(cq, (unsigned long)entry)) {
-   ret = BFS_EQUEUEFULL;
-

[RFC tip/locking/lockdep v5 04/17] lockdep: Introduce lock_list::dep

2018-02-21 Thread Boqun Feng
To add recursive read locks into the dependency graph, we need to store
the types of dependencies for the BFS later. There are four kinds of
dependencies:

*   Non-recursive -> Non-recursive dependencies(NN)
e.g. write_lock(prev) -> write_lock(next), we can also write
this as "prev --(NN)--> next".

*   Recursive -> Non-recursive dependencies(RN)
e.g. read_lock(prev) -> write_lock(next), we can also write this
as "prev --(RN)--> next".

*   Non-recursive -> recursive dependencies(NR)
e.g. write_lock(prev) -> read_lock(next), we can also write this
as "prev --(NR)--> next".

*   Recursive -> recursive dependencies(RR)
e.g. read_lock(prev) -> read_lock(next), we can also write this
as "prev --(RR)--> next".

Given a pair of two locks, four kinds of dependencies could all exist
between them, so we use 4 bit for the presence of each kind(stored in
lock_list::dep). Helper functions and marcos are also introduced to
convert a pair of locks into ::dep bit and maintain the addition of
different kinds of dependencies.

Signed-off-by: Boqun Feng 
---
 include/linux/lockdep.h  |  2 ++
 kernel/locking/lockdep.c | 48 +---
 2 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 6fc77d4dbdcd..ab1e5a7d8864 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -187,6 +187,8 @@ struct lock_list {
struct lock_class   *class;
struct stack_trace  trace;
int distance;
+   /* bitmap of different dependencies from head to this */
+   u16 dep;
 
/*
 * The parent field is used to implement breadth-first search, and the
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 5e6bf8d6954d..acd25bfc336d 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -859,7 +859,7 @@ static struct lock_list *alloc_list_entry(void)
  * Add a new dependency to the head of the list:
  */
 static int add_lock_to_list(struct lock_class *this, struct list_head *head,
-   unsigned long ip, int distance,
+   unsigned long ip, int distance, unsigned int dep,
struct stack_trace *trace)
 {
struct lock_list *entry;
@@ -872,6 +872,7 @@ static int add_lock_to_list(struct lock_class *this, struct 
list_head *head,
return 0;
 
entry->class = this;
+   entry->dep = dep;
entry->distance = distance;
entry->trace = *trace;
/*
@@ -1012,6 +1013,33 @@ static inline bool bfs_error(enum bfs_result res)
return res < 0;
 }
 
+#define DEP_NN_BIT 0
+#define DEP_RN_BIT 1
+#define DEP_NR_BIT 2
+#define DEP_RR_BIT 3
+
+#define DEP_NN_MASK (1U << (DEP_NN_BIT))
+#define DEP_RN_MASK (1U << (DEP_RN_BIT))
+#define DEP_NR_MASK (1U << (DEP_NR_BIT))
+#define DEP_RR_MASK (1U << (DEP_RR_BIT))
+
+static inline unsigned int __calc_dep_bit(int prev, int next)
+{
+   if (prev == 2 && next != 2)
+   return DEP_RN_BIT;
+   if (prev != 2 && next == 2)
+   return DEP_NR_BIT;
+   if (prev == 2 && next == 2)
+   return DEP_RR_BIT;
+   else
+   return DEP_NN_BIT;
+}
+
+static inline unsigned int calc_dep(int prev, int next)
+{
+   return 1U << __calc_dep_bit(prev, next);
+}
+
 static enum bfs_result __bfs(struct lock_list *source_entry,
 void *data,
 int (*match)(struct lock_list *entry, void *data),
@@ -1921,6 +1949,16 @@ check_prev_add(struct task_struct *curr, struct 
held_lock *prev,
if (entry->class == hlock_class(next)) {
if (distance == 1)
entry->distance = 1;
+   entry->dep |= calc_dep(prev->read, next->read);
+   }
+   }
+
+   /* Also, update the reverse dependency in @next's ->locks_before list */
+   list_for_each_entry(entry, _class(next)->locks_before, entry) {
+   if (entry->class == hlock_class(prev)) {
+   if (distance == 1)
+   entry->distance = 1;
+   entry->dep |= calc_dep(next->read, prev->read);
return 1;
}
}
@@ -1948,14 +1986,18 @@ check_prev_add(struct task_struct *curr, struct 
held_lock *prev,
 */
ret = add_lock_to_list(hlock_class(next),
   _class(prev)->locks_after,
-  next->acquire_ip, distance, trace);
+  next->acquire_ip, distance,
+  calc_dep(prev->read, next->read),
+  trace);
 
if (!ret)
return 0;
 
ret = 

[RFC tip/locking/lockdep v5 02/17] lockdep: Make __bfs() visit every dependency until a match

2018-02-21 Thread Boqun Feng
Currently, __bfs() will do a breadth-first search in the dependency
graph and visit each lock class in the graph exactly once, so for
example, in the following graph:

A -> B
|^
||
+--> C

a __bfs() call starts at A, will visit B through dependency A -> B and
visit C through dependency A -> C and that's it, IOW, __bfs() will not
visit dependency C -> B.

This is OK for now, as we only have strong dependencies in the
dependency graph, so whenever there is a traverse path from A to B in
__bfs(), it means A has strong dependency to B(IOW, B depends on A
strongly). So no need to visit all dependencies in the graph.

However, as we are going to add recursive-read lock into the dependency
graph, afterwards, not all the paths mean strong dependencies, in the
same example above, dependency A -> B may be a weak dependency and
traverse A -> C -> B may be a strong dependency path. And with the old
way of __bfs()(i.e. visiting every lock class exactly once), we will
miss the strong dependency path, which will result into failing to find
a deadlock. To cure this for the future, we need to find a way for
__bfs() to visit each dependency, rather than each class, exactly once
in the search until we find a match.

The solution is simple:

We used to mark lock_class::lockdep_dependency_gen_id to indicate a
class has been visited in __bfs(), now we change the semantics a little
bit: we now mark lock_class::lockdep_dependency_gen_id to indicate _all
the dependencies_ in its lock_{after,before} have been visited in the
__bfs()(note we only take one direction in a __bfs() search). In this
way, every dependency is guaranteed to be visited until we find a match.

Signed-off-by: Boqun Feng 
---
 kernel/locking/lockdep.c | 61 +++-
 1 file changed, 34 insertions(+), 27 deletions(-)

diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 9b2e318bcc81..c80f8276ceaa 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -948,24 +948,20 @@ static inline unsigned int  __cq_get_elem_count(struct 
circular_queue *cq)
return (cq->rear - cq->front) & CQ_MASK;
 }
 
-static inline void mark_lock_accessed(struct lock_list *lock,
-   struct lock_list *parent)
+static inline void mark_lock_list_accessed(struct lock_class *class)
 {
-   unsigned long nr;
+   class->dep_gen_id = lockdep_dependency_gen_id;
+}
 
-   nr = lock - list_entries;
-   WARN_ON(nr >= nr_list_entries); /* Out-of-bounds, input fail */
+static inline void visit_lock_entry(struct lock_list *lock,
+   struct lock_list *parent)
+{
lock->parent = parent;
-   lock->class->dep_gen_id = lockdep_dependency_gen_id;
 }
 
-static inline unsigned long lock_accessed(struct lock_list *lock)
+static inline unsigned long lock_list_accessed(struct lock_class *class)
 {
-   unsigned long nr;
-
-   nr = lock - list_entries;
-   WARN_ON(nr >= nr_list_entries); /* Out-of-bounds, input fail */
-   return lock->class->dep_gen_id == lockdep_dependency_gen_id;
+   return class->dep_gen_id == lockdep_dependency_gen_id;
 }
 
 static inline struct lock_list *get_lock_parent(struct lock_list *child)
@@ -1054,6 +1050,18 @@ static enum bfs_result __bfs(struct lock_list 
*source_entry,
goto exit;
}
 
+   /*
+* If we have visited all the dependencies from this @lock to
+* others(iow, if we have visited all lock_list entries in
+* @lock->class->locks_{after,before}, we skip, otherwise go
+* and visit all the dependencies in the list and mark this
+* list accessed.
+*/
+   if (lock_list_accessed(lock->class))
+   continue;
+   else
+   mark_lock_list_accessed(lock->class);
+
if (forward)
head = >class->locks_after;
else
@@ -1062,23 +1070,22 @@ static enum bfs_result __bfs(struct lock_list 
*source_entry,
DEBUG_LOCKS_WARN_ON(!irqs_disabled());
 
list_for_each_entry_rcu(entry, head, entry) {
-   if (!lock_accessed(entry)) {
-   unsigned int cq_depth;
-   mark_lock_accessed(entry, lock);
-   if (match(entry, data)) {
-   *target_entry = entry;
-   ret = BFS_RMATCH;
-   goto exit;
-   }
+   unsigned int cq_depth;
 
-   if (__cq_enqueue(cq, (unsigned long)entry)) {
-   ret = BFS_EQUEUEFULL;
-   goto 

[RFC tip/locking/lockdep v5 05/17] lockdep: Extend __bfs() to work with multiple kinds of dependencies

2018-02-21 Thread Boqun Feng
Now we have four kinds of dependencies in the dependency graph, and not
all the pathes carry strong dependencies, for example:

Given lock A, B, C, if we have:

CPU1CPU2
=   ==
write_lock(A);  read_lock(B);
read_lock(B);   write_lock(C);

then we have dependencies A--(NR)-->B, and B--(RN)-->C, (NR and
RN are to indicate the dependency kind), A actually doesn't have
strong dependency to C(IOW, C doesn't depend on A), to see this,
let's say we have a third CPU3 doing:

CPU3:
=
write_lock(C);
write_lock(A);

, this is not a deadlock. However if we change the read_lock()
on CPU2 to a write_lock(), it's a deadlock then.

So A --(NR)--> B --(RN)--> C is not a strong dependency path but
A --(NR)--> B --(NN)-->C is a strong dependency path.

We can generalize this as: If a path of dependencies doesn't have two
adjacent dependencies as (*R)--L-->(R*), where L is some lock, it is a
strong dependency path, otherwise it's not.

Now our mission is to make __bfs() traverse only the strong dependency
paths, which is simple: we record whether we have -(*R)-> at the current
tail of the path in lock_list::is_rr, and whenever we pick a dependency
in the traverse, we 1) make sure we don't pick a -(R*)-> dependency if
our current tail is -(*R)-> and 2) greedily pick a -(*N)-> as hard as
possible.

With this extension for __bfs(), we now need to initialize the root of
__bfs() properly(with a correct ->is_rr), to do so, we introduce some
helper functions, which also cleans up a little bit for the __bfs() root
initialization code.

Signed-off-by: Boqun Feng 
---
 include/linux/lockdep.h  |   2 +
 kernel/locking/lockdep.c | 116 ---
 2 files changed, 101 insertions(+), 17 deletions(-)

diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index ab1e5a7d8864..a1f91f8680bd 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -189,6 +189,8 @@ struct lock_list {
int distance;
/* bitmap of different dependencies from head to this */
u16 dep;
+   /* used by BFS to record whether this is picked as a recursive read */
+   u16 is_rr;
 
/*
 * The parent field is used to implement breadth-first search, and the
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index acd25bfc336d..07bcfaac6fe2 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -1040,6 +1040,89 @@ static inline unsigned int calc_dep(int prev, int next)
return 1U << __calc_dep_bit(prev, next);
 }
 
+/*
+ * return -1 if no proper dependency could be picked
+ * return 0 if a -(*N)-> dependency could be picked
+ * return 1 if only a -(*R)-> dependency could be picked
+ *
+ * N: non-recursive lock
+ * R: recursive read lock
+ */
+static inline int pick_dep(u16 is_rr, u16 cap_dep)
+{
+   if (is_rr) { /* could only pick -(N*)-> */
+   if (cap_dep & DEP_NN_MASK)
+   return 0;
+   else if (cap_dep & DEP_NR_MASK)
+   return 1;
+   else
+   return -1;
+   } else {
+   if (cap_dep & DEP_NN_MASK || cap_dep & DEP_RN_MASK)
+   return 0;
+   else
+   return 1;
+   }
+}
+
+/*
+ * Initialize a lock_list entry @lock belonging to @class as the root for a BFS
+ * search.
+ */
+static inline void __bfs_init_root(struct lock_list *lock,
+  struct lock_class *class)
+{
+   lock->class = class;
+   lock->parent = NULL;
+   lock->is_rr = 0;
+}
+
+/*
+ * Initialize a lock_list entry @lock based on a lock acquisition @hlock as the
+ * root for a BFS search.
+ */
+static inline void bfs_init_root(struct lock_list *lock,
+struct held_lock *hlock)
+{
+   __bfs_init_root(lock, hlock_class(hlock));
+   lock->is_rr = (hlock->read == 2);
+}
+
+/*
+ * Breadth-First Search to find a strong path in the dependency graph.
+ *
+ * @source_entry: the source of the path we are searching for.
+ * @data: data used for the second parameter of @match function
+ * @match: match function for the search
+ * @target_entry: pointer to the target of a matched path
+ * @forward: direction of path, the lockdep dependency forward or backward
+ *
+ * We may have multiple edges(considering different kinds of dependencies, e.g.
+ * -(NR)-> and -(RN)->) between two nodes in the dependency graph, which may
+ * undermine the normal BFS algorithm, however, we are lucky because: in the
+ * search, for each pair of adjacent nodes, we can pick the edge greedily:
+ *
+ * Say we have nodes L0, L1 and L2, and we 

[RFC tip/locking/lockdep v5 05/17] lockdep: Extend __bfs() to work with multiple kinds of dependencies

2018-02-21 Thread Boqun Feng
Now we have four kinds of dependencies in the dependency graph, and not
all the pathes carry strong dependencies, for example:

Given lock A, B, C, if we have:

CPU1CPU2
=   ==
write_lock(A);  read_lock(B);
read_lock(B);   write_lock(C);

then we have dependencies A--(NR)-->B, and B--(RN)-->C, (NR and
RN are to indicate the dependency kind), A actually doesn't have
strong dependency to C(IOW, C doesn't depend on A), to see this,
let's say we have a third CPU3 doing:

CPU3:
=
write_lock(C);
write_lock(A);

, this is not a deadlock. However if we change the read_lock()
on CPU2 to a write_lock(), it's a deadlock then.

So A --(NR)--> B --(RN)--> C is not a strong dependency path but
A --(NR)--> B --(NN)-->C is a strong dependency path.

We can generalize this as: If a path of dependencies doesn't have two
adjacent dependencies as (*R)--L-->(R*), where L is some lock, it is a
strong dependency path, otherwise it's not.

Now our mission is to make __bfs() traverse only the strong dependency
paths, which is simple: we record whether we have -(*R)-> at the current
tail of the path in lock_list::is_rr, and whenever we pick a dependency
in the traverse, we 1) make sure we don't pick a -(R*)-> dependency if
our current tail is -(*R)-> and 2) greedily pick a -(*N)-> as hard as
possible.

With this extension for __bfs(), we now need to initialize the root of
__bfs() properly(with a correct ->is_rr), to do so, we introduce some
helper functions, which also cleans up a little bit for the __bfs() root
initialization code.

Signed-off-by: Boqun Feng 
---
 include/linux/lockdep.h  |   2 +
 kernel/locking/lockdep.c | 116 ---
 2 files changed, 101 insertions(+), 17 deletions(-)

diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index ab1e5a7d8864..a1f91f8680bd 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -189,6 +189,8 @@ struct lock_list {
int distance;
/* bitmap of different dependencies from head to this */
u16 dep;
+   /* used by BFS to record whether this is picked as a recursive read */
+   u16 is_rr;
 
/*
 * The parent field is used to implement breadth-first search, and the
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index acd25bfc336d..07bcfaac6fe2 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -1040,6 +1040,89 @@ static inline unsigned int calc_dep(int prev, int next)
return 1U << __calc_dep_bit(prev, next);
 }
 
+/*
+ * return -1 if no proper dependency could be picked
+ * return 0 if a -(*N)-> dependency could be picked
+ * return 1 if only a -(*R)-> dependency could be picked
+ *
+ * N: non-recursive lock
+ * R: recursive read lock
+ */
+static inline int pick_dep(u16 is_rr, u16 cap_dep)
+{
+   if (is_rr) { /* could only pick -(N*)-> */
+   if (cap_dep & DEP_NN_MASK)
+   return 0;
+   else if (cap_dep & DEP_NR_MASK)
+   return 1;
+   else
+   return -1;
+   } else {
+   if (cap_dep & DEP_NN_MASK || cap_dep & DEP_RN_MASK)
+   return 0;
+   else
+   return 1;
+   }
+}
+
+/*
+ * Initialize a lock_list entry @lock belonging to @class as the root for a BFS
+ * search.
+ */
+static inline void __bfs_init_root(struct lock_list *lock,
+  struct lock_class *class)
+{
+   lock->class = class;
+   lock->parent = NULL;
+   lock->is_rr = 0;
+}
+
+/*
+ * Initialize a lock_list entry @lock based on a lock acquisition @hlock as the
+ * root for a BFS search.
+ */
+static inline void bfs_init_root(struct lock_list *lock,
+struct held_lock *hlock)
+{
+   __bfs_init_root(lock, hlock_class(hlock));
+   lock->is_rr = (hlock->read == 2);
+}
+
+/*
+ * Breadth-First Search to find a strong path in the dependency graph.
+ *
+ * @source_entry: the source of the path we are searching for.
+ * @data: data used for the second parameter of @match function
+ * @match: match function for the search
+ * @target_entry: pointer to the target of a matched path
+ * @forward: direction of path, the lockdep dependency forward or backward
+ *
+ * We may have multiple edges(considering different kinds of dependencies, e.g.
+ * -(NR)-> and -(RN)->) between two nodes in the dependency graph, which may
+ * undermine the normal BFS algorithm, however, we are lucky because: in the
+ * search, for each pair of adjacent nodes, we can pick the edge greedily:
+ *
+ * Say we have nodes L0, L1 and L2, and we already pick edge from L0 

[RFC tip/locking/lockdep v5 08/17] lockdep: Fix recursive read lock related safe->unsafe detection

2018-02-21 Thread Boqun Feng
There are four cases for recursive read lock realted deadlocks:

(--(X..Y)--> means a strong dependency path starts with a --(X*)-->
dependency and ends with a --(*Y)-- dependency.)

1.  An irq-safe lock L1 has a dependency --(*..*)--> to an
irq-unsafe lock L2.

2.  An irq-read-safe lock L1 has a dependency --(N..*)--> to an
irq-unsafe lock L2.

3.  An irq-safe lock L1 has a dependency --(*..N)--> to an
irq-read-unsafe lock L2.

4.  An irq-read-safe lock L1 has a dependency --(N..N)--> to an
irq-read-unsafe lock L2.

The current check_usage() only checks 1) and 2), so this patch adds
checks for 3) and 4) and makes sure when find_usage_{back,for}wards find
an irq-read-{,un}safe lock, the traverse path should ends at a
dependency --(*N)-->. Note when we search backwards, --(*N)--> indicates
a real dependency --(N*)-->.

Signed-off-by: Boqun Feng 
---
 kernel/locking/lockdep.c | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 0b0ad3db78b4..bd3eef664f9d 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -1504,7 +1504,14 @@ check_redundant(struct lock_list *root, struct held_lock 
*target,
 
 static inline int usage_match(struct lock_list *entry, void *bit)
 {
-   return entry->class->usage_mask & (1 << (enum lock_usage_bit)bit);
+   enum lock_usage_bit ub = (enum lock_usage_bit)bit;
+
+
+   if (ub & 1)
+   return entry->class->usage_mask & (1 << ub) &&
+  !entry->is_rr;
+   else
+   return entry->class->usage_mask & (1 << ub);
 }
 
 
@@ -1815,6 +1822,10 @@ static int check_irq_usage(struct task_struct *curr, 
struct held_lock *prev,
   exclusive_bit(bit), state_name(bit)))
return 0;
 
+   if (!check_usage(curr, prev, next, bit,
+  exclusive_bit(bit) + 1, state_name(bit)))
+   return 0;
+
bit++; /* _READ */
 
/*
@@ -1827,6 +1838,10 @@ static int check_irq_usage(struct task_struct *curr, 
struct held_lock *prev,
   exclusive_bit(bit), state_name(bit)))
return 0;
 
+   if (!check_usage(curr, prev, next, bit,
+  exclusive_bit(bit) + 1, state_name(bit)))
+   return 0;
+
return 1;
 }
 
-- 
2.16.1



[RFC tip/locking/lockdep v5 07/17] lockdep: Adjust check_redundant() for recursive read change

2018-02-21 Thread Boqun Feng
As we have four kinds of dependencies now, check_redundant() should only
report redundant if we have a dependency path which is equal or
_stronger_ than the current dependency. For example if in
check_prev_add() we have:

prev->read == 2 && next->read != 2

, we should only report redundant if we find a path like:

prev--(RN)-->--(*N)-->next

and if we have:

prev->read == 2 && next->read == 2

, we could report redundant if we find a path like:

prev--(RN)-->--(*N)-->next

or

prev--(RN)-->--(*R)-->next

To do so, we need to pass the recursive-read status of @next into
check_redundant(). This patch changes the parameter of check_redundant()
and the match function to achieve this.

Signed-off-by: Boqun Feng 
---
 kernel/locking/lockdep.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index e1be088a34c4..0b0ad3db78b4 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -1338,9 +1338,12 @@ print_circular_bug_header(struct lock_list *entry, 
unsigned int depth,
return 0;
 }
 
-static inline int class_equal(struct lock_list *entry, void *data)
+static inline int hlock_equal(struct lock_list *entry, void *data)
 {
-   return entry->class == data;
+   struct held_lock *hlock = (struct held_lock *)data;
+
+   return hlock_class(hlock) == entry->class &&
+  (hlock->read == 2 || !entry->is_rr);
 }
 
 static inline int hlock_conflict(struct lock_list *entry, void *data)
@@ -1480,14 +1483,14 @@ check_noncircular(struct lock_list *root, struct 
held_lock *target,
 }
 
 static noinline enum bfs_result
-check_redundant(struct lock_list *root, struct lock_class *target,
+check_redundant(struct lock_list *root, struct held_lock *target,
struct lock_list **target_entry)
 {
enum bfs_result result;
 
debug_atomic_inc(nr_redundant_checks);
 
-   result = __bfs_forwards(root, target, class_equal, target_entry);
+   result = __bfs_forwards(root, target, hlock_equal, target_entry);
 
return result;
 }
@@ -2060,7 +2063,7 @@ check_prev_add(struct task_struct *curr, struct held_lock 
*prev,
 * Is the  ->  link redundant?
 */
bfs_init_root(, prev);
-   ret = check_redundant(, hlock_class(next), _entry);
+   ret = check_redundant(, next, _entry);
if (ret == BFS_RMATCH) {
debug_atomic_inc(nr_redundant);
return 2;
-- 
2.16.1



[RFC tip/locking/lockdep v5 08/17] lockdep: Fix recursive read lock related safe->unsafe detection

2018-02-21 Thread Boqun Feng
There are four cases for recursive read lock realted deadlocks:

(--(X..Y)--> means a strong dependency path starts with a --(X*)-->
dependency and ends with a --(*Y)-- dependency.)

1.  An irq-safe lock L1 has a dependency --(*..*)--> to an
irq-unsafe lock L2.

2.  An irq-read-safe lock L1 has a dependency --(N..*)--> to an
irq-unsafe lock L2.

3.  An irq-safe lock L1 has a dependency --(*..N)--> to an
irq-read-unsafe lock L2.

4.  An irq-read-safe lock L1 has a dependency --(N..N)--> to an
irq-read-unsafe lock L2.

The current check_usage() only checks 1) and 2), so this patch adds
checks for 3) and 4) and makes sure when find_usage_{back,for}wards find
an irq-read-{,un}safe lock, the traverse path should ends at a
dependency --(*N)-->. Note when we search backwards, --(*N)--> indicates
a real dependency --(N*)-->.

Signed-off-by: Boqun Feng 
---
 kernel/locking/lockdep.c | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 0b0ad3db78b4..bd3eef664f9d 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -1504,7 +1504,14 @@ check_redundant(struct lock_list *root, struct held_lock 
*target,
 
 static inline int usage_match(struct lock_list *entry, void *bit)
 {
-   return entry->class->usage_mask & (1 << (enum lock_usage_bit)bit);
+   enum lock_usage_bit ub = (enum lock_usage_bit)bit;
+
+
+   if (ub & 1)
+   return entry->class->usage_mask & (1 << ub) &&
+  !entry->is_rr;
+   else
+   return entry->class->usage_mask & (1 << ub);
 }
 
 
@@ -1815,6 +1822,10 @@ static int check_irq_usage(struct task_struct *curr, 
struct held_lock *prev,
   exclusive_bit(bit), state_name(bit)))
return 0;
 
+   if (!check_usage(curr, prev, next, bit,
+  exclusive_bit(bit) + 1, state_name(bit)))
+   return 0;
+
bit++; /* _READ */
 
/*
@@ -1827,6 +1838,10 @@ static int check_irq_usage(struct task_struct *curr, 
struct held_lock *prev,
   exclusive_bit(bit), state_name(bit)))
return 0;
 
+   if (!check_usage(curr, prev, next, bit,
+  exclusive_bit(bit) + 1, state_name(bit)))
+   return 0;
+
return 1;
 }
 
-- 
2.16.1



[RFC tip/locking/lockdep v5 07/17] lockdep: Adjust check_redundant() for recursive read change

2018-02-21 Thread Boqun Feng
As we have four kinds of dependencies now, check_redundant() should only
report redundant if we have a dependency path which is equal or
_stronger_ than the current dependency. For example if in
check_prev_add() we have:

prev->read == 2 && next->read != 2

, we should only report redundant if we find a path like:

prev--(RN)-->--(*N)-->next

and if we have:

prev->read == 2 && next->read == 2

, we could report redundant if we find a path like:

prev--(RN)-->--(*N)-->next

or

prev--(RN)-->--(*R)-->next

To do so, we need to pass the recursive-read status of @next into
check_redundant(). This patch changes the parameter of check_redundant()
and the match function to achieve this.

Signed-off-by: Boqun Feng 
---
 kernel/locking/lockdep.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index e1be088a34c4..0b0ad3db78b4 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -1338,9 +1338,12 @@ print_circular_bug_header(struct lock_list *entry, 
unsigned int depth,
return 0;
 }
 
-static inline int class_equal(struct lock_list *entry, void *data)
+static inline int hlock_equal(struct lock_list *entry, void *data)
 {
-   return entry->class == data;
+   struct held_lock *hlock = (struct held_lock *)data;
+
+   return hlock_class(hlock) == entry->class &&
+  (hlock->read == 2 || !entry->is_rr);
 }
 
 static inline int hlock_conflict(struct lock_list *entry, void *data)
@@ -1480,14 +1483,14 @@ check_noncircular(struct lock_list *root, struct 
held_lock *target,
 }
 
 static noinline enum bfs_result
-check_redundant(struct lock_list *root, struct lock_class *target,
+check_redundant(struct lock_list *root, struct held_lock *target,
struct lock_list **target_entry)
 {
enum bfs_result result;
 
debug_atomic_inc(nr_redundant_checks);
 
-   result = __bfs_forwards(root, target, class_equal, target_entry);
+   result = __bfs_forwards(root, target, hlock_equal, target_entry);
 
return result;
 }
@@ -2060,7 +2063,7 @@ check_prev_add(struct task_struct *curr, struct held_lock 
*prev,
 * Is the  ->  link redundant?
 */
bfs_init_root(, prev);
-   ret = check_redundant(, hlock_class(next), _entry);
+   ret = check_redundant(, next, _entry);
if (ret == BFS_RMATCH) {
debug_atomic_inc(nr_redundant);
return 2;
-- 
2.16.1



[RFC tip/locking/lockdep v5 17/17] MAINTAINERS: Add myself as a LOCKING PRIMITIVES reviewer

2018-02-21 Thread Boqun Feng
Recursive read lock detection work touches most core part of lockdep, so
add myself as a dedicated reviewer to help people find me if any of my
code introduces problems or misunderstandings, also if they need my help
on parsing logs related to recursive read locks.

Besides, I'd like to provide any help for lock related code.

Signed-off-by: Boqun Feng 
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9a7f76eadae9..197dc9c5162f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8239,6 +8239,7 @@ F:Documentation/admin-guide/LSM/LoadPin.rst
 LOCKING PRIMITIVES
 M: Peter Zijlstra 
 M: Ingo Molnar 
+R: Boqun Feng 
 L: linux-kernel@vger.kernel.org
 T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git 
locking/core
 S: Maintained
-- 
2.16.1



[RFC tip/locking/lockdep v5 17/17] MAINTAINERS: Add myself as a LOCKING PRIMITIVES reviewer

2018-02-21 Thread Boqun Feng
Recursive read lock detection work touches most core part of lockdep, so
add myself as a dedicated reviewer to help people find me if any of my
code introduces problems or misunderstandings, also if they need my help
on parsing logs related to recursive read locks.

Besides, I'd like to provide any help for lock related code.

Signed-off-by: Boqun Feng 
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9a7f76eadae9..197dc9c5162f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8239,6 +8239,7 @@ F:Documentation/admin-guide/LSM/LoadPin.rst
 LOCKING PRIMITIVES
 M: Peter Zijlstra 
 M: Ingo Molnar 
+R: Boqun Feng 
 L: linux-kernel@vger.kernel.org
 T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git 
locking/core
 S: Maintained
-- 
2.16.1



[RFC tip/locking/lockdep v5 13/17] lockdep/selftest: Add more recursive read related test cases

2018-02-21 Thread Boqun Feng
Add those four test cases:

1.  X --(NR)--> Y --(NR)--> Z --(NR)--> X is deadlock.

2.  X --(NN)--> Y --(RR)--> Z --(NR)--> X is deadlock.

3.  X --(NN)--> Y --(RR)--> Z --(RN)--> X is not deadlock.

4.  X --(NR)--> Y --(RR)--> Z --(NN)--> X is not deadlock.

Those self testcases are valuable for the development of supporting
recursive read related deadlock detection.

Signed-off-by: Boqun Feng 
---
 lib/locking-selftest.c | 161 +
 1 file changed, 161 insertions(+)

diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c
index c2f06b423da8..6b7a28d84fc4 100644
--- a/lib/locking-selftest.c
+++ b/lib/locking-selftest.c
@@ -1033,6 +1033,133 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_wlock)
 #undef E2
 #undef E3
 
+/*
+ * write-read / write-read / write-read deadlock even if read is recursive
+ */
+
+#define E1()   \
+   \
+   WL(X1); \
+   RL(Y1); \
+   RU(Y1); \
+   WU(X1);
+
+#define E2()   \
+   \
+   WL(Y1); \
+   RL(Z1); \
+   RU(Z1); \
+   WU(Y1);
+
+#define E3()   \
+   \
+   WL(Z1); \
+   RL(X1); \
+   RU(X1); \
+   WU(Z1);
+
+#include "locking-selftest-rlock.h"
+GENERATE_PERMUTATIONS_3_EVENTS(W1R2_W2R3_W3R1)
+
+#undef E1
+#undef E2
+#undef E3
+
+/*
+ * write-write / read-read / write-read deadlock even if read is recursive
+ */
+
+#define E1()   \
+   \
+   WL(X1); \
+   WL(Y1); \
+   WU(Y1); \
+   WU(X1);
+
+#define E2()   \
+   \
+   RL(Y1); \
+   RL(Z1); \
+   RU(Z1); \
+   RU(Y1);
+
+#define E3()   \
+   \
+   WL(Z1); \
+   RL(X1); \
+   RU(X1); \
+   WU(Z1);
+
+#include "locking-selftest-rlock.h"
+GENERATE_PERMUTATIONS_3_EVENTS(W1W2_R2R3_W3R1)
+
+#undef E1
+#undef E2
+#undef E3
+
+/*
+ * write-write / read-read / read-write is not deadlock when read is recursive
+ */
+
+#define E1()   \
+   \
+   WL(X1); \
+   WL(Y1); \
+   WU(Y1); \
+   WU(X1);
+
+#define E2()   \
+   \
+   RL(Y1); \
+   RL(Z1); \
+   RU(Z1); \
+   RU(Y1);
+
+#define E3()   \
+   \
+   RL(Z1); \
+   WL(X1); \
+   WU(X1); \
+   RU(Z1);
+
+#include "locking-selftest-rlock.h"
+GENERATE_PERMUTATIONS_3_EVENTS(W1R2_R2R3_W3W1)
+
+#undef E1
+#undef E2
+#undef E3
+
+/*
+ * write-read / read-read / write-write is not deadlock when read is recursive
+ */
+
+#define E1()   \
+   \
+   WL(X1); \
+   RL(Y1); \
+   RU(Y1); \
+   WU(X1);
+
+#define E2()   \
+   \
+   RL(Y1); \
+   RL(Z1); \
+   RU(Z1); \
+   RU(Y1);
+
+#define E3()   \
+   \
+   WL(Z1); \
+   WL(X1); \
+   WU(X1); \
+   WU(Z1);
+
+#include "locking-selftest-rlock.h"
+GENERATE_PERMUTATIONS_3_EVENTS(W1W2_R2R3_R3W1)
+
+#undef E1
+#undef E2
+#undef E3
 /*
  * read-lock / write-lock recursion that is actually safe.
  */
@@ -1258,6 +1385,19 @@ static inline void print_testname(const char *testname)
dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK);  \
pr_cont("\n");
 
+#define DO_TESTCASE_1RR(desc, name, nr)\
+   print_testname(desc"/"#nr); \
+   pr_cont(" |");  \
+   dotest(name##_##nr, SUCCESS, LOCKTYPE_RWLOCK);  \
+   pr_cont("\n");
+
+#define DO_TESTCASE_1RRB(desc, name, nr)   

[RFC tip/locking/lockdep v5 13/17] lockdep/selftest: Add more recursive read related test cases

2018-02-21 Thread Boqun Feng
Add those four test cases:

1.  X --(NR)--> Y --(NR)--> Z --(NR)--> X is deadlock.

2.  X --(NN)--> Y --(RR)--> Z --(NR)--> X is deadlock.

3.  X --(NN)--> Y --(RR)--> Z --(RN)--> X is not deadlock.

4.  X --(NR)--> Y --(RR)--> Z --(NN)--> X is not deadlock.

Those self testcases are valuable for the development of supporting
recursive read related deadlock detection.

Signed-off-by: Boqun Feng 
---
 lib/locking-selftest.c | 161 +
 1 file changed, 161 insertions(+)

diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c
index c2f06b423da8..6b7a28d84fc4 100644
--- a/lib/locking-selftest.c
+++ b/lib/locking-selftest.c
@@ -1033,6 +1033,133 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_wlock)
 #undef E2
 #undef E3
 
+/*
+ * write-read / write-read / write-read deadlock even if read is recursive
+ */
+
+#define E1()   \
+   \
+   WL(X1); \
+   RL(Y1); \
+   RU(Y1); \
+   WU(X1);
+
+#define E2()   \
+   \
+   WL(Y1); \
+   RL(Z1); \
+   RU(Z1); \
+   WU(Y1);
+
+#define E3()   \
+   \
+   WL(Z1); \
+   RL(X1); \
+   RU(X1); \
+   WU(Z1);
+
+#include "locking-selftest-rlock.h"
+GENERATE_PERMUTATIONS_3_EVENTS(W1R2_W2R3_W3R1)
+
+#undef E1
+#undef E2
+#undef E3
+
+/*
+ * write-write / read-read / write-read deadlock even if read is recursive
+ */
+
+#define E1()   \
+   \
+   WL(X1); \
+   WL(Y1); \
+   WU(Y1); \
+   WU(X1);
+
+#define E2()   \
+   \
+   RL(Y1); \
+   RL(Z1); \
+   RU(Z1); \
+   RU(Y1);
+
+#define E3()   \
+   \
+   WL(Z1); \
+   RL(X1); \
+   RU(X1); \
+   WU(Z1);
+
+#include "locking-selftest-rlock.h"
+GENERATE_PERMUTATIONS_3_EVENTS(W1W2_R2R3_W3R1)
+
+#undef E1
+#undef E2
+#undef E3
+
+/*
+ * write-write / read-read / read-write is not deadlock when read is recursive
+ */
+
+#define E1()   \
+   \
+   WL(X1); \
+   WL(Y1); \
+   WU(Y1); \
+   WU(X1);
+
+#define E2()   \
+   \
+   RL(Y1); \
+   RL(Z1); \
+   RU(Z1); \
+   RU(Y1);
+
+#define E3()   \
+   \
+   RL(Z1); \
+   WL(X1); \
+   WU(X1); \
+   RU(Z1);
+
+#include "locking-selftest-rlock.h"
+GENERATE_PERMUTATIONS_3_EVENTS(W1R2_R2R3_W3W1)
+
+#undef E1
+#undef E2
+#undef E3
+
+/*
+ * write-read / read-read / write-write is not deadlock when read is recursive
+ */
+
+#define E1()   \
+   \
+   WL(X1); \
+   RL(Y1); \
+   RU(Y1); \
+   WU(X1);
+
+#define E2()   \
+   \
+   RL(Y1); \
+   RL(Z1); \
+   RU(Z1); \
+   RU(Y1);
+
+#define E3()   \
+   \
+   WL(Z1); \
+   WL(X1); \
+   WU(X1); \
+   WU(Z1);
+
+#include "locking-selftest-rlock.h"
+GENERATE_PERMUTATIONS_3_EVENTS(W1W2_R2R3_R3W1)
+
+#undef E1
+#undef E2
+#undef E3
 /*
  * read-lock / write-lock recursion that is actually safe.
  */
@@ -1258,6 +1385,19 @@ static inline void print_testname(const char *testname)
dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK);  \
pr_cont("\n");
 
+#define DO_TESTCASE_1RR(desc, name, nr)\
+   print_testname(desc"/"#nr); \
+   pr_cont(" |");  \
+   dotest(name##_##nr, SUCCESS, LOCKTYPE_RWLOCK);  \
+   pr_cont("\n");
+
+#define DO_TESTCASE_1RRB(desc, name, nr)   \
+   

[RFC tip/locking/lockdep v5 16/17] lockdep: Documention for recursive read lock detection reasoning

2018-02-21 Thread Boqun Feng
As now we support recursive read lock deadlock detection, add related
explanation in the Documentation/lockdep/lockdep-desgin.txt:

*   Definition of recursive read locks, non-recursive locks, strong
dependency path and notions of -(**)->.

*   Lockdep's assumption.

*   Informal proof of recursive read lock deadlock detection.

Signed-off-by: Boqun Feng 
Cc: Randy Dunlap 
---
 Documentation/locking/lockdep-design.txt | 170 +++
 1 file changed, 170 insertions(+)

diff --git a/Documentation/locking/lockdep-design.txt 
b/Documentation/locking/lockdep-design.txt
index 382bc25589c2..fd8a8d97ce58 100644
--- a/Documentation/locking/lockdep-design.txt
+++ b/Documentation/locking/lockdep-design.txt
@@ -284,3 +284,173 @@ Run the command and save the output, then compare against 
the output from
 a later run of this command to identify the leakers.  This same output
 can also help you find situations where runtime lock initialization has
 been omitted.
+
+Recursive Read Deadlock Detection:
+--
+Lockdep now is equipped with deadlock detection for recursive read locks.
+
+Recursive read locks, as their name indicates, are the locks able to be
+acquired recursively. Unlike non-recursive read locks, recursive read locks
+only get blocked by current write lock *holders* other than write lock
+*waiters*, for example:
+
+   TASK A: TASK B:
+
+   read_lock(X);
+
+   write_lock(X);
+
+   read_lock(X);
+
+is not a deadlock for recursive read locks, as while the task B is waiting for
+the lock X, the second read_lock() doesn't need to wait because it's a 
recursive
+read lock.
+
+Note that a lock can be a write lock(exclusive lock), a non-recursive read lock
+(non-recursive shared lock) or a recursive read lock(recursive shared lock),
+depending on the API used to acquire it(more specifically, the value of the
+'read' parameter for lock_acquire(...)). In other words, a single lock instance
+has three types of acquisition depending on the acquisition functions:
+exclusive, non-recursive read, and recursive read.
+
+That said, recursive read locks could introduce deadlocks too, considering the
+following:
+
+   TASK A: TASK B:
+
+   read_lock(X);
+   read_lock(Y);
+   write_lock(Y);
+   write_lock(X);
+
+, neither task could get the write locks because the corresponding read locks
+are held by each other.
+
+Lockdep could detect recursive read lock related deadlocks. The 
dependencies(edges)
+in the lockdep graph are classified into four categories:
+
+1) -(NN)->: non-recursive to non-recursive dependency, non-recursive locks 
include
+non-recursive read locks, write locks and exclusive locks(e.g. 
spinlock_t).
+   They are treated equally in deadlock detection. "X -(NN)-> Y" means
+X -> Y and both X and Y are non-recursive locks.
+
+2) -(RN)->: recursive to non-recursive dependency, recursive locks means 
recursive read
+   locks. "X -(RN)-> Y" means X -> Y and X is recursive read lock and
+Y is non-recursive lock.
+
+3) -(NR)->: non-recursive to recursive dependency, "X -(NR)-> Y" means X -> Y 
and X is
+non-recursive lock and Y is recursive lock.
+
+4) -(RR)->: recursive to recursive dependency, "X -(RR)-> Y" means X -> Y and 
both X
+and Y are recursive locks.
+
+Note that given two locks, they may have multiple dependencies between them, 
for example:
+
+   TASK A:
+
+   read_lock(X);
+   write_lock(Y);
+   ...
+
+   TASK B:
+
+   write_lock(X);
+   write_lock(Y);
+
+, we have both X -(RN)-> Y and X -(NN)-> Y in the dependency graph.
+
+And obviously a non-recursive lock can block the corresponding recursive lock,
+and vice versa. Besides a non-recursive lock may block the other non-recursive
+lock of the same instance(e.g. a write lock may block a corresponding
+non-recursive read lock and vice versa).
+
+We use -(*N)-> for edges that is either -(RN)-> or -(NN)->, the similar for 
-(N*)->,
+-(*R)-> and -(R*)->
+
+A "path" is a series of conjunct dependency edges in the graph. And we define a
+"strong" path, which indicates the strong dependency throughout each dependency
+in the path, as the path that doesn't have two conjunct edges(dependencies) as
+-(*R)-> and -(R*)->. IOW, a "strong" path is a path from a lock walking to 
another
+through the lock dependencies, and if X -> Y -> Z in the path(where X, Y, Z are
+locks), if the walk from X to Y is through a -(NR)-> or -(RR)-> dependency, the
+walk from Y to Z must not be through a -(RN)-> or -(RR)-> dependency, otherwise
+it's not a strong path.
+
+We now prove that if a strong path forms a circle, then we have a potential 
deadlock.
+By "forms a circle", it means for a set of locks A0,A1...An, there is a path 

[RFC tip/locking/lockdep v5 16/17] lockdep: Documention for recursive read lock detection reasoning

2018-02-21 Thread Boqun Feng
As now we support recursive read lock deadlock detection, add related
explanation in the Documentation/lockdep/lockdep-desgin.txt:

*   Definition of recursive read locks, non-recursive locks, strong
dependency path and notions of -(**)->.

*   Lockdep's assumption.

*   Informal proof of recursive read lock deadlock detection.

Signed-off-by: Boqun Feng 
Cc: Randy Dunlap 
---
 Documentation/locking/lockdep-design.txt | 170 +++
 1 file changed, 170 insertions(+)

diff --git a/Documentation/locking/lockdep-design.txt 
b/Documentation/locking/lockdep-design.txt
index 382bc25589c2..fd8a8d97ce58 100644
--- a/Documentation/locking/lockdep-design.txt
+++ b/Documentation/locking/lockdep-design.txt
@@ -284,3 +284,173 @@ Run the command and save the output, then compare against 
the output from
 a later run of this command to identify the leakers.  This same output
 can also help you find situations where runtime lock initialization has
 been omitted.
+
+Recursive Read Deadlock Detection:
+--
+Lockdep now is equipped with deadlock detection for recursive read locks.
+
+Recursive read locks, as their name indicates, are the locks able to be
+acquired recursively. Unlike non-recursive read locks, recursive read locks
+only get blocked by current write lock *holders* other than write lock
+*waiters*, for example:
+
+   TASK A: TASK B:
+
+   read_lock(X);
+
+   write_lock(X);
+
+   read_lock(X);
+
+is not a deadlock for recursive read locks, as while the task B is waiting for
+the lock X, the second read_lock() doesn't need to wait because it's a 
recursive
+read lock.
+
+Note that a lock can be a write lock(exclusive lock), a non-recursive read lock
+(non-recursive shared lock) or a recursive read lock(recursive shared lock),
+depending on the API used to acquire it(more specifically, the value of the
+'read' parameter for lock_acquire(...)). In other words, a single lock instance
+has three types of acquisition depending on the acquisition functions:
+exclusive, non-recursive read, and recursive read.
+
+That said, recursive read locks could introduce deadlocks too, considering the
+following:
+
+   TASK A: TASK B:
+
+   read_lock(X);
+   read_lock(Y);
+   write_lock(Y);
+   write_lock(X);
+
+, neither task could get the write locks because the corresponding read locks
+are held by each other.
+
+Lockdep could detect recursive read lock related deadlocks. The 
dependencies(edges)
+in the lockdep graph are classified into four categories:
+
+1) -(NN)->: non-recursive to non-recursive dependency, non-recursive locks 
include
+non-recursive read locks, write locks and exclusive locks(e.g. 
spinlock_t).
+   They are treated equally in deadlock detection. "X -(NN)-> Y" means
+X -> Y and both X and Y are non-recursive locks.
+
+2) -(RN)->: recursive to non-recursive dependency, recursive locks means 
recursive read
+   locks. "X -(RN)-> Y" means X -> Y and X is recursive read lock and
+Y is non-recursive lock.
+
+3) -(NR)->: non-recursive to recursive dependency, "X -(NR)-> Y" means X -> Y 
and X is
+non-recursive lock and Y is recursive lock.
+
+4) -(RR)->: recursive to recursive dependency, "X -(RR)-> Y" means X -> Y and 
both X
+and Y are recursive locks.
+
+Note that given two locks, they may have multiple dependencies between them, 
for example:
+
+   TASK A:
+
+   read_lock(X);
+   write_lock(Y);
+   ...
+
+   TASK B:
+
+   write_lock(X);
+   write_lock(Y);
+
+, we have both X -(RN)-> Y and X -(NN)-> Y in the dependency graph.
+
+And obviously a non-recursive lock can block the corresponding recursive lock,
+and vice versa. Besides a non-recursive lock may block the other non-recursive
+lock of the same instance(e.g. a write lock may block a corresponding
+non-recursive read lock and vice versa).
+
+We use -(*N)-> for edges that is either -(RN)-> or -(NN)->, the similar for 
-(N*)->,
+-(*R)-> and -(R*)->
+
+A "path" is a series of conjunct dependency edges in the graph. And we define a
+"strong" path, which indicates the strong dependency throughout each dependency
+in the path, as the path that doesn't have two conjunct edges(dependencies) as
+-(*R)-> and -(R*)->. IOW, a "strong" path is a path from a lock walking to 
another
+through the lock dependencies, and if X -> Y -> Z in the path(where X, Y, Z are
+locks), if the walk from X to Y is through a -(NR)-> or -(RR)-> dependency, the
+walk from Y to Z must not be through a -(RN)-> or -(RR)-> dependency, otherwise
+it's not a strong path.
+
+We now prove that if a strong path forms a circle, then we have a potential 
deadlock.
+By "forms a circle", it means for a set of locks A0,A1...An, there is a path 
from
+A0 to An:
+
+   A0 -> A1 -> ... 

[RFC tip/locking/lockdep v5 06/17] lockdep: Support deadlock detection for recursive read in check_noncircular()

2018-02-21 Thread Boqun Feng
Currently, lockdep only has limit support for deadlock detection for
recursive read locks.

The basic idea of the detection is:

Since we make __bfs() able to traverse only the strong dependency paths,
so we report a circular deadlock if we could find a circle of a strong
dependency path.

Signed-off-by: Boqun Feng 
---
 kernel/locking/lockdep.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 07bcfaac6fe2..e1be088a34c4 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -1343,6 +1343,14 @@ static inline int class_equal(struct lock_list *entry, 
void *data)
return entry->class == data;
 }
 
+static inline int hlock_conflict(struct lock_list *entry, void *data)
+{
+   struct held_lock *hlock = (struct held_lock *)data;
+
+   return hlock_class(hlock) == entry->class &&
+  (hlock->read != 2 || !entry->is_rr);
+}
+
 static noinline int print_circular_bug(struct lock_list *this,
struct lock_list *target,
struct held_lock *check_src,
@@ -1455,18 +1463,18 @@ unsigned long lockdep_count_backward_deps(struct 
lock_class *class)
 }
 
 /*
- * Prove that the dependency graph starting at  can not
+ * Prove that the dependency graph starting at  can not
  * lead to . Print an error and return BFS_RMATCH if it does.
  */
 static noinline enum bfs_result
-check_noncircular(struct lock_list *root, struct lock_class *target,
+check_noncircular(struct lock_list *root, struct held_lock *target,
  struct lock_list **target_entry)
 {
enum bfs_result result;
 
debug_atomic_inc(nr_cyclic_checks);
 
-   result = __bfs_forwards(root, target, class_equal, target_entry);
+   result = __bfs_forwards(root, target, hlock_conflict, target_entry);
 
return result;
 }
@@ -1994,7 +2002,7 @@ check_prev_add(struct task_struct *curr, struct held_lock 
*prev,
 * keep the stackframe size of the recursive functions low:
 */
bfs_init_root(, next);
-   ret = check_noncircular(, hlock_class(prev), _entry);
+   ret = check_noncircular(, prev, _entry);
if (unlikely(ret == BFS_RMATCH)) {
if (!trace->entries) {
/*
-- 
2.16.1



[PATCH 4.14, 4.9] crypto: talitos - fix Kernel Oops on hashing an empty file

2018-02-21 Thread Christophe Leroy
Upstream 87a81dce53b1ea61acaeefa5191a0376a2d1d721

Performing the hash of an empty file leads to a kernel Oops

[   44.504600] Unable to handle kernel paging request for data at address 
0x000c
[   44.512819] Faulting instruction address: 0xc02d2be8
[   44.524088] Oops: Kernel access of bad area, sig: 11 [#1]
[   44.529171] BE PREEMPT CMPC885
[   44.532232] CPU: 0 PID: 491 Comm: md5sum Not tainted 
4.15.0-rc8-00211-g3a968610b6ea #81
[   44.540814] NIP:  c02d2be8 LR: c02d2984 CTR: 
[   44.545812] REGS: c6813c90 TRAP: 0300   Not tainted  
(4.15.0-rc8-00211-g3a968610b6ea)
[   44.554223] MSR:  9032   CR: 48222822  XER: 2000
[   44.560855] DAR: 000c DSISR: c000
[   44.560855] GPR00: c02d28fc c6813d40 c6828000 c646fa40 0001 0001 
0001 
[   44.560855] GPR08: 004c  c000bfcc  28222822 100280d4 
 10020008
[   44.560855] GPR16:  0020   10024008  
c646f9f0 c6179a10
[   44.560855] GPR24:  0001 c62f0018 c6179a10  c6367a30 
c62f c646f9c0
[   44.598542] NIP [c02d2be8] ahash_process_req+0x448/0x700
[   44.603751] LR [c02d2984] ahash_process_req+0x1e4/0x700
[   44.608868] Call Trace:
[   44.611329] [c6813d40] [c02d28fc] ahash_process_req+0x15c/0x700 (unreliable)
[   44.618302] [c6813d90] [c02060c4] hash_recvmsg+0x11c/0x210
[   44.623716] [c6813db0] [c0331354] ___sys_recvmsg+0x98/0x138
[   44.629226] [c6813eb0] [c03332c0] __sys_recvmsg+0x40/0x84
[   44.634562] [c6813f10] [c03336c0] SyS_socketcall+0xb8/0x1d4
[   44.640073] [c6813f40] [c000d1ac] ret_from_syscall+0x0/0x38
[   44.645530] Instruction dump:
[   44.648465] 38c1 7f63db78 4e800421 7c791b78 54690ffe 0f09 80ff0190 
2f87
[   44.656122] 40befe50 2f990001 409e0210 813f01bc <8129000c> b39e003a 7d29c214 
913e003c

This patch fixes that Oops by checking if src is NULL.

Fixes: 6a1e8d14156d4 ("crypto: talitos - making mapping helpers more generic")
Cc: 
Signed-off-by: Christophe Leroy 
---
 drivers/crypto/talitos.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index dff88838dce7..42913116620a 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1124,6 +1124,11 @@ int talitos_sg_map(struct device *dev, struct 
scatterlist *src,
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
 
+   if (!src) {
+   *ptr = zero_entry;
+   return 1;
+   }
+
to_talitos_ptr_len(ptr, len, is_sec1);
to_talitos_ptr_ext_set(ptr, 0, is_sec1);
 
-- 
2.13.3



[RFC tip/locking/lockdep v5 06/17] lockdep: Support deadlock detection for recursive read in check_noncircular()

2018-02-21 Thread Boqun Feng
Currently, lockdep only has limit support for deadlock detection for
recursive read locks.

The basic idea of the detection is:

Since we make __bfs() able to traverse only the strong dependency paths,
so we report a circular deadlock if we could find a circle of a strong
dependency path.

Signed-off-by: Boqun Feng 
---
 kernel/locking/lockdep.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 07bcfaac6fe2..e1be088a34c4 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -1343,6 +1343,14 @@ static inline int class_equal(struct lock_list *entry, 
void *data)
return entry->class == data;
 }
 
+static inline int hlock_conflict(struct lock_list *entry, void *data)
+{
+   struct held_lock *hlock = (struct held_lock *)data;
+
+   return hlock_class(hlock) == entry->class &&
+  (hlock->read != 2 || !entry->is_rr);
+}
+
 static noinline int print_circular_bug(struct lock_list *this,
struct lock_list *target,
struct held_lock *check_src,
@@ -1455,18 +1463,18 @@ unsigned long lockdep_count_backward_deps(struct 
lock_class *class)
 }
 
 /*
- * Prove that the dependency graph starting at  can not
+ * Prove that the dependency graph starting at  can not
  * lead to . Print an error and return BFS_RMATCH if it does.
  */
 static noinline enum bfs_result
-check_noncircular(struct lock_list *root, struct lock_class *target,
+check_noncircular(struct lock_list *root, struct held_lock *target,
  struct lock_list **target_entry)
 {
enum bfs_result result;
 
debug_atomic_inc(nr_cyclic_checks);
 
-   result = __bfs_forwards(root, target, class_equal, target_entry);
+   result = __bfs_forwards(root, target, hlock_conflict, target_entry);
 
return result;
 }
@@ -1994,7 +2002,7 @@ check_prev_add(struct task_struct *curr, struct held_lock 
*prev,
 * keep the stackframe size of the recursive functions low:
 */
bfs_init_root(, next);
-   ret = check_noncircular(, hlock_class(prev), _entry);
+   ret = check_noncircular(, prev, _entry);
if (unlikely(ret == BFS_RMATCH)) {
if (!trace->entries) {
/*
-- 
2.16.1



[PATCH 4.14, 4.9] crypto: talitos - fix Kernel Oops on hashing an empty file

2018-02-21 Thread Christophe Leroy
Upstream 87a81dce53b1ea61acaeefa5191a0376a2d1d721

Performing the hash of an empty file leads to a kernel Oops

[   44.504600] Unable to handle kernel paging request for data at address 
0x000c
[   44.512819] Faulting instruction address: 0xc02d2be8
[   44.524088] Oops: Kernel access of bad area, sig: 11 [#1]
[   44.529171] BE PREEMPT CMPC885
[   44.532232] CPU: 0 PID: 491 Comm: md5sum Not tainted 
4.15.0-rc8-00211-g3a968610b6ea #81
[   44.540814] NIP:  c02d2be8 LR: c02d2984 CTR: 
[   44.545812] REGS: c6813c90 TRAP: 0300   Not tainted  
(4.15.0-rc8-00211-g3a968610b6ea)
[   44.554223] MSR:  9032   CR: 48222822  XER: 2000
[   44.560855] DAR: 000c DSISR: c000
[   44.560855] GPR00: c02d28fc c6813d40 c6828000 c646fa40 0001 0001 
0001 
[   44.560855] GPR08: 004c  c000bfcc  28222822 100280d4 
 10020008
[   44.560855] GPR16:  0020   10024008  
c646f9f0 c6179a10
[   44.560855] GPR24:  0001 c62f0018 c6179a10  c6367a30 
c62f c646f9c0
[   44.598542] NIP [c02d2be8] ahash_process_req+0x448/0x700
[   44.603751] LR [c02d2984] ahash_process_req+0x1e4/0x700
[   44.608868] Call Trace:
[   44.611329] [c6813d40] [c02d28fc] ahash_process_req+0x15c/0x700 (unreliable)
[   44.618302] [c6813d90] [c02060c4] hash_recvmsg+0x11c/0x210
[   44.623716] [c6813db0] [c0331354] ___sys_recvmsg+0x98/0x138
[   44.629226] [c6813eb0] [c03332c0] __sys_recvmsg+0x40/0x84
[   44.634562] [c6813f10] [c03336c0] SyS_socketcall+0xb8/0x1d4
[   44.640073] [c6813f40] [c000d1ac] ret_from_syscall+0x0/0x38
[   44.645530] Instruction dump:
[   44.648465] 38c1 7f63db78 4e800421 7c791b78 54690ffe 0f09 80ff0190 
2f87
[   44.656122] 40befe50 2f990001 409e0210 813f01bc <8129000c> b39e003a 7d29c214 
913e003c

This patch fixes that Oops by checking if src is NULL.

Fixes: 6a1e8d14156d4 ("crypto: talitos - making mapping helpers more generic")
Cc: 
Signed-off-by: Christophe Leroy 
---
 drivers/crypto/talitos.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index dff88838dce7..42913116620a 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1124,6 +1124,11 @@ int talitos_sg_map(struct device *dev, struct 
scatterlist *src,
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
 
+   if (!src) {
+   *ptr = zero_entry;
+   return 1;
+   }
+
to_talitos_ptr_len(ptr, len, is_sec1);
to_talitos_ptr_ext_set(ptr, 0, is_sec1);
 
-- 
2.13.3



[RFC tip/locking/lockdep v5 15/17] lockdep: Reduce the size of lock_list

2018-02-21 Thread Boqun Feng
We actually only need 4 bits for lock_list::dep and 1 bit for
lock_list::is_rr, besides lock_list::distance should always be no
greater than MAX_LOCKDEP_DEPTH(which is 48 right now), so a u16 will
fit, this patch then reduces the sizes of those fields to save space for
lock_list structure, as a result we can reduce the size increment
introduced by recursive read lock detection and keep the lock_list the
same size as before.

Suggested-by: Peter Zijlstra 
Signed-off-by: Boqun Feng 
---
 include/linux/lockdep.h  |  6 +++---
 kernel/locking/lockdep.c | 11 ++-
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index a1f91f8680bd..3fce8dbf5091 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -186,11 +186,11 @@ struct lock_list {
struct list_headentry;
struct lock_class   *class;
struct stack_trace  trace;
-   int distance;
+   u16 distance;
/* bitmap of different dependencies from head to this */
-   u16 dep;
+   u8  dep;
/* used by BFS to record whether this is picked as a recursive read */
-   u16 is_rr;
+   boolis_rr;
 
/*
 * The parent field is used to implement breadth-first search, and the
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 1b981dc4c061..e8b83b36669c 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -874,7 +874,7 @@ static struct lock_list *alloc_list_entry(void)
  * Add a new dependency to the head of the list:
  */
 static int add_lock_to_list(struct lock_class *this, struct list_head *head,
-   unsigned long ip, int distance, unsigned int dep,
+   unsigned long ip, u16 distance, unsigned int dep,
struct stack_trace *trace)
 {
struct lock_list *entry;
@@ -1063,7 +1063,7 @@ static inline unsigned int calc_dep(int prev, int next)
  * N: non-recursive lock
  * R: recursive read lock
  */
-static inline int pick_dep(u16 is_rr, u16 cap_dep)
+static inline int pick_dep(bool is_rr, u8 cap_dep)
 {
if (is_rr) { /* could only pick -(N*)-> */
if (cap_dep & DEP_NN_MASK)
@@ -1148,7 +1148,8 @@ static enum bfs_result __bfs(struct lock_list 
*source_entry,
struct list_head *head;
struct circular_queue *cq = _cq;
enum bfs_result ret = BFS_RNOMATCH;
-   int is_rr, next_is_rr;
+   bool is_rr;
+   int next_is_rr;
 
if (match(source_entry, data)) {
*target_entry = source_entry;
@@ -1204,7 +1205,7 @@ static enum bfs_result __bfs(struct lock_list 
*source_entry,
next_is_rr = pick_dep(is_rr, entry->dep);
if (next_is_rr < 0)
continue;
-   entry->is_rr = next_is_rr;
+   entry->is_rr = !!next_is_rr;
 
visit_lock_entry(entry, lock);
if (match(entry, data)) {
@@ -2153,7 +2154,7 @@ check_prevs_add(struct task_struct *curr, struct 
held_lock *next)
goto out_bug;
 
for (;;) {
-   int distance = curr->lockdep_depth - depth + 1;
+   u16 distance = curr->lockdep_depth - depth + 1;
hlock = curr->held_locks + depth - 1;
 
if (hlock->check) {
-- 
2.16.1



[RFC tip/locking/lockdep v5 01/17] lockdep: Demagic the return value of BFS

2018-02-21 Thread Boqun Feng
__bfs() could return four magic numbers:

1: search succeeds, but none match.
0: search succeeds, find one match.
-1: search fails because of the cq is full.
-2: search fails because a invalid node is found.

This patch cleans things up by using a enum type for the return value
of __bfs() and its friends, this improves the code readability of the
code, and further, could help if we want to extend the BFS.

Signed-off-by: Boqun Feng 
---
 kernel/locking/lockdep.c | 136 ---
 1 file changed, 80 insertions(+), 56 deletions(-)

diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 89b5f83f1969..9b2e318bcc81 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -984,21 +984,52 @@ static inline int get_lock_depth(struct lock_list *child)
}
return depth;
 }
+/*
+ * Return values of a bfs search:
+ *
+ * BFS_E* indicates an error
+ * BFS_R* indicates a result(match or not)
+ *
+ * BFS_EINVALIDNODE: Find a invalid node in the graph.
+ *
+ * BFS_EQUEUEFULL: The queue is full while doing the bfs.
+ *
+ * BFS_RMATCH: Find the matched node in the graph, and put that node * into
+ **@target_entry.
+ *
+ * BFS_RNOMATCH: Haven't found the matched node and keep *@target_entry
+ *  _unchanged_.
+ */
+enum bfs_result {
+   BFS_EINVALIDNODE = -2,
+   BFS_EQUEUEFULL = -1,
+   BFS_RMATCH = 0,
+   BFS_RNOMATCH = 1,
+};
 
-static int __bfs(struct lock_list *source_entry,
-void *data,
-int (*match)(struct lock_list *entry, void *data),
-struct lock_list **target_entry,
-int forward)
+/*
+ * bfs_result < 0 means error
+ */
+
+static inline bool bfs_error(enum bfs_result res)
+{
+   return res < 0;
+}
+
+static enum bfs_result __bfs(struct lock_list *source_entry,
+void *data,
+int (*match)(struct lock_list *entry, void *data),
+struct lock_list **target_entry,
+int forward)
 {
struct lock_list *entry;
struct list_head *head;
struct circular_queue *cq = _cq;
-   int ret = 1;
+   enum bfs_result ret = BFS_RNOMATCH;
 
if (match(source_entry, data)) {
*target_entry = source_entry;
-   ret = 0;
+   ret = BFS_RMATCH;
goto exit;
}
 
@@ -1019,7 +1050,7 @@ static int __bfs(struct lock_list *source_entry,
__cq_dequeue(cq, (unsigned long *));
 
if (!lock->class) {
-   ret = -2;
+   ret = BFS_EINVALIDNODE;
goto exit;
}
 
@@ -1036,12 +1067,12 @@ static int __bfs(struct lock_list *source_entry,
mark_lock_accessed(entry, lock);
if (match(entry, data)) {
*target_entry = entry;
-   ret = 0;
+   ret = BFS_RMATCH;
goto exit;
}
 
if (__cq_enqueue(cq, (unsigned long)entry)) {
-   ret = -1;
+   ret = BFS_EQUEUEFULL;
goto exit;
}
cq_depth = __cq_get_elem_count(cq);
@@ -1054,19 +1085,21 @@ static int __bfs(struct lock_list *source_entry,
return ret;
 }
 
-static inline int __bfs_forwards(struct lock_list *src_entry,
-   void *data,
-   int (*match)(struct lock_list *entry, void *data),
-   struct lock_list **target_entry)
+static inline enum bfs_result
+__bfs_forwards(struct lock_list *src_entry,
+  void *data,
+  int (*match)(struct lock_list *entry, void *data),
+  struct lock_list **target_entry)
 {
return __bfs(src_entry, data, match, target_entry, 1);
 
 }
 
-static inline int __bfs_backwards(struct lock_list *src_entry,
-   void *data,
-   int (*match)(struct lock_list *entry, void *data),
-   struct lock_list **target_entry)
+static inline enum bfs_result
+__bfs_backwards(struct lock_list *src_entry,
+   void *data,
+   int (*match)(struct lock_list *entry, void *data),
+   struct lock_list **target_entry)
 {
return __bfs(src_entry, data, match, target_entry, 0);
 
@@ -1299,13 +1332,13 @@ unsigned long lockdep_count_backward_deps(struct 
lock_class *class)
 
 /*
  * Prove that the dependency graph starting at  can not
- * lead to . Print an error and return 0 if it does.
+ * lead to . Print an error and return 

[RFC tip/locking/lockdep v5 15/17] lockdep: Reduce the size of lock_list

2018-02-21 Thread Boqun Feng
We actually only need 4 bits for lock_list::dep and 1 bit for
lock_list::is_rr, besides lock_list::distance should always be no
greater than MAX_LOCKDEP_DEPTH(which is 48 right now), so a u16 will
fit, this patch then reduces the sizes of those fields to save space for
lock_list structure, as a result we can reduce the size increment
introduced by recursive read lock detection and keep the lock_list the
same size as before.

Suggested-by: Peter Zijlstra 
Signed-off-by: Boqun Feng 
---
 include/linux/lockdep.h  |  6 +++---
 kernel/locking/lockdep.c | 11 ++-
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index a1f91f8680bd..3fce8dbf5091 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -186,11 +186,11 @@ struct lock_list {
struct list_headentry;
struct lock_class   *class;
struct stack_trace  trace;
-   int distance;
+   u16 distance;
/* bitmap of different dependencies from head to this */
-   u16 dep;
+   u8  dep;
/* used by BFS to record whether this is picked as a recursive read */
-   u16 is_rr;
+   boolis_rr;
 
/*
 * The parent field is used to implement breadth-first search, and the
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 1b981dc4c061..e8b83b36669c 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -874,7 +874,7 @@ static struct lock_list *alloc_list_entry(void)
  * Add a new dependency to the head of the list:
  */
 static int add_lock_to_list(struct lock_class *this, struct list_head *head,
-   unsigned long ip, int distance, unsigned int dep,
+   unsigned long ip, u16 distance, unsigned int dep,
struct stack_trace *trace)
 {
struct lock_list *entry;
@@ -1063,7 +1063,7 @@ static inline unsigned int calc_dep(int prev, int next)
  * N: non-recursive lock
  * R: recursive read lock
  */
-static inline int pick_dep(u16 is_rr, u16 cap_dep)
+static inline int pick_dep(bool is_rr, u8 cap_dep)
 {
if (is_rr) { /* could only pick -(N*)-> */
if (cap_dep & DEP_NN_MASK)
@@ -1148,7 +1148,8 @@ static enum bfs_result __bfs(struct lock_list 
*source_entry,
struct list_head *head;
struct circular_queue *cq = _cq;
enum bfs_result ret = BFS_RNOMATCH;
-   int is_rr, next_is_rr;
+   bool is_rr;
+   int next_is_rr;
 
if (match(source_entry, data)) {
*target_entry = source_entry;
@@ -1204,7 +1205,7 @@ static enum bfs_result __bfs(struct lock_list 
*source_entry,
next_is_rr = pick_dep(is_rr, entry->dep);
if (next_is_rr < 0)
continue;
-   entry->is_rr = next_is_rr;
+   entry->is_rr = !!next_is_rr;
 
visit_lock_entry(entry, lock);
if (match(entry, data)) {
@@ -2153,7 +2154,7 @@ check_prevs_add(struct task_struct *curr, struct 
held_lock *next)
goto out_bug;
 
for (;;) {
-   int distance = curr->lockdep_depth - depth + 1;
+   u16 distance = curr->lockdep_depth - depth + 1;
hlock = curr->held_locks + depth - 1;
 
if (hlock->check) {
-- 
2.16.1



[RFC tip/locking/lockdep v5 01/17] lockdep: Demagic the return value of BFS

2018-02-21 Thread Boqun Feng
__bfs() could return four magic numbers:

1: search succeeds, but none match.
0: search succeeds, find one match.
-1: search fails because of the cq is full.
-2: search fails because a invalid node is found.

This patch cleans things up by using a enum type for the return value
of __bfs() and its friends, this improves the code readability of the
code, and further, could help if we want to extend the BFS.

Signed-off-by: Boqun Feng 
---
 kernel/locking/lockdep.c | 136 ---
 1 file changed, 80 insertions(+), 56 deletions(-)

diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 89b5f83f1969..9b2e318bcc81 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -984,21 +984,52 @@ static inline int get_lock_depth(struct lock_list *child)
}
return depth;
 }
+/*
+ * Return values of a bfs search:
+ *
+ * BFS_E* indicates an error
+ * BFS_R* indicates a result(match or not)
+ *
+ * BFS_EINVALIDNODE: Find a invalid node in the graph.
+ *
+ * BFS_EQUEUEFULL: The queue is full while doing the bfs.
+ *
+ * BFS_RMATCH: Find the matched node in the graph, and put that node * into
+ **@target_entry.
+ *
+ * BFS_RNOMATCH: Haven't found the matched node and keep *@target_entry
+ *  _unchanged_.
+ */
+enum bfs_result {
+   BFS_EINVALIDNODE = -2,
+   BFS_EQUEUEFULL = -1,
+   BFS_RMATCH = 0,
+   BFS_RNOMATCH = 1,
+};
 
-static int __bfs(struct lock_list *source_entry,
-void *data,
-int (*match)(struct lock_list *entry, void *data),
-struct lock_list **target_entry,
-int forward)
+/*
+ * bfs_result < 0 means error
+ */
+
+static inline bool bfs_error(enum bfs_result res)
+{
+   return res < 0;
+}
+
+static enum bfs_result __bfs(struct lock_list *source_entry,
+void *data,
+int (*match)(struct lock_list *entry, void *data),
+struct lock_list **target_entry,
+int forward)
 {
struct lock_list *entry;
struct list_head *head;
struct circular_queue *cq = _cq;
-   int ret = 1;
+   enum bfs_result ret = BFS_RNOMATCH;
 
if (match(source_entry, data)) {
*target_entry = source_entry;
-   ret = 0;
+   ret = BFS_RMATCH;
goto exit;
}
 
@@ -1019,7 +1050,7 @@ static int __bfs(struct lock_list *source_entry,
__cq_dequeue(cq, (unsigned long *));
 
if (!lock->class) {
-   ret = -2;
+   ret = BFS_EINVALIDNODE;
goto exit;
}
 
@@ -1036,12 +1067,12 @@ static int __bfs(struct lock_list *source_entry,
mark_lock_accessed(entry, lock);
if (match(entry, data)) {
*target_entry = entry;
-   ret = 0;
+   ret = BFS_RMATCH;
goto exit;
}
 
if (__cq_enqueue(cq, (unsigned long)entry)) {
-   ret = -1;
+   ret = BFS_EQUEUEFULL;
goto exit;
}
cq_depth = __cq_get_elem_count(cq);
@@ -1054,19 +1085,21 @@ static int __bfs(struct lock_list *source_entry,
return ret;
 }
 
-static inline int __bfs_forwards(struct lock_list *src_entry,
-   void *data,
-   int (*match)(struct lock_list *entry, void *data),
-   struct lock_list **target_entry)
+static inline enum bfs_result
+__bfs_forwards(struct lock_list *src_entry,
+  void *data,
+  int (*match)(struct lock_list *entry, void *data),
+  struct lock_list **target_entry)
 {
return __bfs(src_entry, data, match, target_entry, 1);
 
 }
 
-static inline int __bfs_backwards(struct lock_list *src_entry,
-   void *data,
-   int (*match)(struct lock_list *entry, void *data),
-   struct lock_list **target_entry)
+static inline enum bfs_result
+__bfs_backwards(struct lock_list *src_entry,
+   void *data,
+   int (*match)(struct lock_list *entry, void *data),
+   struct lock_list **target_entry)
 {
return __bfs(src_entry, data, match, target_entry, 0);
 
@@ -1299,13 +1332,13 @@ unsigned long lockdep_count_backward_deps(struct 
lock_class *class)
 
 /*
  * Prove that the dependency graph starting at  can not
- * lead to . Print an error and return 0 if it does.
+ * lead to . Print an error and return BFS_RMATCH if it does.
  */

  1   2   3   4   5   6   7   8   9   10   >