Re: [PATCH 11/40] ipv6/flowlabel: simplify pid namespace lookup

2018-05-16 Thread Eric W. Biederman
Christoph Hellwig  writes:

> On Sat, May 05, 2018 at 07:37:33AM -0500, Eric W. Biederman wrote:
>> Christoph Hellwig  writes:
>> 
>> > The shole seq_file sequence already operates under a single RCU lock pair,
>> > so move the pid namespace lookup into it, and stop grabbing a reference
>> > and remove all kinds of boilerplate code.
>> 
>> This is wrong.
>> 
>> Move task_active_pid_ns(current) from open to seq_start actually means
>> that the results if you pass this proc file between callers the results
>> will change.  So this breaks file descriptor passing.
>> 
>> Open is a bad place to access current.  In the middle of read/write is
>> broken.
>> 
>> 
>> In this particular instance looking up the pid namespace with
>> task_active_pid_ns was a personal brain fart.  What the code should be
>> doing (with an appropriate helper) is:
>> 
>> struct pid_namespace *pid_ns = inode->i_sb->s_fs_info;
>> 
>> Because each mount of proc is bound to a pid namespace.  Looking up the
>> pid namespace from the super_block is a much better way to go.
>
> What do you have in mind for the helper?  For now I've thrown it in
> opencoded into my working tree, but I'd be glad to add a helper.
>
> struct pid_namespace *proc_pid_namespace(struct inode *inode)
> {
>   // maybe warn on for s_magic not on procfs??
>   return inode->i_sb->s_fs_info;
> }

That should work.  Ideally out of line for the proc_fs.h version.
Basically it should be a cousin of PDE_DATA.

Eric



Re: Grant

2018-05-16 Thread Maratovich.M. Fridman



I Mikhail Fridman. has selected you specially as one of my beneficiaries
for my Charitable Donation, Just as I have declared on May 23, 2016 to give
my fortune as charity.

Check the link below for confirmation:

http://www.ibtimes.co.uk/russias-second-wealthiest-man-mikhail-fridman-plans-leaving-14-2bn-fortune-charity-1561604

Reply as soon as possible with further directives.

Best Regards,
Mikhail Fridman.



Re: [PATCH 1/4] scsi: ufs: add quirk to fix mishandling utrlclr/utmrlclr

2018-05-16 Thread Asutosh Das (asd)

On 5/6/2018 3:44 PM, Alim Akhtar wrote:

In the right behavior, setting the bit to '0' indicates clear and
'1' indicates no change. If host controller handles this the other way,
UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR can be used.

Signed-off-by: Seungwon Jeon 
Signed-off-by: Alim Akhtar 
---
  drivers/scsi/ufs/ufshcd.c | 21 +++--
  drivers/scsi/ufs/ufshcd.h |  5 +
  2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 00e7905..9898ce5 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -675,7 +675,24 @@ static inline void ufshcd_put_tm_slot(struct ufs_hba *hba, 
int slot)
   */
  static inline void ufshcd_utrl_clear(struct ufs_hba *hba, u32 pos)
  {
-   ufshcd_writel(hba, ~(1 << pos), REG_UTP_TRANSFER_REQ_LIST_CLEAR);
+   if (hba->quirks & UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR)
+   ufshcd_writel(hba, (1 << pos), REG_UTP_TRANSFER_REQ_LIST_CLEAR);
+   else
+   ufshcd_writel(hba, ~(1 << pos),
+   REG_UTP_TRANSFER_REQ_LIST_CLEAR);
+}
+
+/**
+ * ufshcd_utmrl_clear - Clear a bit in UTRMLCLR register
+ * @hba: per adapter instance
+ * @pos: position of the bit to be cleared
+ */
+static inline void ufshcd_utmrl_clear(struct ufs_hba *hba, u32 pos)
+{
+   if (hba->quirks & UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR)
+   ufshcd_writel(hba, (1 << pos), REG_UTP_TASK_REQ_LIST_CLEAR);
+   else
+   ufshcd_writel(hba, ~(1 << pos), REG_UTP_TASK_REQ_LIST_CLEAR);
  }
  
  /**

@@ -5398,7 +5415,7 @@ static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int 
tag)
goto out;
  
  	spin_lock_irqsave(hba->host->host_lock, flags);

-   ufshcd_writel(hba, ~(1 << tag), REG_UTP_TASK_REQ_LIST_CLEAR);
+   ufshcd_utmrl_clear(hba, tag);
spin_unlock_irqrestore(hba->host->host_lock, flags);
  
  	/* poll for max. 1 sec to clear door bell register by h/w */

diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 8110dcd..43035f8 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -595,6 +595,11 @@ struct ufs_hba {
 */
#define UFSHCD_QUIRK_PRDT_BYTE_GRAN 0x80
  
+	/*

+* Cleaer handling for transfer/task request list is just opposite.
+*/

Spell check - should be 'Clear'

+   #define UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR0x100
+
unsigned int quirks;/* Deviations from standard UFSHCI spec. */
  
  	/* Device deviations from standard UFS device spec. */




Looks good to me, except the spell-check.

--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a 
Linux Foundation Collaborative Project


[PATCH 1/1] qla2xxx: Allow SCSI-MQ to be enabled selectively

2018-05-16 Thread Himanshu Madhani
when ql2xmqsupport=1, use that value to selectively
enable SCSI-MQ

Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_os.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 817c18a8e84d..f870e85be38f 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -4566,6 +4566,7 @@ struct scsi_qla_host *qla2x00_create_host(struct 
scsi_host_template *sht,
return NULL;
}
 
+   host->use_blk_mq = ql2xmqsupport ? true : false;
/* Clear our data area */
vha = shost_priv(host);
memset(vha, 0, sizeof(scsi_qla_host_t));
-- 
2.12.0



Re: [PATCH 34/40] atm: simplify procfs code

2018-05-16 Thread Eric W. Biederman
Christoph Hellwig  writes:

> On Sat, May 05, 2018 at 07:51:18AM -0500, Eric W. Biederman wrote:
>> Christoph Hellwig  writes:
>> 
>> > Use remove_proc_subtree to remove the whole subtree on cleanup, and
>> > unwind the registration loop into individual calls.  Switch to use
>> > proc_create_seq where applicable.
>> 
>> Can you please explain why you are removing the error handling when
>> you are unwinding the registration loop?
>
> Because there is no point in handling these errors.  The code work
> perfectly fine without procfs, or without given proc files and the
> removal works just fine if they don't exist either.  This is a very
> common patter in various parts of the kernel already.
>
> I'll document it better in the changelog.

Thank you.  That is the kind of thing that could be a signal of
inattentiveness and problems, especially when it is not documented.

Eric



[PATCH] Bsg referencing parent device

2018-05-16 Thread Anatoliy Glagolev
A follow-up on earlier discussions:
[PATCH] bsg referencing bus driver module
https://www.spinics.net/lists/linux-scsi/msg119631.html
[PATCH] Waiting for scsi_host_template release
https://www.spinics.net/lists/linux-scsi/msg119432.html

All these discussions are attempts to fix a crash after
SCSI transport driver unload if a user-mode process
holds a handle in BSG layer towards the unloaded driver
via SCSI mid-layer:

[16834.636216,07] Call Trace:
 ...   scsi_proc_hostdir_rm
[16834.641944,07]  [] scsi_host_dev_release+0x3f/0x130
[16834.647740,07]  [] device_release+0x32/0xa0
[16834.653423,07]  [] kobject_cleanup+0x77/0x190
[16834.659002,07]  [] kobject_put+0x25/0x50
[16834.664430,07]  [] put_device+0x17/0x20
[16834.669740,07]  [] bsg_kref_release_function+0x24/0x30
[16834.675007,07]  [] bsg_release+0x166/0x1d0
[16834.680148,07]  [] __fput+0xcb/0x1d0
[16834.685156,07]  [] fput+0xe/0x10
[16834.690017,07]  [] task_work_run+0x86/0xb0
[16834.694781,07]  [] exit_to_usermode_loop+0x6b/0x9a
[16834.699466,07]  [] syscall_return_slowpath+0x55/0x60
[16834.704110,07]  [] int_ret_from_sys_call+0x25/0x9f

The latest input from earlier discussions was to cut off access
to the unloaded driver at bsg_unregister_queue time by calling
blk_cleanup_queue. If we do that we still have to release
the reference to the parent device (otherwise we crash with
the same stack). The next logical step is, rather than maintaining
a "part-time" reference to be dropped early, we discard
referencing completely.
Discarding the reference turns out to be the only thing needed
to fix the problem: all transport drivers already do blk_cleanup_queue
before releasing their reference to the parent device.

>From 7eaa9b43f0b99766b1d197044eb4d2e549d11a24 Mon Sep 17 00:00:00 2001
From: Anatoliy Glagolev 
Date: Wed, 16 May 2018 17:03:09 -0600
Subject: [PATCH] Bsg referencing parent device
Signed-off-by: Anatoliy Glagolev 

Bsg holding reference to a parent device may result in a crash
if user closes a bsg file handle after the parent device driver
has unloaded.
Holding a reference is not really needed: parent device must exist
between bsg_register_queue and bsg_unregister_queue. Before
the device goes away the caller does blk_cleanup_queue so that
all in-flight requests to the device are gone and all new requests
cannot pass beyond the queue. The queue itself is a refcounted
object and it will stay alive with a bsg file.
---
 block/bsg.c | 37 +
 1 file changed, 17 insertions(+), 20 deletions(-)

diff --git a/block/bsg.c b/block/bsg.c
index defa06c..f9e4b91 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -650,18 +650,6 @@ static struct bsg_device *bsg_alloc_device(void)
return bd;
 }
 
-static void bsg_kref_release_function(struct kref *kref)
-{
-   struct bsg_class_device *bcd =
-   container_of(kref, struct bsg_class_device, ref);
-   struct device *parent = bcd->parent;
-
-   if (bcd->release)
-   bcd->release(bcd->parent);
-
-   put_device(parent);
-}
-
 static int bsg_put_device(struct bsg_device *bd)
 {
int ret = 0, do_free;
@@ -694,7 +682,6 @@ static int bsg_put_device(struct bsg_device *bd)
 
kfree(bd);
 out:
-   kref_put(>bsg_dev.ref, bsg_kref_release_function);
if (do_free)
blk_put_queue(q);
return ret;
@@ -760,8 +747,6 @@ static struct bsg_device *bsg_get_device(struct inode 
*inode, struct file *file)
 */
mutex_lock(_mutex);
bcd = idr_find(_minor_idr, iminor(inode));
-   if (bcd)
-   kref_get(>ref);
mutex_unlock(_mutex);
 
if (!bcd)
@@ -772,8 +757,6 @@ static struct bsg_device *bsg_get_device(struct inode 
*inode, struct file *file)
return bd;
 
bd = bsg_add_device(inode, bcd->queue, file);
-   if (IS_ERR(bd))
-   kref_put(>ref, bsg_kref_release_function);
 
return bd;
 }
@@ -902,6 +885,8 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, 
unsigned long arg)
 
 void bsg_unregister_queue(struct request_queue *q)
 {
+   struct device *parent;
+   void (*release)(struct device *dev);
struct bsg_class_device *bcd = >bsg_dev;
 
if (!bcd->class_dev)
@@ -913,8 +898,21 @@ void bsg_unregister_queue(struct request_queue *q)
sysfs_remove_link(>kobj, "bsg");
device_unregister(bcd->class_dev);
bcd->class_dev = NULL;
-   kref_put(>ref, bsg_kref_release_function);
+   parent = bcd->parent;
+   release = bcd->release;
+   bcd->parent = NULL;
+   bcd->release = NULL;
mutex_unlock(_mutex);
+
+   /*
+* The caller of bsg_[un]register_queue must hold a reference
+* to the parent device between ..register.. and ..unregister..
+* so we do not maintain a refcount to parent here.
+* Note: the caller is expected to 

答复: 答复: [PATCH v9 2/5] dt-bindings: scsi: ufs: add document for hisi-ufs

2018-05-16 Thread liwei (CM)
Hi, Rob

-邮件原件-
发件人: Rob Herring [mailto:r...@kernel.org] 
发送时间: 2018年5月16日 21:16
收件人: liwei (CM)
抄送: mark.rutl...@arm.com; catalin.mari...@arm.com; will.dea...@arm.com; 
vinholika...@gmail.com; j...@linux.vnet.ibm.com; martin.peter...@oracle.com; 
khil...@baylibre.com; a...@arndb.de; gregory.clem...@free-electrons.com; 
thomas.petazz...@free-electrons.com; yamada.masah...@socionext.com; 
riku.voi...@linaro.org; tred...@nvidia.com; k...@kernel.org; 
devicet...@vger.kernel.org; linux-ker...@vger.kernel.org; 
linux-arm-ker...@lists.infradead.org; linux-scsi@vger.kernel.org; zangleigang; 
Gengjianfeng; guodong...@linaro.org
主题: Re: 答复: [PATCH v9 2/5] dt-bindings: scsi: ufs: add document for hisi-ufs

On Tue, Apr 24, 2018 at 8:54 AM, liwei (CM)  wrote:
> Hi, Rob
>
> Thanks for your patience.
>
> Hi, Arnd
>
> From Rob's suggestion, we have to list the properties node in ufs-hisi.txt 
> bingings even if documented in the common binding.
>
> -邮件原件-
> 发件人: Rob Herring [mailto:r...@kernel.org]
> 发送时间: 2018年4月24日 20:58
> 收件人: liwei (CM)
> 抄送: mark.rutl...@arm.com; catalin.mari...@arm.com; will.dea...@arm.com; 
> vinholika...@gmail.com; j...@linux.vnet.ibm.com; martin.peter...@oracle.com; 
> khil...@baylibre.com; a...@arndb.de; gregory.clem...@free-electrons.com; 
> thomas.petazz...@free-electrons.com; yamada.masah...@socionext.com; 
> riku.voi...@linaro.org; tred...@nvidia.com; k...@kernel.org; 
> devicet...@vger.kernel.org; linux-ker...@vger.kernel.org; 
> linux-arm-ker...@lists.infradead.org; linux-scsi@vger.kernel.org; 
> zangleigang; Gengjianfeng; guodong...@linaro.org
> 主题: Re: [PATCH v9 2/5] dt-bindings: scsi: ufs: add document for hisi-ufs
>
> On Tue, Apr 17, 2018 at 10:08:11PM +0800, Li Wei wrote:
>> add ufs node document for Hisilicon.
>>
>> Signed-off-by: Li Wei 
>> ---
>>  Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 29 
>> ++
>>  .../devicetree/bindings/ufs/ufshcd-pltfrm.txt  | 10 +---
>>  2 files changed, 36 insertions(+), 3 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt
>>
>> diff --git a/Documentation/devicetree/bindings/ufs/ufs-hisi.txt 
>> b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt
>> new file mode 100644
>> index ..d49ab7d8f31d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt
>> @@ -0,0 +1,29 @@
>> +* Hisilicon Universal Flash Storage (UFS) Host Controller
>> +
>> +UFS nodes are defined to describe on-chip UFS hardware macro.
>> +Each UFS Host Controller should have its own node.
>> +
>> +Required properties:
>> +- compatible: compatible list, contains one of the following -
>> + "hisilicon,hi3660-ufs", 
>> "jedec,ufs-1.1" for hisi ufs
>> + host controller present on Hi36xx 
>> chipset.
>> +- reg   : should contain UFS register address space & UFS SYS 
>> CTRL register address,
>> +- interrupt-parent  : interrupt device
>> +- interrupts: interrupt number
>> +- resets: reset node register, the "arst" corresponds to reset 
>> the APB/AXI bus.
>
> arst belongs in reset-names.
>
> OK, I will fix it in next patch;
>
>> +- reset-names   : describe reset node register
>
> What happened to clocks? You still have to list which ones apply even if
> documented in the common binding.
>
> OK, I will fix it in next patch;
>
>> +
>> +Example:
>> +
>> + ufs: ufs@ff3b {
>> + compatible = "hisilicon,hi3660-ufs", "jedec,ufs-1.1";
>> + /* 0: HCI standard */
>> + /* 1: UFS SYS CTRL */
>> + reg = <0x0 0xff3b 0x0 0x1000>,
>> + <0x0 0xff3b1000 0x0 0x1000>;
>> + interrupt-parent = <>;
>> + interrupts = ;
>> + /* offset: 0x84; bit: 7  */
>> + resets = <_rst 0x84 7>;
>> + reset-names = "arst";
>> + };
>> diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt 
>> b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
>> index c39dfef76a18..adcfb79f63f5 100644
>> --- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
>> +++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
>> @@ -41,6 +41,8 @@ Optional properties:
>>  -lanes-per-direction : number of lanes available per direction - either 1 
>> or 2.
>> Note that it is assume same number of lanes is used 
>> both
>> directions at once. If not specified, default is 2 
>> lanes per direction.
>> +- resets: reset node register, the "rst" corresponds to reset 
>> the whole UFS IP.
>> +- reset-names   : describe reset node register
>
> Does your controller have 1 or 2 resets? There's no point in adding this
> here if it doesn't apply to your controller.
>
> There are 2 reset in our soc init, the "rst" corresponds to reset the whole 
> UFS IP, and " 

Re: [RFC PATCH V2] scsi: ufs: Add specific callback for setting DMA mask

2018-05-16 Thread Subhash Jadavani

On 2018-05-15 21:31, Alim Akhtar wrote:

Ping !!!

On Thu, Mar 8, 2018 at 4:33 PM, Alim Akhtar  
wrote:

Currently DMA mask for UFS HCI is set by reading CAP register's
[64AS] bit. Some HCI controller like Exynos support 36-bit bus 
address.

This works perfectly fine with DMA mask set as 64 in case there is no
IOMMU attached to HCI.
In case if HCI is behind an IOMMU, setting DMA mask as 64 bit won't
work as HCI has only 36bit addressing and SMMU has created mapping of
64 bit and as the device truncates the address, its mapping will not
be found by iommu.
To resolve such issues, let the variant driver sets its own DMA mask.

Signed-off-by: Alim Akhtar 
---
 drivers/scsi/ufs/ufshcd.c | 3 +++
 drivers/scsi/ufs/ufshcd.h | 2 ++
 2 files changed, 5 insertions(+)

I am not sure if there are other ways available to handle such cases.
The IOMMU I am talking about is arm-smmu and it DT binding does not
give much idea about handling such cases.
Have tested this patch with HCI controller with IOMMU attached.

Changes Since V1:
- Fixed build issue as reported by Kbuild test robot.

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index a355d98..9a1374e 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -7781,6 +7781,9 @@ EXPORT_SYMBOL_GPL(ufshcd_dealloc_host);
  */
 static int ufshcd_set_dma_mask(struct ufs_hba *hba)
 {
+   if (hba->vops && hba->vops->set_dma_mask)
+   return hba->vops->set_dma_mask(hba);
+
if (hba->capabilities & MASK_64_ADDRESSING_SUPPORT) {
if (!dma_set_mask_and_coherent(hba->dev, 
DMA_BIT_MASK(64)))

return 0;
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 1332e54..89c6dae 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -297,6 +297,7 @@ struct ufs_pwr_mode_info {
  * @resume: called during host controller PM callback
  * @dbg_register_dump: used to dump controller debug information
  * @phy_initialization: used to initialize phys
+ * @set_dma_mask: used to set variant specific DMA mask
  */
 struct ufs_hba_variant_ops {
const char *name;
@@ -325,6 +326,7 @@ struct ufs_hba_variant_ops {
int (*resume)(struct ufs_hba *, enum ufs_pm_op);
void(*dbg_register_dump)(struct ufs_hba *hba);
int (*phy_initialization)(struct ufs_hba *);
+   int (*set_dma_mask)(struct ufs_hba *hba);
 };

 /* clock gating state  */
--
2.7.4



Looks reasonable to me, you may try posting non-RFC version.

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


Re: [PATCH 4/4] scsi: ufs: make ufshcd_config_pwr_mode of non-static func

2018-05-16 Thread Subhash Jadavani

On 2018-05-06 03:14, Alim Akhtar wrote:

This makes ufshcd_config_pwr_mode non-static so that other vendors
like exynos can use the same.

Signed-off-by: Seungwon Jeon 
Signed-off-by: Alim Akhtar 
---
 drivers/scsi/ufs/ufshcd.c | 5 ++---
 drivers/scsi/ufs/ufshcd.h | 2 ++
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 5bfd385..68aefcd 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -233,8 +233,6 @@ static void ufshcd_suspend_clkscaling(struct 
ufs_hba *hba);

 static void __ufshcd_suspend_clkscaling(struct ufs_hba *hba);
 static int ufshcd_scale_clks(struct ufs_hba *hba, bool scale_up);
 static irqreturn_t ufshcd_intr(int irq, void *__hba);
-static int ufshcd_config_pwr_mode(struct ufs_hba *hba,
-   struct ufs_pa_layer_attr *desired_pwr_mode);
 static int ufshcd_change_power_mode(struct ufs_hba *hba,
 struct ufs_pa_layer_attr *pwr_mode);
 static inline bool ufshcd_valid_tag(struct ufs_hba *hba, int tag)
@@ -3969,7 +3967,7 @@ static int ufshcd_change_power_mode(struct 
ufs_hba *hba,

  * @hba: per-adapter instance
  * @desired_pwr_mode: desired power configuration
  */
-static int ufshcd_config_pwr_mode(struct ufs_hba *hba,
+int ufshcd_config_pwr_mode(struct ufs_hba *hba,
struct ufs_pa_layer_attr *desired_pwr_mode)
 {
struct ufs_pa_layer_attr final_params = { 0 };
@@ -3987,6 +3985,7 @@ static int ufshcd_config_pwr_mode(struct ufs_hba 
*hba,


return ret;
 }
+EXPORT_SYMBOL_GPL(ufshcd_config_pwr_mode);

 /**
  * ufshcd_complete_dev_init() - checks device readiness
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 013a07e..b42a5a3 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -805,6 +805,8 @@ extern int ufshcd_dme_set_attr(struct ufs_hba
*hba, u32 attr_sel,
   u8 attr_set, u32 mib_val, u8 peer);
 extern int ufshcd_dme_get_attr(struct ufs_hba *hba, u32 attr_sel,
   u32 *mib_val, u8 peer);
+extern int ufshcd_config_pwr_mode(struct ufs_hba *hba,
+   struct ufs_pa_layer_attr *desired_pwr_mode);

 /* UIC command interfaces for DME primitives */
 #define DME_LOCAL  0


Looks good to me.
Reviewed-by: Subhash Jadavani 

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


Re: [PATCH 3/4] scsi: ufs: add quirk to enable host controller without hce

2018-05-16 Thread Subhash Jadavani

On 2018-05-06 03:14, Alim Akhtar wrote:

Some host controller doesn't support host controller enable via HCE.

Signed-off-by: Seungwon Jeon 
Signed-off-by: Alim Akhtar 
---
 drivers/scsi/ufs/ufshcd.c | 75 
+--

 drivers/scsi/ufs/ufshcd.h |  5 
 2 files changed, 78 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 253257c..5bfd385 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -3400,6 +3400,52 @@ static int ufshcd_dme_link_startup(struct 
ufs_hba *hba)

"dme-link-startup: error code %d\n", ret);
return ret;
 }
+/**
+ * ufshcd_dme_reset - UIC command for DME_RESET
+ * @hba: per adapter instance
+ *
+ * DME_RESET command is issued in order to reset UniPro stack.
+ * This function now deal with cold reset.
+ *
+ * Returns 0 on success, non-zero value on failure
+ */
+static int ufshcd_dme_reset(struct ufs_hba *hba)
+{
+   struct uic_command uic_cmd = {0};
+   int ret;
+
+   uic_cmd.command = UIC_CMD_DME_RESET;
+
+   ret = ufshcd_send_uic_cmd(hba, _cmd);
+   if (ret)
+   dev_err(hba->dev,
+   "dme-reset: error code %d\n", ret);
+
+   return ret;
+}
+
+/**
+ * ufshcd_dme_enable - UIC command for DME_ENABLE
+ * @hba: per adapter instance
+ *
+ * DME_ENABLE command is issued in order to enable UniPro stack.
+ *
+ * Returns 0 on success, non-zero value on failure
+ */
+static int ufshcd_dme_enable(struct ufs_hba *hba)
+{
+   struct uic_command uic_cmd = {0};
+   int ret;
+
+   uic_cmd.command = UIC_CMD_DME_ENABLE;
+
+   ret = ufshcd_send_uic_cmd(hba, _cmd);
+   if (ret)
+   dev_err(hba->dev,
+   "dme-reset: error code %d\n", ret);
+
+   return ret;
+}

 static inline void ufshcd_add_delay_before_dme_cmd(struct ufs_hba 
*hba)

 {
@@ -4058,7 +4104,7 @@ static inline void ufshcd_hba_stop(struct
ufs_hba *hba, bool can_sleep)
 }

 /**
- * ufshcd_hba_enable - initialize the controller
+ * ufshcd_hba_execute_hce - initialize the controller
  * @hba: per adapter instance
  *
  * The controller resets itself and controller firmware initialization
@@ -4067,7 +4113,7 @@ static inline void ufshcd_hba_stop(struct
ufs_hba *hba, bool can_sleep)
  *
  * Returns 0 on success, non-zero value on failure
  */
-static int ufshcd_hba_enable(struct ufs_hba *hba)
+static int ufshcd_hba_execute_hce(struct ufs_hba *hba)
 {
int retry;

@@ -4122,6 +4168,31 @@ static int ufshcd_hba_enable(struct ufs_hba 
*hba)

return 0;
 }

+static int ufshcd_hba_enable(struct ufs_hba *hba)
+{
+   int ret;
+
+   if (hba->quirks & UFSHCI_QUIRK_BROKEN_HCE) {
+   ufshcd_set_link_off(hba);
+   ufshcd_vops_hce_enable_notify(hba, PRE_CHANGE);
+
+   /* enable UIC related interrupts */
+   ufshcd_enable_intr(hba, UFSHCD_UIC_MASK);
+   ret = ufshcd_dme_reset(hba);
+   if (!ret) {
+   ret = ufshcd_dme_enable(hba);
+   if (!ret)
+   ufshcd_vops_hce_enable_notify(hba, POST_CHANGE);
+   if (ret)
+   dev_err(hba->dev,
+   "Host controller enable failed with 
non-hce\n");
+   }
+   } else {
+   ret = ufshcd_hba_execute_hce(hba);
+   }
+
+   return ret;
+}
 static int ufshcd_disable_tx_lcc(struct ufs_hba *hba, bool peer)
 {
int tx_lanes, i, err = 0;
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 5c91ff1..013a07e 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -606,6 +606,11 @@ struct ufs_hba {
 */
#define UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR   0x200

+   /*
+* This quirks needs to be enabled if host controller cannot be
+* enabled via HCE register.
+*/
+   #define UFSHCI_QUIRK_BROKEN_HCE 0x400
unsigned int quirks;/* Deviations from standard UFSHCI spec. */

/* Device deviations from standard UFS device spec. */


Looks good to me.
Reviewed-by: Subhash Jadavani 

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


Re: [PATCH 2/4] scsi: ufs: add quirk not to allow reset of interrupt aggregation

2018-05-16 Thread Subhash Jadavani

On 2018-05-06 03:14, Alim Akhtar wrote:

Some host controller supports interrupt aggregation, but doesn't
allow to reset counter and timer by s/w.

Signed-off-by: Seungwon Jeon 
Signed-off-by: Alim Akhtar 
---
 drivers/scsi/ufs/ufshcd.c | 3 ++-
 drivers/scsi/ufs/ufshcd.h | 6 ++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 9898ce5..253257c 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -4695,7 +4695,8 @@ static void ufshcd_transfer_req_compl(struct 
ufs_hba *hba)
 	 * false interrupt if device completes another request after 
resetting

 * aggregation and before reading the DB.
 */
-   if (ufshcd_is_intr_aggr_allowed(hba))
+   if (ufshcd_is_intr_aggr_allowed(hba) &&
+   !(hba->quirks & UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR))
ufshcd_reset_intr_aggr(hba);

tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 43035f8..5c91ff1 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -600,6 +600,12 @@ struct ufs_hba {
 */
#define UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR0x100

+   /*
+* This quirk needs to be enabled if host controller doesn't allow
+* that the interrupt aggregation timer and counter are reset by s/w.
+*/
+   #define UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR   0x200
+
unsigned int quirks;/* Deviations from standard UFSHCI spec. */

/* Device deviations from standard UFS device spec. */


Looks good to me.
Reviewed-by: Subhash Jadavani 

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


Re: [PATCH 1/4] scsi: ufs: add quirk to fix mishandling utrlclr/utmrlclr

2018-05-16 Thread Subhash Jadavani

On 2018-05-06 03:14, Alim Akhtar wrote:

In the right behavior, setting the bit to '0' indicates clear and
'1' indicates no change. If host controller handles this the other way,
UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR can be used.

Signed-off-by: Seungwon Jeon 
Signed-off-by: Alim Akhtar 
---
 drivers/scsi/ufs/ufshcd.c | 21 +++--
 drivers/scsi/ufs/ufshcd.h |  5 +
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 00e7905..9898ce5 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -675,7 +675,24 @@ static inline void ufshcd_put_tm_slot(struct
ufs_hba *hba, int slot)
  */
 static inline void ufshcd_utrl_clear(struct ufs_hba *hba, u32 pos)
 {
-   ufshcd_writel(hba, ~(1 << pos), REG_UTP_TRANSFER_REQ_LIST_CLEAR);
+   if (hba->quirks & UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR)
+   ufshcd_writel(hba, (1 << pos), REG_UTP_TRANSFER_REQ_LIST_CLEAR);
+   else
+   ufshcd_writel(hba, ~(1 << pos),
+   REG_UTP_TRANSFER_REQ_LIST_CLEAR);
+}
+
+/**
+ * ufshcd_utmrl_clear - Clear a bit in UTRMLCLR register
+ * @hba: per adapter instance
+ * @pos: position of the bit to be cleared
+ */
+static inline void ufshcd_utmrl_clear(struct ufs_hba *hba, u32 pos)
+{
+   if (hba->quirks & UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR)
+   ufshcd_writel(hba, (1 << pos), REG_UTP_TASK_REQ_LIST_CLEAR);
+   else
+   ufshcd_writel(hba, ~(1 << pos), REG_UTP_TASK_REQ_LIST_CLEAR);
 }

 /**
@@ -5398,7 +5415,7 @@ static int ufshcd_clear_tm_cmd(struct ufs_hba
*hba, int tag)
goto out;

spin_lock_irqsave(hba->host->host_lock, flags);
-   ufshcd_writel(hba, ~(1 << tag), REG_UTP_TASK_REQ_LIST_CLEAR);
+   ufshcd_utmrl_clear(hba, tag);
spin_unlock_irqrestore(hba->host->host_lock, flags);

/* poll for max. 1 sec to clear door bell register by h/w */
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 8110dcd..43035f8 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -595,6 +595,11 @@ struct ufs_hba {
 */
#define UFSHCD_QUIRK_PRDT_BYTE_GRAN 0x80

+   /*
+* Cleaer handling for transfer/task request list is just opposite.
+*/
+   #define UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR0x100
+
unsigned int quirks;/* Deviations from standard UFSHCI spec. */

/* Device deviations from standard UFS device spec. */


Looks good to me.
Reviewed-by: Subhash Jadavani 

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


Re: [PATCH v2 2/2] scsi: ufs: Use freq table with devfreq

2018-05-16 Thread Subhash Jadavani

On 2018-05-04 15:44, Bjorn Andersson wrote:

devfreq requires that the client operates on actual frequencies, not
only 0 and UMAX_INT and as such UFS brok with the introduction of
f1d981eaecf8 ("PM / devfreq: Use the available min/max frequency").

This patch registers the frequencies of the first clock as opp levels
and use these to determine if we're trying to step up or down.

Signed-off-by: Bjorn Andersson 
---

Chances since v1:
- Register min_freq and max_freq as opp levels.
- Unregister opp levels on removal, to make e.g. probe defer working

 drivers/scsi/ufs/ufshcd.c | 47 +--
 1 file changed, 40 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 2253f24309ec..257614b889bd 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -1168,16 +1168,13 @@ static int ufshcd_devfreq_target(struct device 
*dev,

struct ufs_hba *hba = dev_get_drvdata(dev);
ktime_t start;
bool scale_up, sched_clk_scaling_suspend_work = false;
+   struct list_head *clk_list = >clk_list_head;
+   struct ufs_clk_info *clki;
unsigned long irq_flags;

if (!ufshcd_is_clkscaling_supported(hba))
return -EINVAL;

-   if ((*freq > 0) && (*freq < UINT_MAX)) {
-   dev_err(hba->dev, "%s: invalid freq = %lu\n", __func__, *freq);
-   return -EINVAL;
-   }
-
spin_lock_irqsave(hba->host->host_lock, irq_flags);
if (ufshcd_eh_in_progress(hba)) {
spin_unlock_irqrestore(hba->host->host_lock, irq_flags);
@@ -1187,7 +1184,13 @@ static int ufshcd_devfreq_target(struct device 
*dev,

if (!hba->clk_scaling.active_reqs)
sched_clk_scaling_suspend_work = true;

-   scale_up = (*freq == UINT_MAX) ? true : false;
+   if (list_empty(clk_list)) {
+   spin_unlock_irqrestore(hba->host->host_lock, irq_flags);
+   goto out;
+   }
+
+   clki = list_first_entry(clk_list, struct ufs_clk_info, list);
+   scale_up = (*freq == clki->max_freq) ? true : false;
if (!ufshcd_is_devfreq_scaling_required(hba, scale_up)) {
spin_unlock_irqrestore(hba->host->host_lock, irq_flags);
ret = 0;
@@ -1257,16 +1260,29 @@ static struct devfreq_dev_profile
ufs_devfreq_profile = {

 static int ufshcd_devfreq_init(struct ufs_hba *hba)
 {
+   struct list_head *clk_list = >clk_list_head;
+   struct ufs_clk_info *clki;
struct devfreq *devfreq;
int ret;

-   devfreq = devm_devfreq_add_device(hba->dev,
+   /* Skip devfreq if we don't have any clocks in the list */
+   if (list_empty(clk_list))
+   return 0;
+
+   clki = list_first_entry(clk_list, struct ufs_clk_info, list);
+   dev_pm_opp_add(hba->dev, clki->min_freq, 0);
+   dev_pm_opp_add(hba->dev, clki->max_freq, 0);
+
+   devfreq = devfreq_add_device(hba->dev,
_devfreq_profile,
"simple_ondemand",
NULL);
if (IS_ERR(devfreq)) {
ret = PTR_ERR(devfreq);
dev_err(hba->dev, "Unable to register with devfreq %d\n", ret);
+
+   dev_pm_opp_remove(hba->dev, clki->min_freq);
+   dev_pm_opp_remove(hba->dev, clki->max_freq);
return ret;
}

@@ -1275,6 +1291,22 @@ static int ufshcd_devfreq_init(struct ufs_hba 
*hba)

return 0;
 }

+static void ufshcd_devfreq_remove(struct ufs_hba *hba)
+{
+   struct list_head *clk_list = >clk_list_head;
+   struct ufs_clk_info *clki;
+
+   if (!hba->devfreq)
+   return;
+
+   devfreq_remove_device(hba->devfreq);
+   hba->devfreq = NULL;
+
+   clki = list_first_entry(clk_list, struct ufs_clk_info, list);
+   dev_pm_opp_remove(hba->dev, clki->min_freq);
+   dev_pm_opp_remove(hba->dev, clki->max_freq);
+}
+
 static void __ufshcd_suspend_clkscaling(struct ufs_hba *hba)
 {
unsigned long flags;
@@ -6966,6 +6998,7 @@ static void ufshcd_hba_exit(struct ufs_hba *hba)
if (hba->devfreq)
ufshcd_suspend_clkscaling(hba);
destroy_workqueue(hba->clk_scaling.workq);
+   ufshcd_devfreq_remove(hba);
}
ufshcd_setup_clocks(hba, false);
ufshcd_setup_hba_vreg(hba, false);


Looks good to me.
Reviewed-by: Subhash Jadavani 

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


Re: [PATCH v2 10/10] scsi: ufs: Add clock ungating to a separate workqueue

2018-05-16 Thread Subhash Jadavani

On 2018-05-03 04:07, Asutosh Das wrote:

From: Vijay Viswanath 

UFS driver can receive a request during memory reclaim by kswapd.
So when ufs driver puts the ungate work in queue, and if there are no
idle workers, kthreadd is invoked to create a new kworker. Since
kswapd task holds a mutex which kthreadd also needs, this can cause
a deadlock situation. So ungate work must be done in a separate
work queue with WQ_MEM_RECLAIM flag enabled.
Such a workqueue will have a rescue thread which will be called
when the above deadlock condition is possible.

Signed-off-by: Vijay Viswanath 
Signed-off-by: Can Guo 
Signed-off-by: Asutosh Das 
---
 drivers/scsi/ufs/ufshcd.c | 11 ++-
 drivers/scsi/ufs/ufshcd.h |  1 +
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 557d538..3be61b7 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -1483,7 +1483,8 @@ int ufshcd_hold(struct ufs_hba *hba, bool async)
hba->clk_gating.state = REQ_CLKS_ON;
trace_ufshcd_clk_gating(dev_name(hba->dev),
hba->clk_gating.state);
-   schedule_work(>clk_gating.ungate_work);
+   queue_work(hba->clk_gating.clk_gating_workq,
+  >clk_gating.ungate_work);
/*
 * fall through to check if we should wait for this
 * work to be done or not.
@@ -1669,6 +1670,8 @@ static ssize_t
ufshcd_clkgate_enable_store(struct device *dev,

 static void ufshcd_init_clk_gating(struct ufs_hba *hba)
 {
+   char wq_name[sizeof("ufs_clk_gating_00")];
+
if (!ufshcd_is_clkgating_allowed(hba))
return;

@@ -1676,6 +1679,11 @@ static void ufshcd_init_clk_gating(struct 
ufs_hba *hba)

INIT_DELAYED_WORK(>clk_gating.gate_work, ufshcd_gate_work);
INIT_WORK(>clk_gating.ungate_work, ufshcd_ungate_work);

+   snprintf(wq_name, ARRAY_SIZE(wq_name), "ufs_clk_gating_%d",
+hba->host->host_no);
+   hba->clk_gating.clk_gating_workq = alloc_ordered_workqueue(wq_name,
+  WQ_MEM_RECLAIM);
+
hba->clk_gating.is_enabled = true;

hba->clk_gating.delay_attr.show = ufshcd_clkgate_delay_show;
@@ -1703,6 +1711,7 @@ static void ufshcd_exit_clk_gating(struct ufs_hba 
*hba)

device_remove_file(hba->dev, >clk_gating.enable_attr);
cancel_work_sync(>clk_gating.ungate_work);
cancel_delayed_work_sync(>clk_gating.gate_work);
+   destroy_workqueue(hba->clk_gating.clk_gating_workq);
 }

 /* Must be called with host lock acquired */
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 76c31d5..2e6bdc0 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -361,6 +361,7 @@ struct ufs_clk_gating {
struct device_attribute enable_attr;
bool is_enabled;
int active_reqs;
+   struct workqueue_struct *clk_gating_workq;
 };

 struct ufs_saved_pwr_info {


Looks good to me.
Reviewed-by: Subhash Jadavani 

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


Re: [PATCH v2 07/10] scsi: ufs-qcom: remove broken hci version quirk

2018-05-16 Thread Subhash Jadavani

On 2018-05-03 04:07, Asutosh Das wrote:

From: Subhash Jadavani 

UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION is only applicable for QCOM UFS 
host

controller version 2.x.y and this has been fixed from version 3.x.y
onwards, hence this change removes this quirk for version 3.x.y 
onwards.


Signed-off-by: Subhash Jadavani 
Signed-off-by: Asutosh Das 
---
 drivers/scsi/ufs/ufs-qcom.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index d9edef8..27be327 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -1103,7 +1103,7 @@ static void ufs_qcom_advertise_quirks(struct 
ufs_hba *hba)

hba->quirks |= UFSHCD_QUIRK_BROKEN_LCC;
}

-   if (host->hw_ver.major >= 0x2) {
+   if (host->hw_ver.major == 0x2) {
hba->quirks |= UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION;
hba->quirks |= UFSHCD_QUIRK_BROKEN_PWR_MODE_CHANGE;
if (!ufs_qcom_cap_qunipro(host))


Looks good to me.

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


Re: [PATCH v2 08/10] scsi: ufs: make sure all interrupts are processed

2018-05-16 Thread Subhash Jadavani

On 2018-05-03 04:07, Asutosh Das wrote:

From: Venkat Gopalakrishnan 

As multiple requests are submitted to the ufs host controller in
parallel there could be instances where the command completion
interrupt arrives later for a request that is already processed
earlier as the corresponding doorbell was cleared when handling
the previous interrupt. Read the interrupt status in a loop after
processing the received interrupt to catch such interrupts and
handle it.

Signed-off-by: Venkat Gopalakrishnan 
Signed-off-by: Asutosh Das 
---
 drivers/scsi/ufs/ufshcd.c | 27 +++
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index c35a076..09b7a3f 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -5383,19 +5383,30 @@ static irqreturn_t ufshcd_intr(int irq, void 
*__hba)

u32 intr_status, enabled_intr_status;
irqreturn_t retval = IRQ_NONE;
struct ufs_hba *hba = __hba;
+   int retries = hba->nutrs;

spin_lock(hba->host->host_lock);
intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS);
-   enabled_intr_status =
-   intr_status & ufshcd_readl(hba, REG_INTERRUPT_ENABLE);

-   if (intr_status)
-   ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS);
+   /*
+* There could be max of hba->nutrs reqs in flight and in worst case
+* if the reqs get finished 1 by 1 after the interrupt status is
+* read, make sure we handle them by checking the interrupt status
+* again in a loop until we process all of the reqs before returning.
+*/
+   do {
+   enabled_intr_status =
+   intr_status & ufshcd_readl(hba, REG_INTERRUPT_ENABLE);
+   if (intr_status)
+   ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS);
+   if (enabled_intr_status) {
+   ufshcd_sl_intr(hba, enabled_intr_status);
+   retval = IRQ_HANDLED;
+   }
+
+   intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS);
+   } while (intr_status && --retries);

-   if (enabled_intr_status) {
-   ufshcd_sl_intr(hba, enabled_intr_status);
-   retval = IRQ_HANDLED;
-   }
spin_unlock(hba->host->host_lock);
return retval;
 }


Looks good to me.
Reviewed-by: Subhash Jadavani 

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


Re: [PATCH v2 06/10] scsi: ufs: add reference counting for scsi block requests

2018-05-16 Thread Subhash Jadavani

On 2018-05-03 04:07, Asutosh Das wrote:

From: Subhash Jadavani 

Currently we call the scsi_block_requests()/scsi_unblock_requests()
whenever we want to block/unblock scsi requests but as there is no
reference counting, nesting of these calls could leave us in undesired
state sometime. Consider following call flow sequence:
1. func1() calls scsi_block_requests() but calls func2() before
   calling scsi_unblock_requests()
2. func2() calls scsi_block_requests()
3. func2() calls scsi_unblock_requests()
4. func1() calls scsi_unblock_requests()

As there is no reference counting, we will have scsi requests unblocked
after #3 instead of it to be unblocked only after #4. Though we may not
have failures seen with this, we might run into some failures in 
future.

Better solution would be to fix this by adding reference counting.

Signed-off-by: Subhash Jadavani 
Signed-off-by: Can Guo 
Signed-off-by: Asutosh Das 
---
 drivers/scsi/ufs/ufshcd.c | 28 
 drivers/scsi/ufs/ufshcd.h |  2 ++
 2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index dfeb194..c35a076 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -264,6 +264,18 @@ static inline void ufshcd_disable_irq(struct 
ufs_hba *hba)

}
 }

+static void ufshcd_scsi_unblock_requests(struct ufs_hba *hba)
+{
+   if (atomic_dec_and_test(>scsi_block_reqs_cnt))
+   scsi_unblock_requests(hba->host);
+}
+
+static void ufshcd_scsi_block_requests(struct ufs_hba *hba)
+{
+   if (atomic_inc_return(>scsi_block_reqs_cnt) == 1)
+   scsi_block_requests(hba->host);
+}
+
 /* replace non-printable or non-ASCII characters with spaces */
 static inline void ufshcd_remove_non_printable(char *val)
 {
@@ -1077,12 +1089,12 @@ static int ufshcd_clock_scaling_prepare(struct
ufs_hba *hba)
 * make sure that there are no outstanding requests when
 * clock scaling is in progress
 */
-   scsi_block_requests(hba->host);
+   ufshcd_scsi_block_requests(hba);
down_write(>clk_scaling_lock);
if (ufshcd_wait_for_doorbell_clr(hba, DOORBELL_CLR_TOUT_US)) {
ret = -EBUSY;
up_write(>clk_scaling_lock);
-   scsi_unblock_requests(hba->host);
+   ufshcd_scsi_unblock_requests(hba);
}

return ret;
@@ -1091,7 +1103,7 @@ static int ufshcd_clock_scaling_prepare(struct
ufs_hba *hba)
 static void ufshcd_clock_scaling_unprepare(struct ufs_hba *hba)
 {
up_write(>clk_scaling_lock);
-   scsi_unblock_requests(hba->host);
+   ufshcd_scsi_unblock_requests(hba);
 }

 /**
@@ -1411,7 +1423,7 @@ static void ufshcd_ungate_work(struct work_struct 
*work)

hba->clk_gating.is_suspended = false;
}
 unblock_reqs:
-   scsi_unblock_requests(hba->host);
+   ufshcd_scsi_unblock_requests(hba);
 }

 /**
@@ -1467,7 +1479,7 @@ int ufshcd_hold(struct ufs_hba *hba, bool async)
 * work and to enable clocks.
 */
case CLKS_OFF:
-   scsi_block_requests(hba->host);
+   ufshcd_scsi_block_requests(hba);
hba->clk_gating.state = REQ_CLKS_ON;
trace_ufshcd_clk_gating(dev_name(hba->dev),
hba->clk_gating.state);
@@ -5192,7 +5204,7 @@ static void ufshcd_err_handler(struct work_struct 
*work)


 out:
spin_unlock_irqrestore(hba->host->host_lock, flags);
-   scsi_unblock_requests(hba->host);
+   ufshcd_scsi_unblock_requests(hba);
ufshcd_release(hba);
pm_runtime_put_sync(hba->dev);
 }
@@ -5294,7 +5306,7 @@ static void ufshcd_check_errors(struct ufs_hba 
*hba)

/* handle fatal errors only when link is functional */
if (hba->ufshcd_state == UFSHCD_STATE_OPERATIONAL) {
/* block commands from scsi mid-layer */
-   scsi_block_requests(hba->host);
+   ufshcd_scsi_block_requests(hba);

hba->ufshcd_state = UFSHCD_STATE_EH_SCHEDULED;

@@ -8017,7 +8029,7 @@ int ufshcd_init(struct ufs_hba *hba, void
__iomem *mmio_base, unsigned int irq)

/* Hold auto suspend until async scan completes */
pm_runtime_get_sync(dev);
-
+   atomic_set(>scsi_block_reqs_cnt, 0);
/*
 * We are assuming that device wasn't put in sleep/power-down
 * state exclusively during the boot stage before kernel.
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 0417c42..76c31d5 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -498,6 +498,7 @@ struct ufs_stats {
  * @urgent_bkops_lvl: keeps track of urgent bkops level for device
  * @is_urgent_bkops_lvl_checked: keeps track if the urgent bkops level 
for

  *  device is 

Re: [PATCH v2 05/10] scsi: ufshcd: fix possible unclocked register access

2018-05-16 Thread Subhash Jadavani

On 2018-05-03 04:07, Asutosh Das wrote:

From: Subhash Jadavani 

vendor specific setup_clocks ops may depend on clocks managed by ufshcd
driver so if the vendor specific setup_clocks callback is called when
the required clocks are turned off, it results into unclocked register
access.

This change make sure that required clocks are enabled before vendor
specific setup_clocks callback is called.

Signed-off-by: Subhash Jadavani 
Signed-off-by: Venkat Gopalakrishnan 
Signed-off-by: Can Guo 
Signed-off-by: Asutosh Das 
---
 drivers/scsi/ufs/ufshcd.c | 26 --
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 838ba8f0..dfeb194 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -6780,9 +6780,16 @@ static int __ufshcd_setup_clocks(struct ufs_hba
*hba, bool on,
if (list_empty(head))
goto out;

-   ret = ufshcd_vops_setup_clocks(hba, on, PRE_CHANGE);
-   if (ret)
-   return ret;
+   /*
+* vendor specific setup_clocks ops may depend on clocks managed by
+* this standard driver hence call the vendor specific setup_clocks
+* before disabling the clocks managed here.
+*/
+   if (!on) {
+   ret = ufshcd_vops_setup_clocks(hba, on, PRE_CHANGE);
+   if (ret)
+   return ret;
+   }

list_for_each_entry(clki, head, list) {
if (!IS_ERR_OR_NULL(clki->clk)) {
@@ -6806,9 +6813,16 @@ static int __ufshcd_setup_clocks(struct ufs_hba
*hba, bool on,
}
}

-   ret = ufshcd_vops_setup_clocks(hba, on, POST_CHANGE);
-   if (ret)
-   return ret;
+   /*
+* vendor specific setup_clocks ops may depend on clocks managed by
+* this standard driver hence call the vendor specific setup_clocks
+* after enabling the clocks managed here.
+*/
+   if (on) {
+   ret = ufshcd_vops_setup_clocks(hba, on, POST_CHANGE);
+   if (ret)
+   return ret;
+   }

 out:
if (ret) {


Looks good to me.

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


Re: [PATCH v2 04/10] scsi: ufs: fix exception event handling

2018-05-16 Thread Subhash Jadavani

On 2018-05-03 04:07, Asutosh Das wrote:

From: Maya Erez 

The device can set the exception event bit in one of the response UPIU,
for example to notify the need for urgent BKOPs operation.
In such a case the host driver calls ufshcd_exception_event_handler to
handle this notification.
When trying to check the exception event status (for finding the cause 
for
the exception event), the device may be busy with additional SCSI 
commands

handling and may not respond within the 100ms timeout.

To prevent that, we need to block SCSI commands during handling of
exception events and allow retransmissions of the query requests,
in case of timeout.

Signed-off-by: Subhash Jadavani 
Signed-off-by: Maya Erez 
Signed-off-by: Can Guo 
Signed-off-by: Asutosh Das 
---
 drivers/scsi/ufs/ufshcd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 6dabce8..838ba8f0 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -4967,6 +4967,7 @@ static void
ufshcd_exception_event_handler(struct work_struct *work)
hba = container_of(work, struct ufs_hba, eeh_work);

pm_runtime_get_sync(hba->dev);
+   scsi_block_requests(hba->host);
err = ufshcd_get_ee_status(hba, );
if (err) {
dev_err(hba->dev, "%s: failed to get exception status %d\n",
@@ -4980,6 +4981,7 @@ static void
ufshcd_exception_event_handler(struct work_struct *work)
ufshcd_bkops_exception_event_handler(hba);

 out:
+   scsi_unblock_requests(hba->host);
pm_runtime_put_sync(hba->dev);
return;
 }


Looks good to me.
Reviewed-by: Subhash Jadavani 

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


Re: [PATCH v2 03/10] scsi: ufs: Add LCC quirk for host and device

2018-05-16 Thread Subhash Jadavani

On 2018-05-03 04:07, Asutosh Das wrote:

LCC (Line Control Command) is being used for communication between
UFS host and UFS device. But some hosts might have the issue with
issuing the LCC commands to UFS device and in this case LCC could be
explicitly disabled.

But there could be a need where we don't want to disable the LCC
on both host & device; hence this change splits the quirk in 2 parts
one for host and one for device.

Signed-off-by: Subhash Jadavani 
Signed-off-by: Venkat Gopalakrishnan 
Signed-off-by: Can Guo 
Signed-off-by: Asutosh Das 
---
 drivers/scsi/ufs/ufshcd.c | 16 
 drivers/scsi/ufs/ufshcd.h | 12 
 2 files changed, 28 insertions(+)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index f3083fe..6dabce8 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -4116,6 +4116,11 @@ static int ufshcd_disable_tx_lcc(struct ufs_hba
*hba, bool peer)
return err;
 }

+static inline int ufshcd_disable_host_tx_lcc(struct ufs_hba *hba)
+{
+   return ufshcd_disable_tx_lcc(hba, false);
+}
+
 static inline int ufshcd_disable_device_tx_lcc(struct ufs_hba *hba)
 {
return ufshcd_disable_tx_lcc(hba, true);
@@ -4172,6 +4177,17 @@ static int ufshcd_link_startup(struct ufs_hba 
*hba)

ufshcd_dme_set(hba, UIC_ARG_MIB(TX_LCC_ENABLE), 1);
}

+   if (hba->quirks & UFSHCD_BROKEN_LCC_PROCESSING_ON_HOST) {
+   ret = ufshcd_disable_device_tx_lcc(hba);
+   if (ret)
+   goto out;
+   }
+
+   if (hba->quirks & UFSHCD_BROKEN_LCC_PROCESSING_ON_DEVICE) {
+   ret = ufshcd_disable_host_tx_lcc(hba);
+   if (ret)
+   goto out;
+   }
if (link_startup_again) {
link_startup_again = false;
retries = DME_LINKSTARTUP_RETRIES;
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index bb4ecfb..0417c42 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -598,6 +598,18 @@ struct ufs_hba {
 * TX_LCC.
 */
#define UFSHCD_QUIRK_BROKEN_PWR_MODE_CHANGE UFS_BIT(8)
+
+   /*
+* If UFS device is having issue in processing LCC (Line Control
+* Command) coming from UFS host controller then enable this quirk.
+* When this quirk is enabled, host controller driver should disable
+* the LCC transmission on UFS host controller (by clearing
+* TX_LCC_ENABLE attribute of host to 0).
+*/
+   #define UFSHCD_BROKEN_LCC_PROCESSING_ON_DEVICE  0x100
+
+   #define UFSHCD_BROKEN_LCC_PROCESSING_ON_HOST0x200
+
unsigned int quirks;/* Deviations from standard UFSHCI spec. */

/* Device deviations from standard UFS device spec. */


Please check if these quirks are really needed for commercial version of 
UFS host controllers.


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


Re: [PATCH v2 02/10] scsi: ufs-qcom: Enable UFSHCD_QUIRK_BROKEN_PWR_MODE_CHANGE quirk

2018-05-16 Thread Subhash Jadavani

On 2018-05-03 04:07, Asutosh Das wrote:

Enable UFSHCD_QUIRK_BROKEN_PWR_MODE_CHANGE quirk to avoid failures
in seen on some UFS devices.

Signed-off-by: Asutosh Das 
---
 drivers/scsi/ufs/ufs-qcom.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index 4563d2e..d9edef8 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -1105,7 +1105,7 @@ static void ufs_qcom_advertise_quirks(struct 
ufs_hba *hba)


if (host->hw_ver.major >= 0x2) {
hba->quirks |= UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION;
-
+   hba->quirks |= UFSHCD_QUIRK_BROKEN_PWR_MODE_CHANGE;
if (!ufs_qcom_cap_qunipro(host))
/* Legacy UniPro mode still need following quirks */
hba->quirks |= (UFSHCD_QUIRK_DELAY_BEFORE_DME_CMDS


We may not need this.

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


Re: [PATCH v2 01/10] scsi: ufs: Allowing power mode change

2018-05-16 Thread Subhash Jadavani

On 2018-05-03 04:07, Asutosh Das wrote:

From: Yaniv Gardi 

Due to M-PHY issues, moving from HS to any other mode or gear or
even Hibern8 may cause some un-predicted behavior
of the device.
This patch adds provides a quirk to address that.

Signed-off-by: Yaniv Gardi 
Signed-off-by: Subhash Jadavani 
Signed-off-by: Can Guo 
Signed-off-by: Asutosh Das 
---
 drivers/scsi/ufs/ufshcd.c | 8 +++-
 drivers/scsi/ufs/ufshcd.h | 7 +++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 5bc9dc1..f3083fe 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -4162,9 +4162,15 @@ static int ufshcd_link_startup(struct ufs_hba 
*hba)

goto out;
} while (ret && retries--);

-   if (ret)
+   if (ret) {
/* failed to get the link up... retire */
goto out;
+   }
+
+   if (hba->quirks & UFSHCD_QUIRK_BROKEN_PWR_MODE_CHANGE) {
+   ufshcd_dme_set(hba, UIC_ARG_MIB(TX_LCC_ENABLE), 0);
+   ufshcd_dme_set(hba, UIC_ARG_MIB(TX_LCC_ENABLE), 1);
+   }

if (link_startup_again) {
link_startup_again = false;
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index cbe46f6..bb4ecfb 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -591,6 +591,13 @@ struct ufs_hba {
 */
#define UFSHCD_QUIRK_PRDT_BYTE_GRAN UFS_BIT(7)

+   /*
+	 * Needs to be enabled if moving from HS to any other gear/mode or 
even

+* hibern8 causes unpredicted behavior of device.
+* If this quirk is enabled, standard UFS driver will disable/enable
+* TX_LCC.
+*/
+   #define UFSHCD_QUIRK_BROKEN_PWR_MODE_CHANGE UFS_BIT(8)
unsigned int quirks;/* Deviations from standard UFSHCI spec. */

/* Device deviations from standard UFS device spec. */


This was probably needed in early generation of UFS devices (non 
commercial) and may not be really needed now. I believe we can skip this 
patch.


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


Re: [PATCH] scsi: ufs: ufshcd: Remove VLA usage

2018-05-16 Thread Subhash Jadavani

On 2018-05-02 16:58, Kees Cook wrote:

On the quest to remove all VLAs from the kernel[1] this moves buffers
off the stack. In the second instance, this collapses two separately
allocated buffers into a single buffer, since they are used 
consecutively,

which saves 256 bytes (QUERY_DESC_MAX_SIZE + 1) of stack space.

[1]
https://lkml.kernel.org/r/CA+55aFzCG-zNmZwX4A2FQpadafLfEzK6CC=qpxydaacu1rq...@mail.gmail.com

Signed-off-by: Kees Cook 
---
 drivers/scsi/ufs/ufshcd.c | 34 ++
 1 file changed, 26 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 00e79057f870..a271534362f6 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -5958,14 +5958,18 @@ static void ufshcd_init_icc_levels(struct 
ufs_hba *hba)

 {
int ret;
int buff_len = hba->desc_size.pwr_desc;
-   u8 desc_buf[hba->desc_size.pwr_desc];
+   u8 *desc_buf;
+
+   desc_buf = kmalloc(buff_len, GFP_KERNEL);
+   if (!desc_buf)
+   return;

ret = ufshcd_read_power_desc(hba, desc_buf, buff_len);
if (ret) {
dev_err(hba->dev,
"%s: Failed reading power descriptor.len = %d ret = %d",
__func__, buff_len, ret);
-   return;
+   goto out;
}

hba->init_prefetch_data.icc_level =
@@ -5983,6 +5987,8 @@ static void ufshcd_init_icc_levels(struct ufs_hba 
*hba)

"%s: Failed configuring bActiveICCLevel = %d ret = %d",
__func__, hba->init_prefetch_data.icc_level , ret);

+out:
+   kfree(desc_buf);
 }

 /**
@@ -6052,9 +6058,17 @@ static int ufs_get_device_desc(struct ufs_hba 
*hba,

   struct ufs_dev_desc *dev_desc)
 {
int err;
+   size_t buff_len;
u8 model_index;
-   u8 str_desc_buf[QUERY_DESC_MAX_SIZE + 1] = {0};
-   u8 desc_buf[hba->desc_size.dev_desc];
+   u8 *desc_buf;
+
+   buff_len = max_t(size_t, hba->desc_size.dev_desc,
+QUERY_DESC_MAX_SIZE + 1);
+   desc_buf = kmalloc(buff_len, GFP_KERNEL);
+   if (!desc_buf) {
+   err = -ENOMEM;
+   goto out;
+   }

 	err = ufshcd_read_device_desc(hba, desc_buf, 
hba->desc_size.dev_desc);

if (err) {
@@ -6072,7 +6086,10 @@ static int ufs_get_device_desc(struct ufs_hba 
*hba,


model_index = desc_buf[DEVICE_DESC_PARAM_PRDCT_NAME];

-   err = ufshcd_read_string_desc(hba, model_index, str_desc_buf,
+   /* Zero-pad entire buffer for string termination. */
+   memset(desc_buf, 0, buff_len);
+
+   err = ufshcd_read_string_desc(hba, model_index, desc_buf,
  QUERY_DESC_MAX_SIZE, true/*ASCII*/);
if (err) {
dev_err(hba->dev, "%s: Failed reading Product Name. err = %d\n",
@@ -6080,15 +6097,16 @@ static int ufs_get_device_desc(struct ufs_hba 
*hba,

goto out;
}

-   str_desc_buf[QUERY_DESC_MAX_SIZE] = '\0';
-   strlcpy(dev_desc->model, (str_desc_buf + QUERY_DESC_HDR_SIZE),
-   min_t(u8, str_desc_buf[QUERY_DESC_LENGTH_OFFSET],
+   desc_buf[QUERY_DESC_MAX_SIZE] = '\0';
+   strlcpy(dev_desc->model, (desc_buf + QUERY_DESC_HDR_SIZE),
+   min_t(u8, desc_buf[QUERY_DESC_LENGTH_OFFSET],
  MAX_MODEL_LEN));

/* Null terminate the model string */
dev_desc->model[MAX_MODEL_LEN] = '\0';

 out:
+   kfree(desc_buf);
return err;
 }

--
2.17.0



Looks good to me.
Reviewed-by: Subhash Jadavani 

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


Re: [PATCH 7/7] cxlflash: Isolate external module dependencies

2018-05-16 Thread Matthew R. Ochs
On Fri, May 11, 2018 at 02:06:19PM -0500, Uma Krishnan wrote:
> Depending on the underlying transport, cxlflash has a dependency on either
> the CXL or OCXL drivers, which are enabled via their Kconfig option.
> Instead of having a module wide dependency on these config options, it is
> better to isolate the object modules that are dependent on the CXL and OCXL
> drivers and adjust the module dependencies accordingly.
> 
> This commit isolates the object files that are dependent on CXL and/or
> OCXL. The cxl/ocxl fops used in the core driver are tucked under an ifdef
> to avoid compilation errors.
> 
> Signed-off-by: Uma Krishnan 

Acked-by: Matthew R. Ochs 



Re: [PATCH 6/7] cxlflash: Abstract hardware dependent assignments

2018-05-16 Thread Matthew R. Ochs
On Fri, May 11, 2018 at 02:06:05PM -0500, Uma Krishnan wrote:
> As a staging cleanup to support transport specific builds of the cxlflash
> module, relocate device dependent assignments to header files. This will
> avoid littering the core driver with conditional compilation logic.
> 
> Signed-off-by: Uma Krishnan 

Acked-by: Matthew R. Ochs 



Re: [PATCH 5/7] cxlflash: Add include guards to backend.h

2018-05-16 Thread Matthew R. Ochs
On Fri, May 11, 2018 at 02:05:51PM -0500, Uma Krishnan wrote:
> The new header file, backend.h, that was recently added is missing
> the include guards. This commit adds the guards.
> 
> Signed-off-by: Uma Krishnan 

Acked-by: Matthew R. Ochs 



Re: [PATCH 3/7] cxlflash: Acquire semaphore before invoking ioctl services

2018-05-16 Thread Matthew R. Ochs
On Fri, May 11, 2018 at 02:05:22PM -0500, Uma Krishnan wrote:
> When a superpipe process that makes use of virtual LUNs is terminated or
> killed abruptly, there is a possibility that the cxlflash driver could
> hang and deprive other operations on the adapter.
> 
> The release fop registered to be invoked on a context close, detaches
> every LUN associated with the context. The underlying service to detach
> the LUN assumes it has been called with the read semaphore held, and
> releases the semaphore before any operation that could be time consuming.
> 
> When invoked without holding the read semaphore, an opportunity is created
> for the semaphore's count to become negative when it is temporarily
> released during one of these potential lengthy operations. This negative
> count results in subsequent acquisition attempts taking forever, leading
> to the hang.
> 
> To support the current design point of holding the semaphore on the
> ioctl() paths, the release fop should acquire it before invoking any
> ioctl services.
> 
> Signed-off-by: Uma Krishnan 

Acked-by: Matthew R. Ochs 



Re: [PATCH 2/7] cxlflash: Limit the debug logs in the IO path

2018-05-16 Thread Matthew R. Ochs
On Fri, May 11, 2018 at 02:05:08PM -0500, Uma Krishnan wrote:
> The kernel log can get filled with debug messages from send_cmd_ioarrin()
> when dynamic debug is enabled for the cxlflash module and there is a lot
> of legacy I/O traffic.
> 
> While these messages are necessary to debug issues that involve command
> tracking, the abundance of data can overwrite other useful data in the
> log. The best option available is to limit the messages that should
> serve most of the common use cases.
> 
> Signed-off-by: Uma Krishnan 

Acked-by: Matthew R. Ochs 



Re: [PATCH 1/7] cxlflash: Yield to active send threads

2018-05-16 Thread Matthew R. Ochs
On Fri, May 11, 2018 at 02:04:46PM -0500, Uma Krishnan wrote:
> The following Oops may be encountered if the device is reset, i.e. EEH
> recovery, while there is heavy I/O traffic:
> 
> 59:mon> t
> [c000200db64bb680] c00809264c40 cxlflash_queuecommand+0x3b8/0x500
>   [cxlflash]
> [c000200db64bb770] c090d3b0 scsi_dispatch_cmd+0x130/0x2f0
> [c000200db64bb7f0] c090fdd8 scsi_request_fn+0x3c8/0x8d0
> [c000200db64bb900] c067f528 __blk_run_queue+0x68/0xb0
> [c000200db64bb930] c067ab80 __elv_add_request+0x140/0x3c0
> [c000200db64bb9b0] c068daac blk_execute_rq_nowait+0xec/0x1a0
> [c000200db64bba00] c068dbb0 blk_execute_rq+0x50/0xe0
> [c000200db64bba50] c06b2040 sg_io+0x1f0/0x520
> [c000200db64bbaf0] c06b2e94 scsi_cmd_ioctl+0x534/0x610
> [c000200db64bbc20] c0926208 sd_ioctl+0x118/0x280
> [c000200db64bbcc0] c069f7ac blkdev_ioctl+0x7fc/0xe30
> [c000200db64bbd20] c0439204 block_ioctl+0x84/0xa0
> [c000200db64bbd40] c03f8514 do_vfs_ioctl+0xd4/0xa00
> [c000200db64bbde0] c03f8f04 SyS_ioctl+0xc4/0x130
> [c000200db64bbe30] c000b184 system_call+0x58/0x6c
> 
> When there is no room to send the I/O request, the cached room is refreshed
> by reading the memory mapped command room value from the AFU. The AFU
> register mapping is refreshed during a reset, creating a race condition
> that can lead to the Oops above.
> 
> During a device reset, the AFU should not be unmapped until all the active
> send threads quiesce. An atomic counter, cmds_active, is currently used to
> track internal AFU commands and quiesce during reset. This same counter can
> also be used for the active send threads.
> 
> Signed-off-by: Uma Krishnan 

Acked-by: Matthew R. Ochs 



Re: simplify procfs code for seq_file instances V3

2018-05-16 Thread Al Viro
On Wed, May 16, 2018 at 11:43:04AM +0200, Christoph Hellwig wrote:
> We currently have hundreds of proc files that implement plain, read-only
> seq_file based interfaces.  This series consolidates them using new
> procfs helpers that take the seq_operations or simple show callback
> directly.
> 
> A git tree is available at:
> 
> git://git.infradead.org/users/hch/misc.git proc_create.3

Pulled, but the last bit is a bleeding atrocity in need of followup
cleanup.


Re: [Jfs-discussion] [PATCH 25/42] jfs: simplify procfs code

2018-05-16 Thread Dave Kleikamp
On 05/16/2018 04:43 AM, Christoph Hellwig wrote:
> Use remove_proc_subtree to remove the whole subtree on cleanup, and
> unwind the registration loop into individual calls.  Switch to use
> proc_create_seq where applicable.
> 
> Signed-off-by: Christoph Hellwig 

Acked-by:  Dave Kleikamp 

> ---
>  fs/jfs/jfs_debug.c| 43 ++-
>  fs/jfs/jfs_debug.h| 10 +-
>  fs/jfs/jfs_logmgr.c   | 14 +-
>  fs/jfs/jfs_metapage.c | 14 +-
>  fs/jfs/jfs_txnmgr.c   | 28 ++--
>  fs/jfs/jfs_xtree.c| 14 +-
>  6 files changed, 24 insertions(+), 99 deletions(-)
> 
> diff --git a/fs/jfs/jfs_debug.c b/fs/jfs/jfs_debug.c
> index a70907606025..35a5b2a81ae0 100644
> --- a/fs/jfs/jfs_debug.c
> +++ b/fs/jfs/jfs_debug.c
> @@ -29,7 +29,6 @@
>  
>  #ifdef PROC_FS_JFS /* see jfs_debug.h */
>  
> -static struct proc_dir_entry *base;
>  #ifdef CONFIG_JFS_DEBUG
>  static int jfs_loglevel_proc_show(struct seq_file *m, void *v)
>  {
> @@ -66,43 +65,29 @@ static const struct file_operations 
> jfs_loglevel_proc_fops = {
>  };
>  #endif
>  
> -static struct {
> - const char  *name;
> - const struct file_operations *proc_fops;
> -} Entries[] = {
> -#ifdef CONFIG_JFS_STATISTICS
> - { "lmstats",_lmstats_proc_fops, },
> - { "txstats",_txstats_proc_fops, },
> - { "xtstat", _xtstat_proc_fops, },
> - { "mpstat", _mpstat_proc_fops, },
> -#endif
> -#ifdef CONFIG_JFS_DEBUG
> - { "TxAnchor",   _txanchor_proc_fops, },
> - { "loglevel",   _loglevel_proc_fops }
> -#endif
> -};
> -#define NPROCENT ARRAY_SIZE(Entries)
> -
>  void jfs_proc_init(void)
>  {
> - int i;
> + struct proc_dir_entry *base;
>  
> - if (!(base = proc_mkdir("fs/jfs", NULL)))
> + base = proc_mkdir("fs/jfs", NULL);
> + if (!base)
>   return;
>  
> - for (i = 0; i < NPROCENT; i++)
> - proc_create(Entries[i].name, 0, base, Entries[i].proc_fops);
> +#ifdef CONFIG_JFS_STATISTICS
> + proc_create_single("lmstats", 0, base, jfs_lmstats_proc_show);
> + proc_create_single("txstats", 0, base, jfs_txstats_proc_show);
> + proc_create_single("xtstat", 0, base, jfs_xtstat_proc_show);
> + proc_create_single("mpstat", 0, base, jfs_mpstat_proc_show);
> +#endif
> +#ifdef CONFIG_JFS_DEBUG
> + proc_create_single("TxAnchor", 0, base, jfs_txanchor_proc_show);
> + proc_create("loglevel", 0, base, _loglevel_proc_fops);
> +#endif
>  }
>  
>  void jfs_proc_clean(void)
>  {
> - int i;
> -
> - if (base) {
> - for (i = 0; i < NPROCENT; i++)
> - remove_proc_entry(Entries[i].name, base);
> - remove_proc_entry("fs/jfs", NULL);
> - }
> + remove_proc_subtree("fs/jfs", NULL);
>  }
>  
>  #endif /* PROC_FS_JFS */
> diff --git a/fs/jfs/jfs_debug.h b/fs/jfs/jfs_debug.h
> index eafd1300a00b..0d9e35da8462 100644
> --- a/fs/jfs/jfs_debug.h
> +++ b/fs/jfs/jfs_debug.h
> @@ -62,7 +62,7 @@ extern void jfs_proc_clean(void);
>  
>  extern int jfsloglevel;
>  
> -extern const struct file_operations jfs_txanchor_proc_fops;
> +int jfs_txanchor_proc_show(struct seq_file *m, void *v);
>  
>  /* information message: e.g., configuration, major event */
>  #define jfs_info(fmt, arg...) do {   \
> @@ -105,10 +105,10 @@ extern const struct file_operations 
> jfs_txanchor_proc_fops;
>   *   --
>   */
>  #ifdef   CONFIG_JFS_STATISTICS
> -extern const struct file_operations jfs_lmstats_proc_fops;
> -extern const struct file_operations jfs_txstats_proc_fops;
> -extern const struct file_operations jfs_mpstat_proc_fops;
> -extern const struct file_operations jfs_xtstat_proc_fops;
> +int jfs_lmstats_proc_show(struct seq_file *m, void *v);
> +int jfs_txstats_proc_show(struct seq_file *m, void *v);
> +int jfs_mpstat_proc_show(struct seq_file *m, void *v);
> +int jfs_xtstat_proc_show(struct seq_file *m, void *v);
>  
>  #define  INCREMENT(x)((x)++)
>  #define  DECREMENT(x)((x)--)
> diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
> index 0e5d412c0b01..6b68df395892 100644
> --- a/fs/jfs/jfs_logmgr.c
> +++ b/fs/jfs/jfs_logmgr.c
> @@ -2493,7 +2493,7 @@ int lmLogFormat(struct jfs_log *log, s64 logAddress, 
> int logSize)
>  }
>  
>  #ifdef CONFIG_JFS_STATISTICS
> -static int jfs_lmstats_proc_show(struct seq_file *m, void *v)
> +int jfs_lmstats_proc_show(struct seq_file *m, void *v)
>  {
>   seq_printf(m,
>  "JFS Logmgr stats\n"
> @@ -2510,16 +2510,4 @@ static int jfs_lmstats_proc_show(struct seq_file *m, 
> void *v)
>  lmStat.partial_page);
>   return 0;
>  }
> -
> -static int jfs_lmstats_proc_open(struct inode *inode, struct file *file)
> -{
> - return single_open(file, jfs_lmstats_proc_show, NULL);
> -}
> -
> -const struct file_operations jfs_lmstats_proc_fops = {
> - .open   = 

Re: 答复: [PATCH v9 2/5] dt-bindings: scsi: ufs: add document for hisi-ufs

2018-05-16 Thread Rob Herring
On Tue, Apr 24, 2018 at 8:54 AM, liwei (CM)  wrote:
> Hi, Rob
>
> Thanks for your patience.
>
> Hi, Arnd
>
> From Rob's suggestion, we have to list the properties node in ufs-hisi.txt 
> bingings even if documented in the common binding.
>
> -邮件原件-
> 发件人: Rob Herring [mailto:r...@kernel.org]
> 发送时间: 2018年4月24日 20:58
> 收件人: liwei (CM)
> 抄送: mark.rutl...@arm.com; catalin.mari...@arm.com; will.dea...@arm.com; 
> vinholika...@gmail.com; j...@linux.vnet.ibm.com; martin.peter...@oracle.com; 
> khil...@baylibre.com; a...@arndb.de; gregory.clem...@free-electrons.com; 
> thomas.petazz...@free-electrons.com; yamada.masah...@socionext.com; 
> riku.voi...@linaro.org; tred...@nvidia.com; k...@kernel.org; 
> devicet...@vger.kernel.org; linux-ker...@vger.kernel.org; 
> linux-arm-ker...@lists.infradead.org; linux-scsi@vger.kernel.org; 
> zangleigang; Gengjianfeng; guodong...@linaro.org
> 主题: Re: [PATCH v9 2/5] dt-bindings: scsi: ufs: add document for hisi-ufs
>
> On Tue, Apr 17, 2018 at 10:08:11PM +0800, Li Wei wrote:
>> add ufs node document for Hisilicon.
>>
>> Signed-off-by: Li Wei 
>> ---
>>  Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 29 
>> ++
>>  .../devicetree/bindings/ufs/ufshcd-pltfrm.txt  | 10 +---
>>  2 files changed, 36 insertions(+), 3 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt
>>
>> diff --git a/Documentation/devicetree/bindings/ufs/ufs-hisi.txt 
>> b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt
>> new file mode 100644
>> index ..d49ab7d8f31d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt
>> @@ -0,0 +1,29 @@
>> +* Hisilicon Universal Flash Storage (UFS) Host Controller
>> +
>> +UFS nodes are defined to describe on-chip UFS hardware macro.
>> +Each UFS Host Controller should have its own node.
>> +
>> +Required properties:
>> +- compatible: compatible list, contains one of the following -
>> + "hisilicon,hi3660-ufs", 
>> "jedec,ufs-1.1" for hisi ufs
>> + host controller present on Hi36xx 
>> chipset.
>> +- reg   : should contain UFS register address space & UFS SYS 
>> CTRL register address,
>> +- interrupt-parent  : interrupt device
>> +- interrupts: interrupt number
>> +- resets: reset node register, the "arst" corresponds to reset 
>> the APB/AXI bus.
>
> arst belongs in reset-names.
>
> OK, I will fix it in next patch;
>
>> +- reset-names   : describe reset node register
>
> What happened to clocks? You still have to list which ones apply even if
> documented in the common binding.
>
> OK, I will fix it in next patch;
>
>> +
>> +Example:
>> +
>> + ufs: ufs@ff3b {
>> + compatible = "hisilicon,hi3660-ufs", "jedec,ufs-1.1";
>> + /* 0: HCI standard */
>> + /* 1: UFS SYS CTRL */
>> + reg = <0x0 0xff3b 0x0 0x1000>,
>> + <0x0 0xff3b1000 0x0 0x1000>;
>> + interrupt-parent = <>;
>> + interrupts = ;
>> + /* offset: 0x84; bit: 7  */
>> + resets = <_rst 0x84 7>;
>> + reset-names = "arst";
>> + };
>> diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt 
>> b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
>> index c39dfef76a18..adcfb79f63f5 100644
>> --- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
>> +++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
>> @@ -41,6 +41,8 @@ Optional properties:
>>  -lanes-per-direction : number of lanes available per direction - either 1 
>> or 2.
>> Note that it is assume same number of lanes is used 
>> both
>> directions at once. If not specified, default is 2 
>> lanes per direction.
>> +- resets: reset node register, the "rst" corresponds to reset 
>> the whole UFS IP.
>> +- reset-names   : describe reset node register
>
> Does your controller have 1 or 2 resets? There's no point in adding this
> here if it doesn't apply to your controller.
>
> There are 2 reset in our soc init, the "rst" corresponds to reset the whole 
> UFS IP, and " arst " only reset the APB/AXI bus.
> Discussed with our soc colleagues that "arst" is assert by default and needs 
> to deassert,but it done in bootloader,so will remove 'arst' in next patch.
>
> About the 'reset' property,it seems that Arnd Bergmann has different 
> suggestion,he suggested that add 'rst' to ufshcd-pltfrm because it seems 
> common.
> But it looks like only our soc init needs it. What's your opinion? Does it 
> still needs add to common bindings?

For a single reset, then I'm fine with it being in the common
bindings. If there are multiple then it should be in the specific
bindings as the reset names are likely different.

Rob


Re: [PATCH 1/2] Convert target drivers to use sbitmap

2018-05-16 Thread kbuild test robot
Hi Matthew,

I love your patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v4.17-rc5 next-20180516]
[cannot apply to target/master]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Matthew-Wilcox/Use-sbitmap-instead-of-percpu_ida/20180516-143658
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

>> drivers/target/iscsi/iscsi_target_util.c:150:5: sparse: symbol 
>> 'iscsit_wait_for_tag' was not declared. Should it be static?
   drivers/target/iscsi/iscsi_target_util.c:1174:31: sparse: expression using 
sizeof(void)
   drivers/target/iscsi/iscsi_target_util.c:1174:31: sparse: expression using 
sizeof(void)

Please review and possibly fold the followup patch.

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


[RFC PATCH] iscsit_wait_for_tag() can be static

2018-05-16 Thread kbuild test robot

Fixes: 5aff7a710f13 ("Convert target drivers to use sbitmap")
Signed-off-by: Fengguang Wu 
---
 iscsi_target_util.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/target/iscsi/iscsi_target_util.c 
b/drivers/target/iscsi/iscsi_target_util.c
index 28bcffa..e147aef 100644
--- a/drivers/target/iscsi/iscsi_target_util.c
+++ b/drivers/target/iscsi/iscsi_target_util.c
@@ -147,7 +147,7 @@ void iscsit_free_r2ts_from_list(struct iscsi_cmd *cmd)
spin_unlock_bh(>r2t_lock);
 }
 
-int iscsit_wait_for_tag(struct se_session *se_sess, int state, int *cpup)
+static int iscsit_wait_for_tag(struct se_session *se_sess, int state, int 
*cpup)
 {
int tag = -1;
DEFINE_WAIT(wait);


[PATCH 01/42] net/can: single_open_net needs to be paired with single_release_net

2018-05-16 Thread Christoph Hellwig
Otherwise we will leak a reference to the network namespace.

Signed-off-by: Christoph Hellwig 
---
 net/can/bcm.c  | 2 +-
 net/can/proc.c | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/can/bcm.c b/net/can/bcm.c
index ac5e5e34fee3..8073fa14e143 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -249,7 +249,7 @@ static const struct file_operations bcm_proc_fops = {
.open   = bcm_proc_open,
.read   = seq_read,
.llseek = seq_lseek,
-   .release= single_release,
+   .release= single_release_net,
 };
 #endif /* CONFIG_PROC_FS */
 
diff --git a/net/can/proc.c b/net/can/proc.c
index fdf704e9bb8c..fde2fd55b826 100644
--- a/net/can/proc.c
+++ b/net/can/proc.c
@@ -279,7 +279,7 @@ static const struct file_operations can_stats_proc_fops = {
.open   = can_stats_proc_open,
.read   = seq_read,
.llseek = seq_lseek,
-   .release= single_release,
+   .release= single_release_net,
 };
 
 static int can_reset_stats_proc_show(struct seq_file *m, void *v)
@@ -449,7 +449,7 @@ static const struct file_operations 
can_rcvlist_sff_proc_fops = {
.open   = can_rcvlist_sff_proc_open,
.read   = seq_read,
.llseek = seq_lseek,
-   .release= single_release,
+   .release= single_release_net,
 };
 
 
@@ -492,7 +492,7 @@ static const struct file_operations 
can_rcvlist_eff_proc_fops = {
.open   = can_rcvlist_eff_proc_open,
.read   = seq_read,
.llseek = seq_lseek,
-   .release= single_release,
+   .release= single_release_net,
 };
 
 /*
-- 
2.17.0



simplify procfs code for seq_file instances V3

2018-05-16 Thread Christoph Hellwig
We currently have hundreds of proc files that implement plain, read-only
seq_file based interfaces.  This series consolidates them using new
procfs helpers that take the seq_operations or simple show callback
directly.

A git tree is available at:

git://git.infradead.org/users/hch/misc.git proc_create.3

Gitweb:


http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/proc_create.3

Changes since V2:
 - use unsigned int for state_size everywhere
 - move state_size around in proc_dir_entry to use a struct packing hole
 - update SIZEOF_PDE_INLINE_NAME
 - added a new proc_pid_ns helper
 - improved a few changelogs
 - added back a nubus comment
 - minor typo fix
 - collected various ACKs

Changes since V1:
 - open code proc_create_data to avoid setting not fully initialized
   entries live
 - use unsigned int for state_size
 - dropped the s390/cio/blacklist hunk as it has a write method
 - dropped the IPMI patch given that IPMI proc support is scheduled for
   removal.


[PATCH 03/42] proc: don't detour through seq->private to get the inode

2018-05-16 Thread Christoph Hellwig
Signed-off-by: Christoph Hellwig 
---
 fs/proc/array.c | 20 ++--
 1 file changed, 6 insertions(+), 14 deletions(-)

diff --git a/fs/proc/array.c b/fs/proc/array.c
index 911f66924d81..4a8e413bf59b 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -677,20 +677,22 @@ get_children_pid(struct inode *inode, struct pid 
*pid_prev, loff_t pos)
 
 static int children_seq_show(struct seq_file *seq, void *v)
 {
-   seq_printf(seq, "%d ", pid_nr_ns(v, proc_pid_ns(seq->private)));
+   struct inode *inode = file_inode(seq->file);
+
+   seq_printf(seq, "%d ", pid_nr_ns(v, proc_pid_ns(inode)));
return 0;
 }
 
 static void *children_seq_start(struct seq_file *seq, loff_t *pos)
 {
-   return get_children_pid(seq->private, NULL, *pos);
+   return get_children_pid(file_inode(seq->file), NULL, *pos);
 }
 
 static void *children_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
struct pid *pid;
 
-   pid = get_children_pid(seq->private, v, *pos + 1);
+   pid = get_children_pid(file_inode(seq->file), v, *pos + 1);
put_pid(v);
 
++*pos;
@@ -711,17 +713,7 @@ static const struct seq_operations children_seq_ops = {
 
 static int children_seq_open(struct inode *inode, struct file *file)
 {
-   struct seq_file *m;
-   int ret;
-
-   ret = seq_open(file, _seq_ops);
-   if (ret)
-   return ret;
-
-   m = file->private_data;
-   m->private = inode;
-
-   return ret;
+   return seq_open(file, _seq_ops);
 }
 
 const struct file_operations proc_tid_children_operations = {
-- 
2.17.0



[PATCH 10/42] ipv{4,6}/tcp: simplify procfs registration

2018-05-16 Thread Christoph Hellwig
Avoid most of the afinfo indirections and just call the proc helpers
directly.

Signed-off-by: Christoph Hellwig 
---
 include/net/tcp.h   | 11 ++
 net/ipv4/tcp_ipv4.c | 85 +
 net/ipv6/tcp_ipv6.c | 27 +-
 3 files changed, 53 insertions(+), 70 deletions(-)

diff --git a/include/net/tcp.h b/include/net/tcp.h
index 9c9b3768b350..51dc7a26a2fa 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1747,27 +1747,22 @@ enum tcp_seq_states {
TCP_SEQ_STATE_ESTABLISHED,
 };
 
-int tcp_seq_open(struct inode *inode, struct file *file);
+void *tcp_seq_start(struct seq_file *seq, loff_t *pos);
+void *tcp_seq_next(struct seq_file *seq, void *v, loff_t *pos);
+void tcp_seq_stop(struct seq_file *seq, void *v);
 
 struct tcp_seq_afinfo {
-   char*name;
sa_family_t family;
-   const struct file_operations*seq_fops;
-   struct seq_operations   seq_ops;
 };
 
 struct tcp_iter_state {
struct seq_net_private  p;
-   sa_family_t family;
enum tcp_seq_states state;
struct sock *syn_wait_sk;
int bucket, offset, sbucket, num;
loff_t  last_pos;
 };
 
-int tcp_proc_register(struct net *net, struct tcp_seq_afinfo *afinfo);
-void tcp_proc_unregister(struct net *net, struct tcp_seq_afinfo *afinfo);
-
 extern struct request_sock_ops tcp_request_sock_ops;
 extern struct request_sock_ops tcp6_request_sock_ops;
 
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index f70586b50838..645f259d0972 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1961,6 +1961,7 @@ EXPORT_SYMBOL(tcp_v4_destroy_sock);
  */
 static void *listening_get_next(struct seq_file *seq, void *cur)
 {
+   struct tcp_seq_afinfo *afinfo = PDE_DATA(file_inode(seq->file));
struct tcp_iter_state *st = seq->private;
struct net *net = seq_file_net(seq);
struct inet_listen_hashbucket *ilb;
@@ -1983,7 +1984,7 @@ static void *listening_get_next(struct seq_file *seq, 
void *cur)
sk_for_each_from(sk) {
if (!net_eq(sock_net(sk), net))
continue;
-   if (sk->sk_family == st->family)
+   if (sk->sk_family == afinfo->family)
return sk;
}
spin_unlock(>lock);
@@ -2020,6 +2021,7 @@ static inline bool empty_bucket(const struct 
tcp_iter_state *st)
  */
 static void *established_get_first(struct seq_file *seq)
 {
+   struct tcp_seq_afinfo *afinfo = PDE_DATA(file_inode(seq->file));
struct tcp_iter_state *st = seq->private;
struct net *net = seq_file_net(seq);
void *rc = NULL;
@@ -2036,7 +2038,7 @@ static void *established_get_first(struct seq_file *seq)
 
spin_lock_bh(lock);
sk_nulls_for_each(sk, node, 
_hashinfo.ehash[st->bucket].chain) {
-   if (sk->sk_family != st->family ||
+   if (sk->sk_family != afinfo->family ||
!net_eq(sock_net(sk), net)) {
continue;
}
@@ -2051,6 +2053,7 @@ static void *established_get_first(struct seq_file *seq)
 
 static void *established_get_next(struct seq_file *seq, void *cur)
 {
+   struct tcp_seq_afinfo *afinfo = PDE_DATA(file_inode(seq->file));
struct sock *sk = cur;
struct hlist_nulls_node *node;
struct tcp_iter_state *st = seq->private;
@@ -2062,7 +2065,8 @@ static void *established_get_next(struct seq_file *seq, 
void *cur)
sk = sk_nulls_next(sk);
 
sk_nulls_for_each_from(sk, node) {
-   if (sk->sk_family == st->family && net_eq(sock_net(sk), net))
+   if (sk->sk_family == afinfo->family &&
+   net_eq(sock_net(sk), net))
return sk;
}
 
@@ -2135,7 +2139,7 @@ static void *tcp_seek_last_pos(struct seq_file *seq)
return rc;
 }
 
-static void *tcp_seq_start(struct seq_file *seq, loff_t *pos)
+void *tcp_seq_start(struct seq_file *seq, loff_t *pos)
 {
struct tcp_iter_state *st = seq->private;
void *rc;
@@ -2156,8 +2160,9 @@ static void *tcp_seq_start(struct seq_file *seq, loff_t 
*pos)
st->last_pos = *pos;
return rc;
 }
+EXPORT_SYMBOL(tcp_seq_start);
 
-static void *tcp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+void *tcp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
struct tcp_iter_state *st = seq->private;
void *rc = NULL;
@@ -2186,8 +2191,9 @@ static void *tcp_seq_next(struct seq_file *seq, void *v, 
loff_t *pos)
st->last_pos = *pos;
return rc;
 }
+EXPORT_SYMBOL(tcp_seq_next);
 
-static void tcp_seq_stop(struct seq_file *seq, void *v)
+void tcp_seq_stop(struct seq_file *seq, void *v)
 {
struct tcp_iter_state *st = seq->private;
 
@@ -2202,47 

[PATCH 08/42] proc: introduce proc_create_single{,_data}

2018-05-16 Thread Christoph Hellwig
Variants of proc_create{,_data} that directly take a seq_file show
callback and drastically reduces the boilerplate code in the callers.

All trivial callers converted over.

Signed-off-by: Christoph Hellwig 
---
 arch/arm/kernel/dma.c | 14 +---
 arch/arm/kernel/swp_emulate.c | 15 +---
 arch/arm/mach-rpc/ecard.c | 16 +---
 arch/ia64/kernel/palinfo.c| 16 +---
 arch/ia64/kernel/salinfo.c| 42 --
 arch/ia64/sn/kernel/sn2/prominfo_proc.c   | 32 +---
 arch/ia64/sn/kernel/sn2/sn_proc_fs.c  | 62 ++
 arch/m68k/kernel/setup_mm.c   | 14 +---
 arch/mips/pci/ops-pmcmsp.c| 28 +--
 arch/mips/sibyte/common/bus_watcher.c | 16 +---
 arch/parisc/kernel/pci-dma.c  | 17 +---
 arch/parisc/kernel/pdc_chassis.c  | 14 +---
 arch/powerpc/kernel/eeh.c | 14 +---
 arch/powerpc/kernel/rtas-proc.c   | 32 +---
 arch/powerpc/platforms/cell/spufs/sched.c | 14 +---
 arch/s390/kernel/sysinfo.c| 14 +---
 arch/sh/drivers/dma/dma-api.c | 14 +---
 arch/sparc/kernel/ioport.c| 19 +
 arch/um/drivers/ubd_kern.c| 16 +---
 arch/x86/kernel/apm_32.c  | 15 +---
 drivers/acpi/ac.c | 21 +
 drivers/acpi/button.c | 19 +
 drivers/block/DAC960.c| 49 ++-
 drivers/block/pktcdvd.c   | 14 +---
 drivers/block/ps3vram.c   | 17 +---
 drivers/char/apm-emulation.c  | 15 +---
 drivers/char/ds1620.c | 14 +---
 drivers/char/efirtc.c | 15 +---
 drivers/char/nvram.c  | 15 +---
 drivers/char/rtc.c| 19 +
 drivers/char/toshiba.c| 15 +---
 drivers/connector/connector.c | 15 +---
 drivers/input/misc/hp_sdc_rtc.c   | 14 +---
 drivers/isdn/capi/capi.c  | 30 +--
 drivers/isdn/capi/capidrv.c   | 15 +---
 drivers/isdn/hardware/eicon/diva_didd.c   | 17 +---
 drivers/isdn/hardware/eicon/divasi.c  | 17 +---
 drivers/macintosh/via-pmu.c   | 57 +++--
 drivers/media/pci/saa7164/saa7164-core.c  | 14 +---
 drivers/media/pci/zoran/videocodec.c  | 16 +---
 drivers/message/fusion/mptbase.c  | 57 +++--
 drivers/mtd/mtdcore.c | 14 +---
 drivers/net/wireless/atmel/atmel.c| 15 +---
 .../net/wireless/intersil/hostap/hostap_ap.c  | 16 +---
 drivers/net/wireless/ray_cs.c | 15 +---
 drivers/nubus/proc.c  | 51 ++--
 drivers/parisc/ccio-dma.c | 34 +---
 drivers/parisc/sba_iommu.c| 32 +---
 drivers/platform/x86/toshiba_acpi.c   | 17 +---
 drivers/pnp/pnpbios/proc.c| 78 ++
 drivers/staging/comedi/proc.c | 18 +---
 drivers/usb/gadget/udc/at91_udc.c | 16 +---
 drivers/usb/gadget/udc/fsl_udc_core.c | 18 +---
 drivers/usb/gadget/udc/goku_udc.c | 18 +---
 drivers/usb/gadget/udc/omap_udc.c | 15 +---
 drivers/video/fbdev/via/viafbdev.c| 17 +---
 fs/cifs/cifs_debug.c  | 15 +---
 fs/f2fs/sysfs.c   | 29 ++-
 fs/filesystems.c  | 14 +---
 fs/fscache/internal.h |  2 +-
 fs/fscache/proc.c |  4 +-
 fs/fscache/stats.c| 17 +---
 fs/proc/cmdline.c | 14 +---
 fs/proc/generic.c | 29 +++
 fs/proc/internal.h|  5 +-
 fs/proc/loadavg.c | 14 +---
 fs/proc/meminfo.c | 14 +---
 fs/proc/softirqs.c| 14 +---
 fs/proc/uptime.c  | 14 +---
 fs/proc/version.c | 14 +---
 fs/reiserfs/procfs.c  | 16 +---
 fs/xfs/xfs_stats.c| 31 +--
 include/linux/proc_fs.h   | 10 ++-
 kernel/cgroup/cgroup-internal.h   |  2 +-
 kernel/cgroup/cgroup-v1.c | 14 +---
 kernel/cgroup/cgroup.c|  2 +-
 kernel/dma.c  | 14 +---
 kernel/exec_domain.c  | 14 +---
 kernel/irq/proc.c | 82 +++
 kernel/locking/lockdep_proc.c | 16 +---
 net/8021q/vlanproc.c  | 21 +
 net/ipv4/ipconfig.c   | 14 

[PATCH 02/42] proc: introduce a proc_pid_ns helper

2018-05-16 Thread Christoph Hellwig
Factor out retrieving the per-sb pid namespaces from the sb private data
into an easier to understand helper.

Suggested-by: Eric W. Biederman 
Signed-off-by: Christoph Hellwig 
---
 fs/proc/array.c |  7 +--
 fs/proc/base.c  | 18 --
 fs/proc/self.c  |  4 ++--
 fs/proc/thread_self.c   |  4 ++--
 include/linux/proc_fs.h |  6 ++
 5 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/fs/proc/array.c b/fs/proc/array.c
index ae2c807fd719..911f66924d81 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -677,12 +677,7 @@ get_children_pid(struct inode *inode, struct pid 
*pid_prev, loff_t pos)
 
 static int children_seq_show(struct seq_file *seq, void *v)
 {
-   struct inode *inode = seq->private;
-   pid_t pid;
-
-   pid = pid_nr_ns(v, inode->i_sb->s_fs_info);
-   seq_printf(seq, "%d ", pid);
-
+   seq_printf(seq, "%d ", pid_nr_ns(v, proc_pid_ns(seq->private)));
return 0;
 }
 
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 1b2ede6abcdf..29237cad19fd 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -698,7 +698,7 @@ static bool has_pid_permissions(struct pid_namespace *pid,
 
 static int proc_pid_permission(struct inode *inode, int mask)
 {
-   struct pid_namespace *pid = inode->i_sb->s_fs_info;
+   struct pid_namespace *pid = proc_pid_ns(inode);
struct task_struct *task;
bool has_perms;
 
@@ -733,13 +733,11 @@ static const struct inode_operations 
proc_def_inode_operations = {
 static int proc_single_show(struct seq_file *m, void *v)
 {
struct inode *inode = m->private;
-   struct pid_namespace *ns;
-   struct pid *pid;
+   struct pid_namespace *ns = proc_pid_ns(inode);
+   struct pid *pid = proc_pid(inode);
struct task_struct *task;
int ret;
 
-   ns = inode->i_sb->s_fs_info;
-   pid = proc_pid(inode);
task = get_pid_task(pid, PIDTYPE_PID);
if (!task)
return -ESRCH;
@@ -1410,7 +1408,7 @@ static const struct file_operations 
proc_fail_nth_operations = {
 static int sched_show(struct seq_file *m, void *v)
 {
struct inode *inode = m->private;
-   struct pid_namespace *ns = inode->i_sb->s_fs_info;
+   struct pid_namespace *ns = proc_pid_ns(inode);
struct task_struct *p;
 
p = get_proc_task(inode);
@@ -1782,8 +1780,8 @@ int pid_getattr(const struct path *path, struct kstat 
*stat,
u32 request_mask, unsigned int query_flags)
 {
struct inode *inode = d_inode(path->dentry);
+   struct pid_namespace *pid = proc_pid_ns(inode);
struct task_struct *task;
-   struct pid_namespace *pid = path->dentry->d_sb->s_fs_info;
 
generic_fillattr(inode, stat);
 
@@ -2337,7 +2335,7 @@ static int proc_timers_open(struct inode *inode, struct 
file *file)
return -ENOMEM;
 
tp->pid = proc_pid(inode);
-   tp->ns = inode->i_sb->s_fs_info;
+   tp->ns = proc_pid_ns(inode);
return 0;
 }
 
@@ -3239,7 +3237,7 @@ static struct tgid_iter next_tgid(struct pid_namespace 
*ns, struct tgid_iter ite
 int proc_pid_readdir(struct file *file, struct dir_context *ctx)
 {
struct tgid_iter iter;
-   struct pid_namespace *ns = file_inode(file)->i_sb->s_fs_info;
+   struct pid_namespace *ns = proc_pid_ns(file_inode(file));
loff_t pos = ctx->pos;
 
if (pos >= PID_MAX_LIMIT + TGID_OFFSET)
@@ -3588,7 +3586,7 @@ static int proc_task_readdir(struct file *file, struct 
dir_context *ctx)
/* f_version caches the tgid value that the last readdir call couldn't
 * return. lseek aka telldir automagically resets f_version to 0.
 */
-   ns = inode->i_sb->s_fs_info;
+   ns = proc_pid_ns(inode);
tid = (int)file->f_version;
file->f_version = 0;
for (task = first_tid(proc_pid(inode), tid, ctx->pos - 2, ns);
diff --git a/fs/proc/self.c b/fs/proc/self.c
index 4d7d061696b3..127265e5c55f 100644
--- a/fs/proc/self.c
+++ b/fs/proc/self.c
@@ -12,7 +12,7 @@ static const char *proc_self_get_link(struct dentry *dentry,
  struct inode *inode,
  struct delayed_call *done)
 {
-   struct pid_namespace *ns = inode->i_sb->s_fs_info;
+   struct pid_namespace *ns = proc_pid_ns(inode);
pid_t tgid = task_tgid_nr_ns(current, ns);
char *name;
 
@@ -36,7 +36,7 @@ static unsigned self_inum __ro_after_init;
 int proc_setup_self(struct super_block *s)
 {
struct inode *root_inode = d_inode(s->s_root);
-   struct pid_namespace *ns = s->s_fs_info;
+   struct pid_namespace *ns = proc_pid_ns(root_inode);
struct dentry *self;

inode_lock(root_inode);
diff --git a/fs/proc/thread_self.c b/fs/proc/thread_self.c
index 9d2efaca499f..b905010ca9eb 100644
--- a/fs/proc/thread_self.c
+++ b/fs/proc/thread_self.c
@@ -12,7 +12,7 @@ static const char 

[PATCH 07/42] proc: introduce proc_create_seq_private

2018-05-16 Thread Christoph Hellwig
Variant of proc_create_data that directly take a struct seq_operations
argument + a private state size and drastically reduces the boilerplate
code in the callers.

All trivial callers converted over.

Signed-off-by: Christoph Hellwig 
---
 fs/locks.c | 16 ++--
 fs/proc/generic.c  |  9 ++---
 fs/proc/internal.h |  1 +
 include/linux/atalk.h  |  7 ++-
 include/linux/proc_fs.h|  9 ++---
 kernel/time/timer_list.c   | 16 ++--
 mm/vmalloc.c   | 18 +++---
 net/appletalk/aarp.c   | 20 +---
 net/appletalk/atalk_proc.c |  3 ++-
 net/atm/lec.c  | 15 ++-
 net/decnet/af_decnet.c | 17 +++--
 net/decnet/dn_route.c  | 19 +++
 12 files changed, 37 insertions(+), 113 deletions(-)

diff --git a/fs/locks.c b/fs/locks.c
index 62bbe8b31f26..05e211be8684 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -2788,22 +2788,10 @@ static const struct seq_operations locks_seq_operations 
= {
.show   = locks_show,
 };
 
-static int locks_open(struct inode *inode, struct file *filp)
-{
-   return seq_open_private(filp, _seq_operations,
-   sizeof(struct locks_iterator));
-}
-
-static const struct file_operations proc_locks_operations = {
-   .open   = locks_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= seq_release_private,
-};
-
 static int __init proc_locks_init(void)
 {
-   proc_create("locks", 0, NULL, _locks_operations);
+   proc_create_seq_private("locks", 0, NULL, _seq_operations,
+   sizeof(struct locks_iterator), NULL);
return 0;
 }
 fs_initcall(proc_locks_init);
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index af644caaaf85..f87cb0053387 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -560,6 +560,8 @@ static int proc_seq_open(struct inode *inode, struct file 
*file)
 {
struct proc_dir_entry *de = PDE(inode);
 
+   if (de->state_size)
+   return seq_open_private(file, de->seq_ops, de->state_size);
return seq_open(file, de->seq_ops);
 }
 
@@ -570,9 +572,9 @@ static const struct file_operations proc_seq_fops = {
.release= seq_release,
 };
 
-struct proc_dir_entry *proc_create_seq_data(const char *name, umode_t mode,
+struct proc_dir_entry *proc_create_seq_private(const char *name, umode_t mode,
struct proc_dir_entry *parent, const struct seq_operations *ops,
-   void *data)
+   unsigned int state_size, void *data)
 {
struct proc_dir_entry *p;
 
@@ -581,9 +583,10 @@ struct proc_dir_entry *proc_create_seq_data(const char 
*name, umode_t mode,
return NULL;
p->proc_fops = _seq_fops;
p->seq_ops = ops;
+   p->state_size = state_size;
return proc_register(parent, p);
 }
-EXPORT_SYMBOL(proc_create_seq_data);
+EXPORT_SYMBOL(proc_create_seq_private);
 
 void proc_set_size(struct proc_dir_entry *de, loff_t size)
 {
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 4fb01c5f9c1a..bcfe830ffd59 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -46,6 +46,7 @@ struct proc_dir_entry {
const struct file_operations *proc_fops;
const struct seq_operations *seq_ops;
void *data;
+   unsigned int state_size;
unsigned int low_ino;
nlink_t nlink;
kuid_t uid;
diff --git a/include/linux/atalk.h b/include/linux/atalk.h
index 40373920ea58..23f805562f4e 100644
--- a/include/linux/atalk.h
+++ b/include/linux/atalk.h
@@ -145,7 +145,12 @@ extern rwlock_t atalk_interfaces_lock;
 
 extern struct atalk_route atrtr_default;
 
-extern const struct file_operations atalk_seq_arp_fops;
+struct aarp_iter_state {
+   int bucket;
+   struct aarp_entry **table;
+};
+
+extern const struct seq_operations aarp_seq_ops;
 
 extern int sysctl_aarp_expiry_time;
 extern int sysctl_aarp_tick_time;
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index f368a896a8cb..314713a48817 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -25,11 +25,13 @@ extern struct proc_dir_entry *proc_mkdir_mode(const char *, 
umode_t,
  struct proc_dir_entry *);
 struct proc_dir_entry *proc_create_mount_point(const char *name);
 
-struct proc_dir_entry *proc_create_seq_data(const char *name, umode_t mode,
+struct proc_dir_entry *proc_create_seq_private(const char *name, umode_t mode,
struct proc_dir_entry *parent, const struct seq_operations *ops,
-   void *data);
+   unsigned int state_size, void *data);
+#define proc_create_seq_data(name, mode, parent, ops, data) \
+   proc_create_seq_private(name, mode, parent, ops, 0, data)
 #define proc_create_seq(name, mode, parent, ops) \
-   proc_create_seq_data(name, mode, 

[PATCH 06/42] proc: introduce proc_create_seq{,_data}

2018-05-16 Thread Christoph Hellwig
Variants of proc_create{,_data} that directly take a struct seq_operations
argument and drastically reduces the boilerplate code in the callers.

All trivial callers converted over.

Signed-off-by: Christoph Hellwig 
---
 arch/ia64/hp/common/sba_iommu.c  | 15 +-
 arch/ia64/kernel/perfmon.c   | 16 +--
 arch/s390/kernel/sysinfo.c   | 14 +-
 block/genhd.c| 28 +--
 crypto/proc.c| 14 +-
 drivers/char/misc.c  | 15 +-
 drivers/isdn/capi/kcapi_proc.c   | 80 ++--
 drivers/net/hamradio/bpqether.c  | 16 +--
 drivers/net/hamradio/scc.c   | 17 +--
 drivers/net/hamradio/yam.c   | 16 +--
 drivers/pci/proc.c   | 17 +--
 drivers/s390/block/dasd_proc.c   | 17 +--
 drivers/s390/char/tape_proc.c| 19 +---
 drivers/staging/ipx/ipx_proc.c   | 45 ++
 drivers/tty/tty_ldisc.c  | 15 +-
 drivers/video/fbdev/core/fbmem.c | 15 +-
 drivers/zorro/proc.c | 17 +--
 fs/cachefiles/proc.c | 19 +---
 fs/fscache/histogram.c   | 17 +--
 fs/fscache/internal.h|  3 +-
 fs/fscache/proc.c|  4 +-
 fs/proc/consoles.c   | 14 +-
 fs/proc/devices.c| 14 +-
 fs/proc/generic.c| 30 
 fs/proc/internal.h   |  1 +
 fs/proc/interrupts.c | 14 +-
 fs/proc/nommu.c  | 14 +-
 fs/proc/proc_tty.c   | 16 +--
 include/linux/proc_fs.h  |  9 
 include/linux/tty.h  |  3 +-
 include/net/ax25.h   |  5 +-
 include/net/netrom.h |  5 +-
 include/net/rose.h   |  6 +--
 kernel/locking/lockdep_proc.c| 29 +---
 kernel/sched/debug.c | 28 +--
 kernel/sched/stats.c | 15 +-
 mm/vmalloc.c | 11 +++--
 mm/vmstat.c  | 56 ++
 net/appletalk/atalk_proc.c   | 48 +++
 net/atm/br2684.c | 14 +-
 net/ax25/af_ax25.c   | 21 ++---
 net/ax25/ax25_route.c| 15 +-
 net/ax25/ax25_uid.c  | 15 +-
 net/core/net-procfs.c| 16 +--
 net/decnet/dn_dev.c  | 15 +-
 net/llc/llc_proc.c   | 28 +--
 net/netrom/af_netrom.c   | 18 ++-
 net/netrom/nr_route.c| 29 +---
 net/rose/af_rose.c   | 26 +++
 net/rose/rose_route.c| 44 ++
 net/sctp/objcnt.c| 16 +--
 net/x25/x25_proc.c   | 48 +++
 security/keys/proc.c | 34 +-
 53 files changed, 151 insertions(+), 925 deletions(-)

diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index aec4a3354abe..cb5cd86a5530 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -1942,19 +1942,6 @@ static const struct seq_operations ioc_seq_ops = {
.show  = ioc_show
 };
 
-static int
-ioc_open(struct inode *inode, struct file *file)
-{
-   return seq_open(file, _seq_ops);
-}
-
-static const struct file_operations ioc_fops = {
-   .open= ioc_open,
-   .read= seq_read,
-   .llseek  = seq_lseek,
-   .release = seq_release
-};
-
 static void __init
 ioc_proc_init(void)
 {
@@ -1964,7 +1951,7 @@ ioc_proc_init(void)
if (!dir)
return;
 
-   proc_create(ioc_list->name, 0, dir, _fops);
+   proc_create_seq(ioc_list->name, 0, dir, _seq_ops);
 }
 #endif
 
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 8fb280e33114..3b38c717008a 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -5708,13 +5708,6 @@ const struct seq_operations pfm_seq_ops = {
.show = pfm_proc_show
 };
 
-static int
-pfm_proc_open(struct inode *inode, struct file *file)
-{
-   return seq_open(file, _seq_ops);
-}
-
-
 /*
  * we come here as soon as local_cpu_data->pfm_syst_wide is set. this happens
  * during pfm_enable() hence before pfm_start(). We cannot assume monitoring
@@ -6537,13 +6530,6 @@ pfm_probe_pmu(void)
return 0;
 }
 
-static const struct file_operations pfm_proc_fops = {
-   .open   = pfm_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= seq_release,
-};
-
 int __init
 pfm_init(void)
 {
@@ -6615,7 +6601,7 @@ pfm_init(void)
/*
 * create /proc/perfmon (mostly for debugging purposes)
 */
-   perfmon_dir = proc_create("perfmon", S_IRUGO, NULL, _proc_fops);
+   perfmon_dir = proc_create_seq("perfmon", S_IRUGO, NULL, _seq_ops);
if (perfmon_dir == NULL) {
printk(KERN_ERR "perfmon: cannot create /proc entry, perfmon 
disabled\n");
pmu_conf = 

[PATCH 09/42] ipv{4,6}/udp{,lite}: simplify proc registration

2018-05-16 Thread Christoph Hellwig
Remove a couple indirections to make the code look like most other
protocols.

Signed-off-by: Christoph Hellwig 
---
 include/net/udp.h  | 20 --
 net/ipv4/udp.c | 99 +-
 net/ipv4/udplite.c | 21 +++---
 net/ipv6/udp.c | 30 +-
 net/ipv6/udplite.c | 21 +++---
 5 files changed, 78 insertions(+), 113 deletions(-)

diff --git a/include/net/udp.h b/include/net/udp.h
index 0676b272f6ac..093cd323f66a 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -408,31 +408,27 @@ do {  
\
 #define __UDPX_INC_STATS(sk, field) __UDP_INC_STATS(sock_net(sk), field, 0)
 #endif
 
-/* /proc */
-int udp_seq_open(struct inode *inode, struct file *file);
-
+#ifdef CONFIG_PROC_FS
 struct udp_seq_afinfo {
-   char*name;
sa_family_t family;
struct udp_table*udp_table;
-   const struct file_operations*seq_fops;
-   struct seq_operations   seq_ops;
 };
 
 struct udp_iter_state {
struct seq_net_private  p;
-   sa_family_t family;
int bucket;
-   struct udp_table*udp_table;
 };
 
-#ifdef CONFIG_PROC_FS
-int udp_proc_register(struct net *net, struct udp_seq_afinfo *afinfo);
-void udp_proc_unregister(struct net *net, struct udp_seq_afinfo *afinfo);
+void *udp_seq_start(struct seq_file *seq, loff_t *pos);
+void *udp_seq_next(struct seq_file *seq, void *v, loff_t *pos);
+void udp_seq_stop(struct seq_file *seq, void *v);
+
+extern const struct file_operations udp_afinfo_seq_fops;
+extern const struct file_operations udp6_afinfo_seq_fops;
 
 int udp4_proc_init(void);
 void udp4_proc_exit(void);
-#endif
+#endif /* CONFIG_PROC_FS */
 
 int udpv4_offload_init(void);
 
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index b61a770884fa..51559a8c6e57 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2582,12 +2582,13 @@ EXPORT_SYMBOL(udp_prot);
 static struct sock *udp_get_first(struct seq_file *seq, int start)
 {
struct sock *sk;
+   struct udp_seq_afinfo *afinfo = PDE_DATA(file_inode(seq->file));
struct udp_iter_state *state = seq->private;
struct net *net = seq_file_net(seq);
 
-   for (state->bucket = start; state->bucket <= state->udp_table->mask;
+   for (state->bucket = start; state->bucket <= afinfo->udp_table->mask;
 ++state->bucket) {
-   struct udp_hslot *hslot = 
>udp_table->hash[state->bucket];
+   struct udp_hslot *hslot = 
>udp_table->hash[state->bucket];
 
if (hlist_empty(>head))
continue;
@@ -2596,7 +2597,7 @@ static struct sock *udp_get_first(struct seq_file *seq, 
int start)
sk_for_each(sk, >head) {
if (!net_eq(sock_net(sk), net))
continue;
-   if (sk->sk_family == state->family)
+   if (sk->sk_family == afinfo->family)
goto found;
}
spin_unlock_bh(>lock);
@@ -2608,16 +2609,17 @@ static struct sock *udp_get_first(struct seq_file *seq, 
int start)
 
 static struct sock *udp_get_next(struct seq_file *seq, struct sock *sk)
 {
+   struct udp_seq_afinfo *afinfo = PDE_DATA(file_inode(seq->file));
struct udp_iter_state *state = seq->private;
struct net *net = seq_file_net(seq);
 
do {
sk = sk_next(sk);
-   } while (sk && (!net_eq(sock_net(sk), net) || sk->sk_family != 
state->family));
+   } while (sk && (!net_eq(sock_net(sk), net) || sk->sk_family != 
afinfo->family));
 
if (!sk) {
-   if (state->bucket <= state->udp_table->mask)
-   
spin_unlock_bh(>udp_table->hash[state->bucket].lock);
+   if (state->bucket <= afinfo->udp_table->mask)
+   
spin_unlock_bh(>udp_table->hash[state->bucket].lock);
return udp_get_first(seq, state->bucket + 1);
}
return sk;
@@ -2633,15 +2635,16 @@ static struct sock *udp_get_idx(struct seq_file *seq, 
loff_t pos)
return pos ? NULL : sk;
 }
 
-static void *udp_seq_start(struct seq_file *seq, loff_t *pos)
+void *udp_seq_start(struct seq_file *seq, loff_t *pos)
 {
struct udp_iter_state *state = seq->private;
state->bucket = MAX_UDP_PORTS;
 
return *pos ? udp_get_idx(seq, *pos-1) : SEQ_START_TOKEN;
 }
+EXPORT_SYMBOL(udp_seq_start);
 
-static void *udp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+void *udp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
struct sock *sk;
 
@@ -2653,56 +2656,17 @@ static void *udp_seq_next(struct seq_file *seq, void 
*v, loff_t *pos)
++*pos;
return sk;
 }
+EXPORT_SYMBOL(udp_seq_next);
 
-static void udp_seq_stop(struct seq_file *seq, void *v)
+void 

[PATCH 04/42] proc: simplify proc_register calling conventions

2018-05-16 Thread Christoph Hellwig
Return registered entry on success, return NULL on failure and free the
passed in entry.  Also expose it in internal.h as we'll start using it
in proc_net.c soon.

Signed-off-by: Christoph Hellwig 
---
 fs/proc/generic.c  | 44 ++--
 fs/proc/internal.h |  2 ++
 2 files changed, 20 insertions(+), 26 deletions(-)

diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 2078e70e1595..bd8480ff0d35 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -346,13 +346,12 @@ static const struct inode_operations 
proc_dir_inode_operations = {
.setattr= proc_notify_change,
 };
 
-static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * 
dp)
+/* returns the registered entry, or frees dp and returns NULL on failure */
+struct proc_dir_entry *proc_register(struct proc_dir_entry *dir,
+   struct proc_dir_entry *dp)
 {
-   int ret;
-
-   ret = proc_alloc_inum(>low_ino);
-   if (ret)
-   return ret;
+   if (proc_alloc_inum(>low_ino))
+   goto out_free_entry;
 
write_lock(_subdir_lock);
dp->parent = dir;
@@ -360,12 +359,16 @@ static int proc_register(struct proc_dir_entry * dir, 
struct proc_dir_entry * dp
WARN(1, "proc_dir_entry '%s/%s' already registered\n",
 dir->name, dp->name);
write_unlock(_subdir_lock);
-   proc_free_inum(dp->low_ino);
-   return -EEXIST;
+   goto out_free_inum;
}
write_unlock(_subdir_lock);
 
-   return 0;
+   return dp;
+out_free_inum:
+   proc_free_inum(dp->low_ino);
+out_free_entry:
+   pde_free(dp);
+   return NULL;
 }
 
 static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent,
@@ -443,10 +446,7 @@ struct proc_dir_entry *proc_symlink(const char *name,
if (ent->data) {
strcpy((char*)ent->data,dest);
ent->proc_iops = _link_inode_operations;
-   if (proc_register(parent, ent) < 0) {
-   pde_free(ent);
-   ent = NULL;
-   }
+   ent = proc_register(parent, ent);
} else {
pde_free(ent);
ent = NULL;
@@ -470,11 +470,9 @@ struct proc_dir_entry *proc_mkdir_data(const char *name, 
umode_t mode,
ent->proc_fops = _dir_operations;
ent->proc_iops = _dir_inode_operations;
parent->nlink++;
-   if (proc_register(parent, ent) < 0) {
-   pde_free(ent);
+   ent = proc_register(parent, ent);
+   if (!ent)
parent->nlink--;
-   ent = NULL;
-   }
}
return ent;
 }
@@ -505,11 +503,9 @@ struct proc_dir_entry *proc_create_mount_point(const char 
*name)
ent->proc_fops = NULL;
ent->proc_iops = NULL;
parent->nlink++;
-   if (proc_register(parent, ent) < 0) {
-   pde_free(ent);
+   ent = proc_register(parent, ent);
+   if (!ent)
parent->nlink--;
-   ent = NULL;
-   }
}
return ent;
 }
@@ -539,11 +535,7 @@ struct proc_dir_entry *proc_create_data(const char *name, 
umode_t mode,
pde->proc_fops = proc_fops;
pde->data = data;
pde->proc_iops = _file_inode_operations;
-   if (proc_register(parent, pde) < 0)
-   goto out_free;
-   return pde;
-out_free:
-   pde_free(pde);
+   return proc_register(parent, pde);
 out:
return NULL;
 }
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 0f1692e63cb6..488e67490312 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -162,6 +162,8 @@ extern bool proc_fill_cache(struct file *, struct 
dir_context *, const char *, i
 /*
  * generic.c
  */
+struct proc_dir_entry *proc_register(struct proc_dir_entry *dir,
+   struct proc_dir_entry *dp);
 extern struct dentry *proc_lookup(struct inode *, struct dentry *, unsigned 
int);
 struct dentry *proc_lookup_de(struct inode *, struct dentry *, struct 
proc_dir_entry *);
 extern int proc_readdir(struct file *, struct dir_context *);
-- 
2.17.0



[PATCH 14/42] net/kcm: simplify proc registration

2018-05-16 Thread Christoph Hellwig
Remove a couple indirections to make the code look like most other
protocols.

Signed-off-by: Christoph Hellwig 
---
 net/kcm/kcmproc.c | 71 ---
 1 file changed, 17 insertions(+), 54 deletions(-)

diff --git a/net/kcm/kcmproc.c b/net/kcm/kcmproc.c
index 1fac92543094..6d0667e62baf 100644
--- a/net/kcm/kcmproc.c
+++ b/net/kcm/kcmproc.c
@@ -15,12 +15,6 @@
 #include 
 
 #ifdef CONFIG_PROC_FS
-struct kcm_seq_muxinfo {
-   char*name;
-   const struct file_operations*seq_fops;
-   const struct seq_operations seq_ops;
-};
-
 static struct kcm_mux *kcm_get_first(struct seq_file *seq)
 {
struct net *net = seq_file_net(seq);
@@ -86,14 +80,6 @@ struct kcm_proc_mux_state {
int idx;
 };
 
-static int kcm_seq_open(struct inode *inode, struct file *file)
-{
-   struct kcm_seq_muxinfo *muxinfo = PDE_DATA(inode);
-
-   return seq_open_net(inode, file, >seq_ops,
-  sizeof(struct kcm_proc_mux_state));
-}
-
 static void kcm_format_mux_header(struct seq_file *seq)
 {
struct net *net = seq_file_net(seq);
@@ -246,6 +232,19 @@ static int kcm_seq_show(struct seq_file *seq, void *v)
return 0;
 }
 
+static const struct seq_operations kcm_seq_ops = {
+   .show   = kcm_seq_show,
+   .start  = kcm_seq_start,
+   .next   = kcm_seq_next,
+   .stop   = kcm_seq_stop,
+};
+
+static int kcm_seq_open(struct inode *inode, struct file *file)
+{
+   return seq_open_net(inode, file, _seq_ops,
+  sizeof(struct kcm_proc_mux_state));
+}
+
 static const struct file_operations kcm_seq_fops = {
.open   = kcm_seq_open,
.read   = seq_read,
@@ -253,37 +252,6 @@ static const struct file_operations kcm_seq_fops = {
.release= seq_release_net,
 };
 
-static struct kcm_seq_muxinfo kcm_seq_muxinfo = {
-   .name   = "kcm",
-   .seq_fops   = _seq_fops,
-   .seq_ops= {
-   .show   = kcm_seq_show,
-   .start  = kcm_seq_start,
-   .next   = kcm_seq_next,
-   .stop   = kcm_seq_stop,
-   }
-};
-
-static int kcm_proc_register(struct net *net, struct kcm_seq_muxinfo *muxinfo)
-{
-   struct proc_dir_entry *p;
-   int rc = 0;
-
-   p = proc_create_data(muxinfo->name, 0444, net->proc_net,
-muxinfo->seq_fops, muxinfo);
-   if (!p)
-   rc = -ENOMEM;
-   return rc;
-}
-EXPORT_SYMBOL(kcm_proc_register);
-
-static void kcm_proc_unregister(struct net *net,
-   struct kcm_seq_muxinfo *muxinfo)
-{
-   remove_proc_entry(muxinfo->name, net->proc_net);
-}
-EXPORT_SYMBOL(kcm_proc_unregister);
-
 static int kcm_stats_seq_show(struct seq_file *seq, void *v)
 {
struct kcm_psock_stats psock_stats;
@@ -404,16 +372,11 @@ static const struct file_operations kcm_stats_seq_fops = {
 
 static int kcm_proc_init_net(struct net *net)
 {
-   int err;
-
if (!proc_create("kcm_stats", 0444, net->proc_net,
-_stats_seq_fops)) {
-   err = -ENOMEM;
+_stats_seq_fops))
goto out_kcm_stats;
-   }
 
-   err = kcm_proc_register(net, _seq_muxinfo);
-   if (err)
+   if (!proc_create("kcm", 0444, net->proc_net, _seq_fops))
goto out_kcm;
 
return 0;
@@ -421,12 +384,12 @@ static int kcm_proc_init_net(struct net *net)
 out_kcm:
remove_proc_entry("kcm_stats", net->proc_net);
 out_kcm_stats:
-   return err;
+   return -ENOMEM;
 }
 
 static void kcm_proc_exit_net(struct net *net)
 {
-   kcm_proc_unregister(net, _seq_muxinfo);
+   remove_proc_entry("kcm", net->proc_net);
remove_proc_entry("kcm_stats", net->proc_net);
 }
 
-- 
2.17.0



[PATCH 05/42] proc: add a proc_create_reg helper

2018-05-16 Thread Christoph Hellwig
Common code for creating a regular file.  Factor out of proc_create_data, to
be reused by other functions soon.

Signed-off-by: Christoph Hellwig 
---
 fs/proc/generic.c  | 44 +---
 fs/proc/internal.h |  2 ++
 2 files changed, 27 insertions(+), 19 deletions(-)

diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index bd8480ff0d35..ab6a321076b8 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -511,33 +511,39 @@ struct proc_dir_entry *proc_create_mount_point(const char 
*name)
 }
 EXPORT_SYMBOL(proc_create_mount_point);
 
-struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
-   struct proc_dir_entry *parent,
-   const struct file_operations *proc_fops,
-   void *data)
+struct proc_dir_entry *proc_create_reg(const char *name, umode_t mode,
+   struct proc_dir_entry **parent, void *data)
 {
-   struct proc_dir_entry *pde;
+   struct proc_dir_entry *p;
+
if ((mode & S_IFMT) == 0)
mode |= S_IFREG;
-
-   if (!S_ISREG(mode)) {
-   WARN_ON(1); /* use proc_mkdir() */
+   if ((mode & S_IALLUGO) == 0)
+   mode |= S_IRUGO;
+   if (WARN_ON_ONCE(!S_ISREG(mode)))
return NULL;
+
+   p = __proc_create(parent, name, mode, 1);
+   if (p) {
+   p->proc_iops = _file_inode_operations;
+   p->data = data;
}
+   return p;
+}
+
+struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
+   struct proc_dir_entry *parent,
+   const struct file_operations *proc_fops, void *data)
+{
+   struct proc_dir_entry *p;
 
BUG_ON(proc_fops == NULL);
 
-   if ((mode & S_IALLUGO) == 0)
-   mode |= S_IRUGO;
-   pde = __proc_create(, name, mode, 1);
-   if (!pde)
-   goto out;
-   pde->proc_fops = proc_fops;
-   pde->data = data;
-   pde->proc_iops = _file_inode_operations;
-   return proc_register(parent, pde);
-out:
-   return NULL;
+   p = proc_create_reg(name, mode, , data);
+   if (!p)
+   return NULL;
+   p->proc_fops = proc_fops;
+   return proc_register(parent, p);
 }
 EXPORT_SYMBOL(proc_create_data);
  
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 488e67490312..dd1e11400b97 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -162,6 +162,8 @@ extern bool proc_fill_cache(struct file *, struct 
dir_context *, const char *, i
 /*
  * generic.c
  */
+struct proc_dir_entry *proc_create_reg(const char *name, umode_t mode,
+   struct proc_dir_entry **parent, void *data);
 struct proc_dir_entry *proc_register(struct proc_dir_entry *dir,
struct proc_dir_entry *dp);
 extern struct dentry *proc_lookup(struct inode *, struct dentry *, unsigned 
int);
-- 
2.17.0



[PATCH 12/42] ipv{4,6}/raw: simplify ѕeq_file code

2018-05-16 Thread Christoph Hellwig
Pass the hashtable to the proc private data instead of copying
it into the per-file private data.

Signed-off-by: Christoph Hellwig 
---
 include/net/raw.h |  4 
 net/ipv4/raw.c| 36 
 net/ipv6/raw.c|  6 --
 3 files changed, 16 insertions(+), 30 deletions(-)

diff --git a/include/net/raw.h b/include/net/raw.h
index 99d26d0c4a19..9c9fa98a91a4 100644
--- a/include/net/raw.h
+++ b/include/net/raw.h
@@ -48,7 +48,6 @@ void raw_proc_exit(void);
 struct raw_iter_state {
struct seq_net_private p;
int bucket;
-   struct raw_hashinfo *h;
 };
 
 static inline struct raw_iter_state *raw_seq_private(struct seq_file *seq)
@@ -58,9 +57,6 @@ static inline struct raw_iter_state *raw_seq_private(struct 
seq_file *seq)
 void *raw_seq_start(struct seq_file *seq, loff_t *pos);
 void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos);
 void raw_seq_stop(struct seq_file *seq, void *v);
-int raw_seq_open(struct inode *ino, struct file *file,
-struct raw_hashinfo *h, const struct seq_operations *ops);
-
 #endif
 
 int raw_hash_sk(struct sock *sk);
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 1b4d3355624a..ae57962b31e3 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -1003,11 +1003,12 @@ struct proto raw_prot = {
 static struct sock *raw_get_first(struct seq_file *seq)
 {
struct sock *sk;
+   struct raw_hashinfo *h = PDE_DATA(file_inode(seq->file));
struct raw_iter_state *state = raw_seq_private(seq);
 
for (state->bucket = 0; state->bucket < RAW_HTABLE_SIZE;
++state->bucket) {
-   sk_for_each(sk, >h->ht[state->bucket])
+   sk_for_each(sk, >ht[state->bucket])
if (sock_net(sk) == seq_file_net(seq))
goto found;
}
@@ -1018,6 +1019,7 @@ static struct sock *raw_get_first(struct seq_file *seq)
 
 static struct sock *raw_get_next(struct seq_file *seq, struct sock *sk)
 {
+   struct raw_hashinfo *h = PDE_DATA(file_inode(seq->file));
struct raw_iter_state *state = raw_seq_private(seq);
 
do {
@@ -1027,7 +1029,7 @@ static struct sock *raw_get_next(struct seq_file *seq, 
struct sock *sk)
} while (sk && sock_net(sk) != seq_file_net(seq));
 
if (!sk && ++state->bucket < RAW_HTABLE_SIZE) {
-   sk = sk_head(>h->ht[state->bucket]);
+   sk = sk_head(>ht[state->bucket]);
goto try_again;
}
return sk;
@@ -1045,9 +1047,9 @@ static struct sock *raw_get_idx(struct seq_file *seq, 
loff_t pos)
 
 void *raw_seq_start(struct seq_file *seq, loff_t *pos)
 {
-   struct raw_iter_state *state = raw_seq_private(seq);
+   struct raw_hashinfo *h = PDE_DATA(file_inode(seq->file));
 
-   read_lock(>h->lock);
+   read_lock(>lock);
return *pos ? raw_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
 }
 EXPORT_SYMBOL_GPL(raw_seq_start);
@@ -1067,9 +1069,9 @@ EXPORT_SYMBOL_GPL(raw_seq_next);
 
 void raw_seq_stop(struct seq_file *seq, void *v)
 {
-   struct raw_iter_state *state = raw_seq_private(seq);
+   struct raw_hashinfo *h = PDE_DATA(file_inode(seq->file));
 
-   read_unlock(>h->lock);
+   read_unlock(>lock);
 }
 EXPORT_SYMBOL_GPL(raw_seq_stop);
 
@@ -1110,25 +1112,10 @@ static const struct seq_operations raw_seq_ops = {
.show  = raw_seq_show,
 };
 
-int raw_seq_open(struct inode *ino, struct file *file,
-struct raw_hashinfo *h, const struct seq_operations *ops)
-{
-   int err;
-   struct raw_iter_state *i;
-
-   err = seq_open_net(ino, file, ops, sizeof(struct raw_iter_state));
-   if (err < 0)
-   return err;
-
-   i = raw_seq_private((struct seq_file *)file->private_data);
-   i->h = h;
-   return 0;
-}
-EXPORT_SYMBOL_GPL(raw_seq_open);
-
 static int raw_v4_seq_open(struct inode *inode, struct file *file)
 {
-   return raw_seq_open(inode, file, _v4_hashinfo, _seq_ops);
+   return seq_open_net(inode, file, _seq_ops,
+   sizeof(struct raw_iter_state));
 }
 
 static const struct file_operations raw_seq_fops = {
@@ -1140,7 +1127,8 @@ static const struct file_operations raw_seq_fops = {
 
 static __net_init int raw_init_net(struct net *net)
 {
-   if (!proc_create("raw", 0444, net->proc_net, _seq_fops))
+   if (!proc_create_data("raw", 0444, net->proc_net, _seq_fops,
+   _v4_hashinfo))
return -ENOMEM;
 
return 0;
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 5eb9b08947ed..dade69bf61e6 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -1306,7 +1306,8 @@ static const struct seq_operations raw6_seq_ops = {
 
 static int raw6_seq_open(struct inode *inode, struct file *file)
 {
-   return raw_seq_open(inode, file, _v6_hashinfo, _seq_ops);
+   return seq_open_net(inode, file, _seq_ops,
+   sizeof(struct raw_iter_state));
 }
 

[PATCH 15/42] netfilter/x_tables: simplify ѕeq_file code

2018-05-16 Thread Christoph Hellwig
Just use the address family from the proc private data instead of copying
it into per-file data.

Signed-off-by: Christoph Hellwig 
---
 net/netfilter/x_tables.c | 39 +++
 1 file changed, 11 insertions(+), 28 deletions(-)

diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 71325fef647d..3704101af27f 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -1489,15 +1489,10 @@ void *xt_unregister_table(struct xt_table *table)
 EXPORT_SYMBOL_GPL(xt_unregister_table);
 
 #ifdef CONFIG_PROC_FS
-struct xt_names_priv {
-   struct seq_net_private p;
-   u_int8_t af;
-};
 static void *xt_table_seq_start(struct seq_file *seq, loff_t *pos)
 {
-   struct xt_names_priv *priv = seq->private;
struct net *net = seq_file_net(seq);
-   u_int8_t af = priv->af;
+   u_int8_t af = (unsigned long)PDE_DATA(file_inode(seq->file));
 
mutex_lock([af].mutex);
return seq_list_start(>xt.tables[af], *pos);
@@ -1505,17 +1500,15 @@ static void *xt_table_seq_start(struct seq_file *seq, 
loff_t *pos)
 
 static void *xt_table_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-   struct xt_names_priv *priv = seq->private;
struct net *net = seq_file_net(seq);
-   u_int8_t af = priv->af;
+   u_int8_t af = (unsigned long)PDE_DATA(file_inode(seq->file));
 
return seq_list_next(v, >xt.tables[af], pos);
 }
 
 static void xt_table_seq_stop(struct seq_file *seq, void *v)
 {
-   struct xt_names_priv *priv = seq->private;
-   u_int8_t af = priv->af;
+   u_int8_t af = (unsigned long)PDE_DATA(file_inode(seq->file));
 
mutex_unlock([af].mutex);
 }
@@ -1538,16 +1531,8 @@ static const struct seq_operations xt_table_seq_ops = {
 
 static int xt_table_open(struct inode *inode, struct file *file)
 {
-   int ret;
-   struct xt_names_priv *priv;
-
-   ret = seq_open_net(inode, file, _table_seq_ops,
-  sizeof(struct xt_names_priv));
-   if (!ret) {
-   priv = ((struct seq_file *)file->private_data)->private;
-   priv->af = (unsigned long)PDE_DATA(inode);
-   }
-   return ret;
+   return seq_open_net(inode, file, _table_seq_ops,
+   sizeof(struct seq_net_private));
 }
 
 static const struct file_operations xt_table_ops = {
@@ -1563,7 +1548,7 @@ static const struct file_operations xt_table_ops = {
  */
 struct nf_mttg_trav {
struct list_head *head, *curr;
-   uint8_t class, nfproto;
+   uint8_t class;
 };
 
 enum {
@@ -1580,6 +1565,7 @@ static void *xt_mttg_seq_next(struct seq_file *seq, void 
*v, loff_t *ppos,
[MTTG_TRAV_NFP_UNSPEC] = MTTG_TRAV_NFP_SPEC,
[MTTG_TRAV_NFP_SPEC]   = MTTG_TRAV_DONE,
};
+   uint8_t nfproto = (unsigned long)PDE_DATA(file_inode(seq->file));
struct nf_mttg_trav *trav = seq->private;
 
switch (trav->class) {
@@ -1594,9 +1580,9 @@ static void *xt_mttg_seq_next(struct seq_file *seq, void 
*v, loff_t *ppos,
if (trav->curr != trav->head)
break;
mutex_unlock([NFPROTO_UNSPEC].mutex);
-   mutex_lock([trav->nfproto].mutex);
+   mutex_lock([nfproto].mutex);
trav->head = trav->curr = is_target ?
-   [trav->nfproto].target : [trav->nfproto].match;
+   [nfproto].target : [nfproto].match;
trav->class = next_class[trav->class];
break;
case MTTG_TRAV_NFP_SPEC:
@@ -1628,6 +1614,7 @@ static void *xt_mttg_seq_start(struct seq_file *seq, 
loff_t *pos,
 
 static void xt_mttg_seq_stop(struct seq_file *seq, void *v)
 {
+   uint8_t nfproto = (unsigned long)PDE_DATA(file_inode(seq->file));
struct nf_mttg_trav *trav = seq->private;
 
switch (trav->class) {
@@ -1635,7 +1622,7 @@ static void xt_mttg_seq_stop(struct seq_file *seq, void 
*v)
mutex_unlock([NFPROTO_UNSPEC].mutex);
break;
case MTTG_TRAV_NFP_SPEC:
-   mutex_unlock([trav->nfproto].mutex);
+   mutex_unlock([nfproto].mutex);
break;
}
 }
@@ -1680,8 +1667,6 @@ static int xt_match_open(struct inode *inode, struct file 
*file)
trav = __seq_open_private(file, _match_seq_ops, sizeof(*trav));
if (!trav)
return -ENOMEM;
-
-   trav->nfproto = (unsigned long)PDE_DATA(inode);
return 0;
 }
 
@@ -1732,8 +1717,6 @@ static int xt_target_open(struct inode *inode, struct 
file *file)
trav = __seq_open_private(file, _target_seq_ops, sizeof(*trav));
if (!trav)
return -ENOMEM;
-
-   trav->nfproto = (unsigned long)PDE_DATA(inode);
return 0;
 }
 
-- 
2.17.0



[PATCH 11/42] ipv{4,6}/ping: simplify proc file creation

2018-05-16 Thread Christoph Hellwig
Remove the pointless ping_seq_afinfo indirection and make the code look
like most other protocols.

Signed-off-by: Christoph Hellwig 
---
 include/net/ping.h | 11 --
 net/ipv4/ping.c| 50 +-
 net/ipv6/ping.c| 35 +---
 3 files changed, 37 insertions(+), 59 deletions(-)

diff --git a/include/net/ping.h b/include/net/ping.h
index 4cd90d6b5c25..fd080e043a6e 100644
--- a/include/net/ping.h
+++ b/include/net/ping.h
@@ -83,20 +83,9 @@ int  ping_queue_rcv_skb(struct sock *sk, struct sk_buff 
*skb);
 bool ping_rcv(struct sk_buff *skb);
 
 #ifdef CONFIG_PROC_FS
-struct ping_seq_afinfo {
-   char*name;
-   sa_family_t family;
-   const struct file_operations*seq_fops;
-   const struct seq_operations seq_ops;
-};
-
-extern const struct file_operations ping_seq_fops;
-
 void *ping_seq_start(struct seq_file *seq, loff_t *pos, sa_family_t family);
 void *ping_seq_next(struct seq_file *seq, void *v, loff_t *pos);
 void ping_seq_stop(struct seq_file *seq, void *v);
-int ping_proc_register(struct net *net, struct ping_seq_afinfo *afinfo);
-void ping_proc_unregister(struct net *net, struct ping_seq_afinfo *afinfo);
 
 int __init ping_proc_init(void);
 void ping_proc_exit(void);
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 56a010622f70..4d21c24dba78 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -1150,58 +1150,36 @@ static int ping_v4_seq_show(struct seq_file *seq, void 
*v)
return 0;
 }
 
-static int ping_seq_open(struct inode *inode, struct file *file)
+static const struct seq_operations ping_v4_seq_ops = {
+   .start  = ping_v4_seq_start,
+   .show   = ping_v4_seq_show,
+   .next   = ping_seq_next,
+   .stop   = ping_seq_stop,
+};
+
+static int ping_v4_seq_open(struct inode *inode, struct file *file)
 {
-   struct ping_seq_afinfo *afinfo = PDE_DATA(inode);
-   return seq_open_net(inode, file, >seq_ops,
+   return seq_open_net(inode, file, _v4_seq_ops,
   sizeof(struct ping_iter_state));
 }
 
-const struct file_operations ping_seq_fops = {
-   .open   = ping_seq_open,
+const struct file_operations ping_v4_seq_fops = {
+   .open   = ping_v4_seq_open,
.read   = seq_read,
.llseek = seq_lseek,
.release= seq_release_net,
 };
-EXPORT_SYMBOL_GPL(ping_seq_fops);
-
-static struct ping_seq_afinfo ping_v4_seq_afinfo = {
-   .name   = "icmp",
-   .family = AF_INET,
-   .seq_fops   = _seq_fops,
-   .seq_ops= {
-   .start  = ping_v4_seq_start,
-   .show   = ping_v4_seq_show,
-   .next   = ping_seq_next,
-   .stop   = ping_seq_stop,
-   },
-};
 
-int ping_proc_register(struct net *net, struct ping_seq_afinfo *afinfo)
+static int __net_init ping_v4_proc_init_net(struct net *net)
 {
-   struct proc_dir_entry *p;
-   p = proc_create_data(afinfo->name, 0444, net->proc_net,
-afinfo->seq_fops, afinfo);
-   if (!p)
+   if (!proc_create("icmp", 0444, net->proc_net, _v4_seq_fops))
return -ENOMEM;
return 0;
 }
-EXPORT_SYMBOL_GPL(ping_proc_register);
-
-void ping_proc_unregister(struct net *net, struct ping_seq_afinfo *afinfo)
-{
-   remove_proc_entry(afinfo->name, net->proc_net);
-}
-EXPORT_SYMBOL_GPL(ping_proc_unregister);
-
-static int __net_init ping_v4_proc_init_net(struct net *net)
-{
-   return ping_proc_register(net, _v4_seq_afinfo);
-}
 
 static void __net_exit ping_v4_proc_exit_net(struct net *net)
 {
-   ping_proc_unregister(net, _v4_seq_afinfo);
+   remove_proc_entry("icmp", net->proc_net);
 }
 
 static struct pernet_operations ping_v4_net_ops = {
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
index 746eeae7f581..45d5c8e0f2bf 100644
--- a/net/ipv6/ping.c
+++ b/net/ipv6/ping.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /* Compatibility glue so we can support IPv6 when it's compiled as a module */
@@ -215,26 +216,36 @@ static int ping_v6_seq_show(struct seq_file *seq, void *v)
return 0;
 }
 
-static struct ping_seq_afinfo ping_v6_seq_afinfo = {
-   .name   = "icmp6",
-   .family = AF_INET6,
-   .seq_fops   = _seq_fops,
-   .seq_ops= {
-   .start  = ping_v6_seq_start,
-   .show   = ping_v6_seq_show,
-   .next   = ping_seq_next,
-   .stop   = ping_seq_stop,
-   },
+static const struct seq_operations ping_v6_seq_ops = {
+   .start  = ping_v6_seq_start,
+   .show   = ping_v6_seq_show,
+   .next   = ping_seq_next,
+   .stop   = ping_seq_stop,
+};
+
+static int 

[PATCH 19/42] acpi/battery: simplify procfs code

2018-05-16 Thread Christoph Hellwig
Use remove_proc_subtree to remove the whole subtree on cleanup, and
unwind the registration loop into individual calls.  Switch to use
proc_create_seq where applicable.

Signed-off-by: Christoph Hellwig 
Reviewed-by: Rafael J. Wysocki 
---
 drivers/acpi/battery.c | 121 +
 1 file changed, 26 insertions(+), 95 deletions(-)

diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index bdb24d636d9a..76550689ce10 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -81,14 +81,6 @@ MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
 #ifdef CONFIG_ACPI_PROCFS_POWER
 extern struct proc_dir_entry *acpi_lock_battery_dir(void);
 extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
-
-enum acpi_battery_files {
-   info_tag = 0,
-   state_tag,
-   alarm_tag,
-   ACPI_BATTERY_NUMFILES,
-};
-
 #endif
 
 static const struct acpi_device_id battery_device_ids[] = {
@@ -985,9 +977,10 @@ static const char *acpi_battery_units(const struct 
acpi_battery *battery)
"mA" : "mW";
 }
 
-static int acpi_battery_print_info(struct seq_file *seq, int result)
+static int acpi_battery_info_proc_show(struct seq_file *seq, void *offset)
 {
struct acpi_battery *battery = seq->private;
+   int result = acpi_battery_update(battery, false);
 
if (result)
goto end;
@@ -1041,9 +1034,10 @@ static int acpi_battery_print_info(struct seq_file *seq, 
int result)
return result;
 }
 
-static int acpi_battery_print_state(struct seq_file *seq, int result)
+static int acpi_battery_state_proc_show(struct seq_file *seq, void *offset)
 {
struct acpi_battery *battery = seq->private;
+   int result = acpi_battery_update(battery, false);
 
if (result)
goto end;
@@ -1088,9 +1082,10 @@ static int acpi_battery_print_state(struct seq_file 
*seq, int result)
return result;
 }
 
-static int acpi_battery_print_alarm(struct seq_file *seq, int result)
+static int acpi_battery_alarm_proc_show(struct seq_file *seq, void *offset)
 {
struct acpi_battery *battery = seq->private;
+   int result = acpi_battery_update(battery, false);
 
if (result)
goto end;
@@ -1142,82 +1137,22 @@ static ssize_t acpi_battery_write_alarm(struct file 
*file,
return result;
 }
 
-typedef int(*print_func)(struct seq_file *seq, int result);
-
-static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = {
-   acpi_battery_print_info,
-   acpi_battery_print_state,
-   acpi_battery_print_alarm,
-};
-
-static int acpi_battery_read(int fid, struct seq_file *seq)
+static int acpi_battery_alarm_proc_open(struct inode *inode, struct file *file)
 {
-   struct acpi_battery *battery = seq->private;
-   int result = acpi_battery_update(battery, false);
-   return acpi_print_funcs[fid](seq, result);
+   return single_open(file, acpi_battery_alarm_proc_show, PDE_DATA(inode));
 }
 
-#define DECLARE_FILE_FUNCTIONS(_name) \
-static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \
-{ \
-   return acpi_battery_read(_name##_tag, seq); \
-} \
-static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file 
*file) \
-{ \
-   return single_open(file, acpi_battery_read_##_name, PDE_DATA(inode)); \
-}
-
-DECLARE_FILE_FUNCTIONS(info);
-DECLARE_FILE_FUNCTIONS(state);
-DECLARE_FILE_FUNCTIONS(alarm);
-
-#undef DECLARE_FILE_FUNCTIONS
-
-#define FILE_DESCRIPTION_RO(_name) \
-   { \
-   .name = __stringify(_name), \
-   .mode = S_IRUGO, \
-   .ops = { \
-   .open = acpi_battery_##_name##_open_fs, \
-   .read = seq_read, \
-   .llseek = seq_lseek, \
-   .release = single_release, \
-   .owner = THIS_MODULE, \
-   }, \
-   }
-
-#define FILE_DESCRIPTION_RW(_name) \
-   { \
-   .name = __stringify(_name), \
-   .mode = S_IFREG | S_IRUGO | S_IWUSR, \
-   .ops = { \
-   .open = acpi_battery_##_name##_open_fs, \
-   .read = seq_read, \
-   .llseek = seq_lseek, \
-   .write = acpi_battery_write_##_name, \
-   .release = single_release, \
-   .owner = THIS_MODULE, \
-   }, \
-   }
-
-static const struct battery_file {
-   struct file_operations ops;
-   umode_t mode;
-   const char *name;
-} acpi_battery_file[] = {
-   FILE_DESCRIPTION_RO(info),
-   FILE_DESCRIPTION_RO(state),
-   FILE_DESCRIPTION_RW(alarm),
+static const struct file_operations acpi_battery_alarm_fops = {
+   .owner  = THIS_MODULE,
+   .open   = acpi_battery_alarm_proc_open,
+   .read   = seq_read,
+   .write  = acpi_battery_write_alarm,
+   .llseek = seq_lseek,
+   .release= single_release,
 };
 
-#undef FILE_DESCRIPTION_RO

[PATCH 20/42] sgi-gru: simplify procfs code

2018-05-16 Thread Christoph Hellwig
Use remove_proc_subtree to remove the whole subtree on cleanup, and
unwind the registration loop into individual calls.  Switch to use
proc_create_seq where applicable.

Signed-off-by: Christoph Hellwig 
---
 drivers/misc/sgi-gru/gruprocfs.c | 81 ++--
 1 file changed, 14 insertions(+), 67 deletions(-)

diff --git a/drivers/misc/sgi-gru/gruprocfs.c b/drivers/misc/sgi-gru/gruprocfs.c
index 4f7635922394..42ea2eccaee9 100644
--- a/drivers/misc/sgi-gru/gruprocfs.c
+++ b/drivers/misc/sgi-gru/gruprocfs.c
@@ -270,16 +270,6 @@ static int options_open(struct inode *inode, struct file 
*file)
return single_open(file, options_show, NULL);
 }
 
-static int cch_open(struct inode *inode, struct file *file)
-{
-   return seq_open(file, _seq_ops);
-}
-
-static int gru_open(struct inode *inode, struct file *file)
-{
-   return seq_open(file, _seq_ops);
-}
-
 /* *INDENT-OFF* */
 static const struct file_operations statistics_fops = {
.open   = statistics_open,
@@ -305,73 +295,30 @@ static const struct file_operations options_fops = {
.release= single_release,
 };
 
-static const struct file_operations cch_fops = {
-   .open   = cch_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= seq_release,
-};
-static const struct file_operations gru_fops = {
-   .open   = gru_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= seq_release,
-};
-
-static struct proc_entry {
-   char *name;
-   umode_t mode;
-   const struct file_operations *fops;
-   struct proc_dir_entry *entry;
-} proc_files[] = {
-   {"statistics", 0644, _fops},
-   {"mcs_statistics", 0644, _statistics_fops},
-   {"debug_options", 0644, _fops},
-   {"cch_status", 0444, _fops},
-   {"gru_status", 0444, _fops},
-   {NULL}
-};
-/* *INDENT-ON* */
-
 static struct proc_dir_entry *proc_gru __read_mostly;
 
-static int create_proc_file(struct proc_entry *p)
-{
-   p->entry = proc_create(p->name, p->mode, proc_gru, p->fops);
-   if (!p->entry)
-   return -1;
-   return 0;
-}
-
-static void delete_proc_files(void)
-{
-   struct proc_entry *p;
-
-   if (proc_gru) {
-   for (p = proc_files; p->name; p++)
-   if (p->entry)
-   remove_proc_entry(p->name, proc_gru);
-   proc_remove(proc_gru);
-   }
-}
-
 int gru_proc_init(void)
 {
-   struct proc_entry *p;
-
proc_gru = proc_mkdir("sgi_uv/gru", NULL);
-
-   for (p = proc_files; p->name; p++)
-   if (create_proc_file(p))
-   goto err;
+   if (!proc_gru)
+   return -1;
+   if (!proc_create("statistics", 0644, proc_gru, _fops))
+   goto err;
+   if (!proc_create("mcs_statistics", 0644, proc_gru, 
_statistics_fops))
+   goto err;
+   if (!proc_create("debug_options", 0644, proc_gru, _fops))
+   goto err;
+   if (!proc_create_seq("cch_status", 0444, proc_gru, _seq_ops))
+   goto err;
+   if (!proc_create_seq("gru_status", 0444, proc_gru, _seq_ops))
+   goto err;
return 0;
-
 err:
-   delete_proc_files();
+   remove_proc_subtree("sgi_uv/gru", NULL);
return -1;
 }
 
 void gru_proc_exit(void)
 {
-   delete_proc_files();
+   remove_proc_subtree("sgi_uv/gru", NULL);
 }
-- 
2.17.0



[PATCH 13/42] ipv6/flowlabel: simplify pid namespace lookup

2018-05-16 Thread Christoph Hellwig
The code should be using the pid namespace from the procfs mount
instead of trying to look it up during open.

Suggested-by: Eric W. Biederman 
Signed-off-by: Christoph Hellwig 
---
 net/ipv6/ip6_flowlabel.c | 29 ++---
 1 file changed, 6 insertions(+), 23 deletions(-)

diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index c05c4e82a7ca..2fbd9bed764a 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -754,6 +754,10 @@ static struct ip6_flowlabel *ip6fl_get_idx(struct seq_file 
*seq, loff_t pos)
 static void *ip6fl_seq_start(struct seq_file *seq, loff_t *pos)
__acquires(RCU)
 {
+   struct ip6fl_iter_state *state = ip6fl_seq_private(seq);
+
+   state->pid_ns = proc_pid_ns(file_inode(seq->file));
+
rcu_read_lock_bh();
return *pos ? ip6fl_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
 }
@@ -810,36 +814,15 @@ static const struct seq_operations ip6fl_seq_ops = {
 
 static int ip6fl_seq_open(struct inode *inode, struct file *file)
 {
-   struct seq_file *seq;
-   struct ip6fl_iter_state *state;
-   int err;
-
-   err = seq_open_net(inode, file, _seq_ops,
+   return seq_open_net(inode, file, _seq_ops,
   sizeof(struct ip6fl_iter_state));
-
-   if (!err) {
-   seq = file->private_data;
-   state = ip6fl_seq_private(seq);
-   rcu_read_lock();
-   state->pid_ns = get_pid_ns(task_active_pid_ns(current));
-   rcu_read_unlock();
-   }
-   return err;
-}
-
-static int ip6fl_seq_release(struct inode *inode, struct file *file)
-{
-   struct seq_file *seq = file->private_data;
-   struct ip6fl_iter_state *state = ip6fl_seq_private(seq);
-   put_pid_ns(state->pid_ns);
-   return seq_release_net(inode, file);
 }
 
 static const struct file_operations ip6fl_seq_fops = {
.open   =   ip6fl_seq_open,
.read   =   seq_read,
.llseek =   seq_lseek,
-   .release=   ip6fl_seq_release,
+   .release=   seq_release_net,
 };
 
 static int __net_init ip6_flowlabel_proc_init(struct net *net)
-- 
2.17.0



[PATCH 22/42] sg: simplify procfs code

2018-05-16 Thread Christoph Hellwig
Use remove_proc_subtree to remove the whole subtree on cleanup, and
unwind the registration loop into individual calls.  Switch to use
proc_create_seq where applicable.

Also don't bother handling proc_create* failures - the driver works
perfectly fine without the proc files, and the cleanup will handle
missing files gracefully.

Signed-off-by: Christoph Hellwig 
---
 drivers/scsi/sg.c | 124 +-
 1 file changed, 12 insertions(+), 112 deletions(-)

diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index c198b96368dd..8ff687158704 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -66,7 +66,6 @@ static int sg_version_num = 30536;/* 2 digits for each 
component */
 static char *sg_version_date = "20140603";
 
 static int sg_proc_init(void);
-static void sg_proc_cleanup(void);
 #endif
 
 #define SG_ALLOW_DIO_DEF 0
@@ -1661,7 +1660,7 @@ static void __exit
 exit_sg(void)
 {
 #ifdef CONFIG_SCSI_PROC_FS
-   sg_proc_cleanup();
+   remove_proc_subtree("scsi/sg", NULL);
 #endif /* CONFIG_SCSI_PROC_FS */
scsi_unregister_interface(_interface);
class_destroy(sg_sysfs_class);
@@ -2274,11 +2273,6 @@ sg_get_dev(int dev)
 }
 
 #ifdef CONFIG_SCSI_PROC_FS
-
-static struct proc_dir_entry *sg_proc_sgp = NULL;
-
-static char sg_proc_sg_dirname[] = "scsi/sg";
-
 static int sg_proc_seq_show_int(struct seq_file *s, void *v);
 
 static int sg_proc_single_open_adio(struct inode *inode, struct file *file);
@@ -2306,37 +2300,11 @@ static const struct file_operations dressz_fops = {
 };
 
 static int sg_proc_seq_show_version(struct seq_file *s, void *v);
-static int sg_proc_single_open_version(struct inode *inode, struct file *file);
-static const struct file_operations version_fops = {
-   .owner = THIS_MODULE,
-   .open = sg_proc_single_open_version,
-   .read = seq_read,
-   .llseek = seq_lseek,
-   .release = single_release,
-};
-
 static int sg_proc_seq_show_devhdr(struct seq_file *s, void *v);
-static int sg_proc_single_open_devhdr(struct inode *inode, struct file *file);
-static const struct file_operations devhdr_fops = {
-   .owner = THIS_MODULE,
-   .open = sg_proc_single_open_devhdr,
-   .read = seq_read,
-   .llseek = seq_lseek,
-   .release = single_release,
-};
-
 static int sg_proc_seq_show_dev(struct seq_file *s, void *v);
-static int sg_proc_open_dev(struct inode *inode, struct file *file);
 static void * dev_seq_start(struct seq_file *s, loff_t *pos);
 static void * dev_seq_next(struct seq_file *s, void *v, loff_t *pos);
 static void dev_seq_stop(struct seq_file *s, void *v);
-static const struct file_operations dev_fops = {
-   .owner = THIS_MODULE,
-   .open = sg_proc_open_dev,
-   .read = seq_read,
-   .llseek = seq_lseek,
-   .release = seq_release,
-};
 static const struct seq_operations dev_seq_ops = {
.start = dev_seq_start,
.next  = dev_seq_next,
@@ -2345,14 +2313,6 @@ static const struct seq_operations dev_seq_ops = {
 };
 
 static int sg_proc_seq_show_devstrs(struct seq_file *s, void *v);
-static int sg_proc_open_devstrs(struct inode *inode, struct file *file);
-static const struct file_operations devstrs_fops = {
-   .owner = THIS_MODULE,
-   .open = sg_proc_open_devstrs,
-   .read = seq_read,
-   .llseek = seq_lseek,
-   .release = seq_release,
-};
 static const struct seq_operations devstrs_seq_ops = {
.start = dev_seq_start,
.next  = dev_seq_next,
@@ -2361,14 +2321,6 @@ static const struct seq_operations devstrs_seq_ops = {
 };
 
 static int sg_proc_seq_show_debug(struct seq_file *s, void *v);
-static int sg_proc_open_debug(struct inode *inode, struct file *file);
-static const struct file_operations debug_fops = {
-   .owner = THIS_MODULE,
-   .open = sg_proc_open_debug,
-   .read = seq_read,
-   .llseek = seq_lseek,
-   .release = seq_release,
-};
 static const struct seq_operations debug_seq_ops = {
.start = dev_seq_start,
.next  = dev_seq_next,
@@ -2376,50 +2328,23 @@ static const struct seq_operations debug_seq_ops = {
.show  = sg_proc_seq_show_debug,
 };
 
-
-struct sg_proc_leaf {
-   const char * name;
-   const struct file_operations * fops;
-};
-
-static const struct sg_proc_leaf sg_proc_leaf_arr[] = {
-   {"allow_dio", _fops},
-   {"debug", _fops},
-   {"def_reserved_size", _fops},
-   {"device_hdr", _fops},
-   {"devices", _fops},
-   {"device_strs", _fops},
-   {"version", _fops}
-};
-
 static int
 sg_proc_init(void)
 {
-   int num_leaves = ARRAY_SIZE(sg_proc_leaf_arr);
-   int k;
+   struct proc_dir_entry *p;
 
-   sg_proc_sgp = proc_mkdir(sg_proc_sg_dirname, NULL);
-   if (!sg_proc_sgp)
+   p = proc_mkdir("scsi/sg", NULL);
+   if (!p)
return 1;
-   for (k = 0; k < num_leaves; ++k) {
-   const struct sg_proc_leaf *leaf = 

[PATCH 17/42] proc: introduce proc_create_net{,_data}

2018-05-16 Thread Christoph Hellwig
Variants of proc_create{,_data} that directly take a struct seq_operations
and deal with network namespaces in ->open and ->release.  All callers of
proc_create + seq_open_net converted over, and seq_{open,release}_net are
removed entirely.

Signed-off-by: Christoph Hellwig 
---
 drivers/net/ppp/pppoe.c | 18 +---
 fs/nfs/client.c | 43 ++---
 fs/proc/proc_net.c  | 61 -
 include/linux/proc_fs.h |  9 
 include/linux/seq_file_net.h|  3 --
 include/net/ip6_fib.h   | 10 +++-
 include/net/phonet/pn_dev.h |  4 +-
 include/net/udp.h   |  4 +-
 net/8021q/vlanproc.c| 18 ++--
 net/atm/clip.c  | 17 +--
 net/core/net-procfs.c   | 49 +++-
 net/core/sock.c | 16 +--
 net/decnet/dn_neigh.c   | 18 +---
 net/ipv4/arp.c  | 17 ++-
 net/ipv4/fib_trie.c | 32 ++---
 net/ipv4/igmp.c | 33 ++---
 net/ipv4/ipmr.c | 32 ++---
 net/ipv4/ping.c | 16 +--
 net/ipv4/raw.c  | 17 +--
 net/ipv4/tcp_ipv4.c | 17 +--
 net/ipv4/udp.c  | 21 ++---
 net/ipv4/udplite.c  |  4 +-
 net/ipv6/addrconf.c | 16 +--
 net/ipv6/anycast.c  | 16 +--
 net/ipv6/ip6_fib.c  | 18 +---
 net/ipv6/ip6_flowlabel.c| 17 +--
 net/ipv6/ip6mr.c| 32 ++---
 net/ipv6/mcast.c| 34 ++
 net/ipv6/ping.c | 16 +--
 net/ipv6/raw.c  | 17 +--
 net/ipv6/route.c| 11 +
 net/ipv6/tcp_ipv6.c | 17 +--
 net/ipv6/udp.c  | 21 ++---
 net/ipv6/udplite.c  |  5 +-
 net/kcm/kcmproc.c   | 16 +--
 net/key/af_key.c| 16 +--
 net/l2tp/l2tp_ppp.c | 22 +
 net/netfilter/ipvs/ip_vs_app.c  | 16 +--
 net/netfilter/ipvs/ip_vs_conn.c | 35 ++
 net/netfilter/ipvs/ip_vs_ctl.c  | 16 +--
 net/netfilter/nf_conntrack_expect.c | 17 +--
 net/netfilter/nf_conntrack_standalone.c | 33 ++---
 net/netfilter/nf_log.c  | 19 +---
 net/netfilter/nf_synproxy_core.c| 17 +--
 net/netfilter/nfnetlink_log.c   | 18 +---
 net/netfilter/nfnetlink_queue.c | 18 +---
 net/netfilter/x_tables.c| 18 ++--
 net/netlink/af_netlink.c| 18 +---
 net/packet/af_packet.c  | 17 +--
 net/phonet/pn_dev.c |  6 ++-
 net/phonet/socket.c | 30 +---
 net/rxrpc/ar-internal.h |  4 +-
 net/rxrpc/net_ns.c  |  7 ++-
 net/rxrpc/proc.c| 31 +
 net/sctp/proc.c | 54 +++---
 net/unix/af_unix.c  | 17 +--
 net/wireless/wext-proc.c| 17 +--
 57 files changed, 202 insertions(+), 939 deletions(-)

diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
index 7df07337d69c..ce61231e96ea 100644
--- a/drivers/net/ppp/pppoe.c
+++ b/drivers/net/ppp/pppoe.c
@@ -1096,21 +1096,6 @@ static const struct seq_operations pppoe_seq_ops = {
.stop   = pppoe_seq_stop,
.show   = pppoe_seq_show,
 };
-
-static int pppoe_seq_open(struct inode *inode, struct file *file)
-{
-   return seq_open_net(inode, file, _seq_ops,
-   sizeof(struct seq_net_private));
-}
-
-static const struct file_operations pppoe_seq_fops = {
-   .owner  = THIS_MODULE,
-   .open   = pppoe_seq_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= seq_release_net,
-};
-
 #endif /* CONFIG_PROC_FS */
 
 static const struct proto_ops pppoe_ops = {
@@ -1146,7 +1131,8 @@ static __net_init int pppoe_init_net(struct net *net)
 
rwlock_init(>hash_lock);
 
-   pde = proc_create("pppoe", 0444, net->proc_net, _seq_fops);
+   pde = proc_create_net("pppoe", 0444, net->proc_net,
+   _seq_ops, sizeof(struct seq_net_private));
 #ifdef CONFIG_PROC_FS
if (!pde)
return -ENOMEM;
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index b9129e2befea..bbc91d7ca1bd 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -1067,7 +1067,6 @@ void nfs_clients_init(struct net *net)
 }
 
 #ifdef CONFIG_PROC_FS
-static int nfs_server_list_open(struct 

[PATCH 24/42] ext4: simplify procfs code

2018-05-16 Thread Christoph Hellwig
Use remove_proc_subtree to remove the whole subtree on cleanup, and
unwind the registration loop into individual calls.  Switch to use
proc_create_seq where applicable.

Signed-off-by: Christoph Hellwig 
---
 fs/ext4/ext4.h|  2 +-
 fs/ext4/mballoc.c | 29 
 fs/ext4/sysfs.c   | 49 +--
 3 files changed, 14 insertions(+), 66 deletions(-)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index a42e71203e53..229ea4da6785 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2390,7 +2390,7 @@ extern int ext4_init_inode_table(struct super_block *sb,
 extern void ext4_end_bitmap_read(struct buffer_head *bh, int uptodate);
 
 /* mballoc.c */
-extern const struct file_operations ext4_seq_mb_groups_fops;
+extern const struct seq_operations ext4_mb_seq_groups_ops;
 extern long ext4_mb_stats;
 extern long ext4_mb_max_to_scan;
 extern int ext4_mb_init(struct super_block *);
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 769a62708b1c..6884e81c1465 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2254,7 +2254,7 @@ ext4_mb_regular_allocator(struct ext4_allocation_context 
*ac)
 
 static void *ext4_mb_seq_groups_start(struct seq_file *seq, loff_t *pos)
 {
-   struct super_block *sb = seq->private;
+   struct super_block *sb = PDE_DATA(file_inode(seq->file));
ext4_group_t group;
 
if (*pos < 0 || *pos >= ext4_get_groups_count(sb))
@@ -2265,7 +2265,7 @@ static void *ext4_mb_seq_groups_start(struct seq_file 
*seq, loff_t *pos)
 
 static void *ext4_mb_seq_groups_next(struct seq_file *seq, void *v, loff_t 
*pos)
 {
-   struct super_block *sb = seq->private;
+   struct super_block *sb = PDE_DATA(file_inode(seq->file));
ext4_group_t group;
 
++*pos;
@@ -2277,7 +2277,7 @@ static void *ext4_mb_seq_groups_next(struct seq_file 
*seq, void *v, loff_t *pos)
 
 static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v)
 {
-   struct super_block *sb = seq->private;
+   struct super_block *sb = PDE_DATA(file_inode(seq->file));
ext4_group_t group = (ext4_group_t) ((unsigned long) v);
int i;
int err, buddy_loaded = 0;
@@ -2330,34 +2330,13 @@ static void ext4_mb_seq_groups_stop(struct seq_file 
*seq, void *v)
 {
 }
 
-static const struct seq_operations ext4_mb_seq_groups_ops = {
+const struct seq_operations ext4_mb_seq_groups_ops = {
.start  = ext4_mb_seq_groups_start,
.next   = ext4_mb_seq_groups_next,
.stop   = ext4_mb_seq_groups_stop,
.show   = ext4_mb_seq_groups_show,
 };
 
-static int ext4_mb_seq_groups_open(struct inode *inode, struct file *file)
-{
-   struct super_block *sb = PDE_DATA(inode);
-   int rc;
-
-   rc = seq_open(file, _mb_seq_groups_ops);
-   if (rc == 0) {
-   struct seq_file *m = file->private_data;
-   m->private = sb;
-   }
-   return rc;
-
-}
-
-const struct file_operations ext4_seq_mb_groups_fops = {
-   .open   = ext4_mb_seq_groups_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= seq_release,
-};
-
 static struct kmem_cache *get_groupinfo_cache(int blocksize_bits)
 {
int cache_index = blocksize_bits - EXT4_MIN_BLOCK_LOG_SIZE;
diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c
index 9ebd26c957c2..f34da0bb8f17 100644
--- a/fs/ext4/sysfs.c
+++ b/fs/ext4/sysfs.c
@@ -346,39 +346,9 @@ static struct kobject *ext4_root;
 
 static struct kobject *ext4_feat;
 
-#define PROC_FILE_SHOW_DEFN(name) \
-static int name##_open(struct inode *inode, struct file *file) \
-{ \
-   return single_open(file, ext4_seq_##name##_show, PDE_DATA(inode)); \
-} \
-\
-static const struct file_operations ext4_seq_##name##_fops = { \
-   .open   = name##_open, \
-   .read   = seq_read, \
-   .llseek = seq_lseek, \
-   .release= single_release, \
-}
-
-#define PROC_FILE_LIST(name) \
-   { __stringify(name), _seq_##name##_fops }
-
-PROC_FILE_SHOW_DEFN(es_shrinker_info);
-PROC_FILE_SHOW_DEFN(options);
-
-static const struct ext4_proc_files {
-   const char *name;
-   const struct file_operations *fops;
-} proc_files[] = {
-   PROC_FILE_LIST(options),
-   PROC_FILE_LIST(es_shrinker_info),
-   PROC_FILE_LIST(mb_groups),
-   { NULL, NULL },
-};
-
 int ext4_register_sysfs(struct super_block *sb)
 {
struct ext4_sb_info *sbi = EXT4_SB(sb);
-   const struct ext4_proc_files *p;
int err;
 
init_completion(>s_kobj_unregister);
@@ -392,11 +362,14 @@ int ext4_register_sysfs(struct super_block *sb)
 
if (ext4_proc_root)
sbi->s_proc = proc_mkdir(sb->s_id, ext4_proc_root);
-
if (sbi->s_proc) {
-   for (p = proc_files; p->name; p++)
-   proc_create_data(p->name, S_IRUGO, sbi->s_proc,
-p->fops, sb);
+   

[PATCH 31/42] hostap: switch to proc_create_{seq,single}_data

2018-05-16 Thread Christoph Hellwig
And use proc private data directly instead of doing a detour
through seq->private.

Signed-off-by: Christoph Hellwig 
---
 .../net/wireless/intersil/hostap/hostap_ap.c  |  70 ++---
 .../net/wireless/intersil/hostap/hostap_hw.c  |  17 +--
 .../wireless/intersil/hostap/hostap_proc.c| 143 +++---
 3 files changed, 39 insertions(+), 191 deletions(-)

diff --git a/drivers/net/wireless/intersil/hostap/hostap_ap.c 
b/drivers/net/wireless/intersil/hostap/hostap_ap.c
index 4f76f81dd3af..d1884b8913e7 100644
--- a/drivers/net/wireless/intersil/hostap/hostap_ap.c
+++ b/drivers/net/wireless/intersil/hostap/hostap_ap.c
@@ -69,7 +69,7 @@ static void prism2_send_mgmt(struct net_device *dev,
 #ifndef PRISM2_NO_PROCFS_DEBUG
 static int ap_debug_proc_show(struct seq_file *m, void *v)
 {
-   struct ap_data *ap = m->private;
+   struct ap_data *ap = PDE_DATA(file_inode(m->file));
 
seq_printf(m, "BridgedUnicastFrames=%u\n", ap->bridged_unicast);
seq_printf(m, "BridgedMulticastFrames=%u\n", ap->bridged_multicast);
@@ -81,18 +81,6 @@ static int ap_debug_proc_show(struct seq_file *m, void *v)
seq_printf(m, "tx_drop_nonassoc=%u\n", ap->tx_drop_nonassoc);
return 0;
 }
-
-static int ap_debug_proc_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, ap_debug_proc_show, PDE_DATA(inode));
-}
-
-static const struct file_operations ap_debug_proc_fops = {
-   .open   = ap_debug_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
 #endif /* PRISM2_NO_PROCFS_DEBUG */
 
 
@@ -333,7 +321,7 @@ void hostap_deauth_all_stas(struct net_device *dev, struct 
ap_data *ap,
 
 static int ap_control_proc_show(struct seq_file *m, void *v)
 {
-   struct ap_data *ap = m->private;
+   struct ap_data *ap = PDE_DATA(file_inode(m->file));
char *policy_txt;
struct mac_entry *entry;
 
@@ -365,20 +353,20 @@ static int ap_control_proc_show(struct seq_file *m, void 
*v)
 
 static void *ap_control_proc_start(struct seq_file *m, loff_t *_pos)
 {
-   struct ap_data *ap = m->private;
+   struct ap_data *ap = PDE_DATA(file_inode(m->file));
spin_lock_bh(>mac_restrictions.lock);
return seq_list_start_head(>mac_restrictions.mac_list, *_pos);
 }
 
 static void *ap_control_proc_next(struct seq_file *m, void *v, loff_t *_pos)
 {
-   struct ap_data *ap = m->private;
+   struct ap_data *ap = PDE_DATA(file_inode(m->file));
return seq_list_next(v, >mac_restrictions.mac_list, _pos);
 }
 
 static void ap_control_proc_stop(struct seq_file *m, void *v)
 {
-   struct ap_data *ap = m->private;
+   struct ap_data *ap = PDE_DATA(file_inode(m->file));
spin_unlock_bh(>mac_restrictions.lock);
 }
 
@@ -389,24 +377,6 @@ static const struct seq_operations ap_control_proc_seqops 
= {
.show   = ap_control_proc_show,
 };
 
-static int ap_control_proc_open(struct inode *inode, struct file *file)
-{
-   int ret = seq_open(file, _control_proc_seqops);
-   if (ret == 0) {
-   struct seq_file *m = file->private_data;
-   m->private = PDE_DATA(inode);
-   }
-   return ret;
-}
-
-static const struct file_operations ap_control_proc_fops = {
-   .open   = ap_control_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= seq_release,
-};
-
-
 int ap_control_add_mac(struct mac_restrictions *mac_restrictions, u8 *mac)
 {
struct mac_entry *entry;
@@ -585,20 +555,20 @@ static int prism2_ap_proc_show(struct seq_file *m, void 
*v)
 
 static void *prism2_ap_proc_start(struct seq_file *m, loff_t *_pos)
 {
-   struct ap_data *ap = m->private;
+   struct ap_data *ap = PDE_DATA(file_inode(m->file));
spin_lock_bh(>sta_table_lock);
return seq_list_start_head(>sta_list, *_pos);
 }
 
 static void *prism2_ap_proc_next(struct seq_file *m, void *v, loff_t *_pos)
 {
-   struct ap_data *ap = m->private;
+   struct ap_data *ap = PDE_DATA(file_inode(m->file));
return seq_list_next(v, >sta_list, _pos);
 }
 
 static void prism2_ap_proc_stop(struct seq_file *m, void *v)
 {
-   struct ap_data *ap = m->private;
+   struct ap_data *ap = PDE_DATA(file_inode(m->file));
spin_unlock_bh(>sta_table_lock);
 }
 
@@ -608,23 +578,6 @@ static const struct seq_operations prism2_ap_proc_seqops = 
{
.stop   = prism2_ap_proc_stop,
.show   = prism2_ap_proc_show,
 };
-
-static int prism2_ap_proc_open(struct inode *inode, struct file *file)
-{
-   int ret = seq_open(file, _ap_proc_seqops);
-   if (ret == 0) {
-   struct seq_file *m = file->private_data;
-   m->private = PDE_DATA(inode);
-   }
-   return ret;
-}
-
-static const struct file_operations prism2_ap_proc_fops = {
-   .open   = prism2_ap_proc_open,
-   .read   = seq_read,

Re: [PATCH 41/42] tty: replace ->proc_fops with ->proc_show

2018-05-16 Thread Greg Kroah-Hartman
On Wed, May 16, 2018 at 11:43:45AM +0200, Christoph Hellwig wrote:
> Just set up the show callback in the tty_operations, and use
> proc_create_single_data to create the file without additional
> boilerplace code.
> 
> Signed-off-by: Christoph Hellwig 

Reviewed-by: Greg Kroah-Hartman 


[PATCH 26/42] staging/rtl8192u: simplify procfs code

2018-05-16 Thread Christoph Hellwig
Unwind the registration loop into individual calls.  Switch to use
proc_create_single where applicable.

Also don't bother handling proc_create* failures - the driver works
perfectly fine without the proc files, and the cleanup will handle
missing files gracefully.

Signed-off-by: Christoph Hellwig 
---
 drivers/staging/rtl8192u/r8192U_core.c | 67 ++
 1 file changed, 14 insertions(+), 53 deletions(-)

diff --git a/drivers/staging/rtl8192u/r8192U_core.c 
b/drivers/staging/rtl8192u/r8192U_core.c
index d607c59761cf..7a0dbc0fa18e 100644
--- a/drivers/staging/rtl8192u/r8192U_core.c
+++ b/drivers/staging/rtl8192u/r8192U_core.c
@@ -646,64 +646,25 @@ static void rtl8192_proc_module_init(void)
rtl8192_proc = proc_mkdir(RTL819xU_MODULE_NAME, init_net.proc_net);
 }
 
-/*
- * seq_file wrappers for procfile show routines.
- */
-static int rtl8192_proc_open(struct inode *inode, struct file *file)
-{
-   struct net_device *dev = proc_get_parent_data(inode);
-   int (*show)(struct seq_file *, void *) = PDE_DATA(inode);
-
-   return single_open(file, show, dev);
-}
-
-static const struct file_operations rtl8192_proc_fops = {
-   .open   = rtl8192_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
-
-/*
- * Table of proc files we need to create.
- */
-struct rtl8192_proc_file {
-   char name[12];
-   int (*show)(struct seq_file *, void *);
-};
-
-static const struct rtl8192_proc_file rtl8192_proc_files[] = {
-   { "stats-rx",   _get_stats_rx },
-   { "stats-tx",   _get_stats_tx },
-   { "stats-ap",   _get_stats_ap },
-   { "registers",  _get_registers },
-   { "" }
-};
-
 static void rtl8192_proc_init_one(struct net_device *dev)
 {
-   const struct rtl8192_proc_file *f;
struct proc_dir_entry *dir;
 
-   if (rtl8192_proc) {
-   dir = proc_mkdir_data(dev->name, 0, rtl8192_proc, dev);
-   if (!dir) {
-   RT_TRACE(COMP_ERR,
-"Unable to initialize /proc/net/rtl8192/%s\n",
-dev->name);
-   return;
-   }
+   if (!rtl8192_proc)
+   return;
 
-   for (f = rtl8192_proc_files; f->name[0]; f++) {
-   if (!proc_create_data(f->name, S_IFREG | S_IRUGO, dir,
- _proc_fops, f->show)) {
-   RT_TRACE(COMP_ERR,
-"Unable to initialize 
/proc/net/rtl8192/%s/%s\n",
-dev->name, f->name);
-   return;
-   }
-   }
-   }
+   dir = proc_mkdir_data(dev->name, 0, rtl8192_proc, dev);
+   if (!dir)
+   return;
+
+   proc_create_single("stats-rx", S_IFREG | S_IRUGO, dir,
+   proc_get_stats_rx);
+   proc_create_single("stats-tx", S_IFREG | S_IRUGO, dir,
+   proc_get_stats_tx);
+   proc_create_single("stats-ap", S_IFREG | S_IRUGO, dir,
+   proc_get_stats_ap);
+   proc_create_single("registers", S_IFREG | S_IRUGO, dir,
+   proc_get_registers);
 }
 
 static void rtl8192_proc_remove_one(struct net_device *dev)
-- 
2.17.0



[PATCH 25/42] jfs: simplify procfs code

2018-05-16 Thread Christoph Hellwig
Use remove_proc_subtree to remove the whole subtree on cleanup, and
unwind the registration loop into individual calls.  Switch to use
proc_create_seq where applicable.

Signed-off-by: Christoph Hellwig 
---
 fs/jfs/jfs_debug.c| 43 ++-
 fs/jfs/jfs_debug.h| 10 +-
 fs/jfs/jfs_logmgr.c   | 14 +-
 fs/jfs/jfs_metapage.c | 14 +-
 fs/jfs/jfs_txnmgr.c   | 28 ++--
 fs/jfs/jfs_xtree.c| 14 +-
 6 files changed, 24 insertions(+), 99 deletions(-)

diff --git a/fs/jfs/jfs_debug.c b/fs/jfs/jfs_debug.c
index a70907606025..35a5b2a81ae0 100644
--- a/fs/jfs/jfs_debug.c
+++ b/fs/jfs/jfs_debug.c
@@ -29,7 +29,6 @@
 
 #ifdef PROC_FS_JFS /* see jfs_debug.h */
 
-static struct proc_dir_entry *base;
 #ifdef CONFIG_JFS_DEBUG
 static int jfs_loglevel_proc_show(struct seq_file *m, void *v)
 {
@@ -66,43 +65,29 @@ static const struct file_operations jfs_loglevel_proc_fops 
= {
 };
 #endif
 
-static struct {
-   const char  *name;
-   const struct file_operations *proc_fops;
-} Entries[] = {
-#ifdef CONFIG_JFS_STATISTICS
-   { "lmstats",_lmstats_proc_fops, },
-   { "txstats",_txstats_proc_fops, },
-   { "xtstat", _xtstat_proc_fops, },
-   { "mpstat", _mpstat_proc_fops, },
-#endif
-#ifdef CONFIG_JFS_DEBUG
-   { "TxAnchor",   _txanchor_proc_fops, },
-   { "loglevel",   _loglevel_proc_fops }
-#endif
-};
-#define NPROCENT   ARRAY_SIZE(Entries)
-
 void jfs_proc_init(void)
 {
-   int i;
+   struct proc_dir_entry *base;
 
-   if (!(base = proc_mkdir("fs/jfs", NULL)))
+   base = proc_mkdir("fs/jfs", NULL);
+   if (!base)
return;
 
-   for (i = 0; i < NPROCENT; i++)
-   proc_create(Entries[i].name, 0, base, Entries[i].proc_fops);
+#ifdef CONFIG_JFS_STATISTICS
+   proc_create_single("lmstats", 0, base, jfs_lmstats_proc_show);
+   proc_create_single("txstats", 0, base, jfs_txstats_proc_show);
+   proc_create_single("xtstat", 0, base, jfs_xtstat_proc_show);
+   proc_create_single("mpstat", 0, base, jfs_mpstat_proc_show);
+#endif
+#ifdef CONFIG_JFS_DEBUG
+   proc_create_single("TxAnchor", 0, base, jfs_txanchor_proc_show);
+   proc_create("loglevel", 0, base, _loglevel_proc_fops);
+#endif
 }
 
 void jfs_proc_clean(void)
 {
-   int i;
-
-   if (base) {
-   for (i = 0; i < NPROCENT; i++)
-   remove_proc_entry(Entries[i].name, base);
-   remove_proc_entry("fs/jfs", NULL);
-   }
+   remove_proc_subtree("fs/jfs", NULL);
 }
 
 #endif /* PROC_FS_JFS */
diff --git a/fs/jfs/jfs_debug.h b/fs/jfs/jfs_debug.h
index eafd1300a00b..0d9e35da8462 100644
--- a/fs/jfs/jfs_debug.h
+++ b/fs/jfs/jfs_debug.h
@@ -62,7 +62,7 @@ extern void jfs_proc_clean(void);
 
 extern int jfsloglevel;
 
-extern const struct file_operations jfs_txanchor_proc_fops;
+int jfs_txanchor_proc_show(struct seq_file *m, void *v);
 
 /* information message: e.g., configuration, major event */
 #define jfs_info(fmt, arg...) do { \
@@ -105,10 +105,10 @@ extern const struct file_operations 
jfs_txanchor_proc_fops;
  * --
  */
 #ifdef CONFIG_JFS_STATISTICS
-extern const struct file_operations jfs_lmstats_proc_fops;
-extern const struct file_operations jfs_txstats_proc_fops;
-extern const struct file_operations jfs_mpstat_proc_fops;
-extern const struct file_operations jfs_xtstat_proc_fops;
+int jfs_lmstats_proc_show(struct seq_file *m, void *v);
+int jfs_txstats_proc_show(struct seq_file *m, void *v);
+int jfs_mpstat_proc_show(struct seq_file *m, void *v);
+int jfs_xtstat_proc_show(struct seq_file *m, void *v);
 
 #defineINCREMENT(x)((x)++)
 #defineDECREMENT(x)((x)--)
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
index 0e5d412c0b01..6b68df395892 100644
--- a/fs/jfs/jfs_logmgr.c
+++ b/fs/jfs/jfs_logmgr.c
@@ -2493,7 +2493,7 @@ int lmLogFormat(struct jfs_log *log, s64 logAddress, int 
logSize)
 }
 
 #ifdef CONFIG_JFS_STATISTICS
-static int jfs_lmstats_proc_show(struct seq_file *m, void *v)
+int jfs_lmstats_proc_show(struct seq_file *m, void *v)
 {
seq_printf(m,
   "JFS Logmgr stats\n"
@@ -2510,16 +2510,4 @@ static int jfs_lmstats_proc_show(struct seq_file *m, 
void *v)
   lmStat.partial_page);
return 0;
 }
-
-static int jfs_lmstats_proc_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, jfs_lmstats_proc_show, NULL);
-}
-
-const struct file_operations jfs_lmstats_proc_fops = {
-   .open   = jfs_lmstats_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
 #endif /* CONFIG_JFS_STATISTICS */
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index 1a3b0cc22ad3..fa2c6824c7f2 100644
--- a/fs/jfs/jfs_metapage.c
+++ 

[PATCH 34/42] netfilter/x_tables: switch to proc_create_seq_private

2018-05-16 Thread Christoph Hellwig
And remove proc boilerplate code.

Signed-off-by: Christoph Hellwig 
---
 net/netfilter/x_tables.c | 42 ++--
 1 file changed, 6 insertions(+), 36 deletions(-)

diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 344dd01a5027..0e314f95a4a3 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -1648,22 +1648,6 @@ static const struct seq_operations xt_match_seq_ops = {
.show   = xt_match_seq_show,
 };
 
-static int xt_match_open(struct inode *inode, struct file *file)
-{
-   struct nf_mttg_trav *trav;
-   trav = __seq_open_private(file, _match_seq_ops, sizeof(*trav));
-   if (!trav)
-   return -ENOMEM;
-   return 0;
-}
-
-static const struct file_operations xt_match_ops = {
-   .open= xt_match_open,
-   .read= seq_read,
-   .llseek  = seq_lseek,
-   .release = seq_release_private,
-};
-
 static void *xt_target_seq_start(struct seq_file *seq, loff_t *pos)
 {
return xt_mttg_seq_start(seq, pos, true);
@@ -1698,22 +1682,6 @@ static const struct seq_operations xt_target_seq_ops = {
.show   = xt_target_seq_show,
 };
 
-static int xt_target_open(struct inode *inode, struct file *file)
-{
-   struct nf_mttg_trav *trav;
-   trav = __seq_open_private(file, _target_seq_ops, sizeof(*trav));
-   if (!trav)
-   return -ENOMEM;
-   return 0;
-}
-
-static const struct file_operations xt_target_ops = {
-   .open= xt_target_open,
-   .read= seq_read,
-   .llseek  = seq_lseek,
-   .release = seq_release_private,
-};
-
 #define FORMAT_TABLES  "_tables_names"
 #defineFORMAT_MATCHES  "_tables_matches"
 #define FORMAT_TARGETS "_tables_targets"
@@ -1787,8 +1755,9 @@ int xt_proto_init(struct net *net, u_int8_t af)
 
strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_MATCHES, sizeof(buf));
-   proc = proc_create_data(buf, 0440, net->proc_net, _match_ops,
-   (void *)(unsigned long)af);
+   proc = proc_create_seq_private(buf, 0440, net->proc_net,
+   _match_seq_ops, sizeof(struct nf_mttg_trav),
+   (void *)(unsigned long)af);
if (!proc)
goto out_remove_tables;
if (uid_valid(root_uid) && gid_valid(root_gid))
@@ -1796,8 +1765,9 @@ int xt_proto_init(struct net *net, u_int8_t af)
 
strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TARGETS, sizeof(buf));
-   proc = proc_create_data(buf, 0440, net->proc_net, _target_ops,
-   (void *)(unsigned long)af);
+   proc = proc_create_seq_private(buf, 0440, net->proc_net,
+_target_seq_ops, sizeof(struct nf_mttg_trav),
+(void *)(unsigned long)af);
if (!proc)
goto out_remove_matches;
if (uid_valid(root_uid) && gid_valid(root_gid))
-- 
2.17.0



[PATCH 27/42] resource: switch to proc_create_seq_data

2018-05-16 Thread Christoph Hellwig
And use the root resource directly from the proc private data.

Signed-off-by: Christoph Hellwig 
---
 kernel/resource.c | 43 +--
 1 file changed, 5 insertions(+), 38 deletions(-)

diff --git a/kernel/resource.c b/kernel/resource.c
index 2af6c03858b9..b589dda910b3 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -87,7 +87,7 @@ enum { MAX_IORES_LEVEL = 5 };
 static void *r_start(struct seq_file *m, loff_t *pos)
__acquires(resource_lock)
 {
-   struct resource *p = m->private;
+   struct resource *p = PDE_DATA(file_inode(m->file));
loff_t l = 0;
read_lock(_lock);
for (p = p->child; p && l < *pos; p = r_next(m, p, ))
@@ -103,7 +103,7 @@ static void r_stop(struct seq_file *m, void *v)
 
 static int r_show(struct seq_file *m, void *v)
 {
-   struct resource *root = m->private;
+   struct resource *root = PDE_DATA(file_inode(m->file));
struct resource *r = v, *p;
unsigned long long start, end;
int width = root->end < 0x1 ? 4 : 8;
@@ -135,44 +135,11 @@ static const struct seq_operations resource_op = {
.show   = r_show,
 };
 
-static int ioports_open(struct inode *inode, struct file *file)
-{
-   int res = seq_open(file, _op);
-   if (!res) {
-   struct seq_file *m = file->private_data;
-   m->private = _resource;
-   }
-   return res;
-}
-
-static int iomem_open(struct inode *inode, struct file *file)
-{
-   int res = seq_open(file, _op);
-   if (!res) {
-   struct seq_file *m = file->private_data;
-   m->private = _resource;
-   }
-   return res;
-}
-
-static const struct file_operations proc_ioports_operations = {
-   .open   = ioports_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= seq_release,
-};
-
-static const struct file_operations proc_iomem_operations = {
-   .open   = iomem_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= seq_release,
-};
-
 static int __init ioresources_init(void)
 {
-   proc_create("ioports", 0, NULL, _ioports_operations);
-   proc_create("iomem", 0, NULL, _iomem_operations);
+   proc_create_seq_data("ioports", 0, NULL, _op,
+   _resource);
+   proc_create_seq_data("iomem", 0, NULL, _op, _resource);
return 0;
 }
 __initcall(ioresources_init);
-- 
2.17.0



[PATCH 29/42] rtc/proc: switch to proc_create_single_data

2018-05-16 Thread Christoph Hellwig
And stop trying to get a reference on the submodule, procfs code deals
with release after an unloaded module and thus removed proc entry.

Signed-off-by: Christoph Hellwig 
Acked-by: Alexandre Belloni 
---
 drivers/rtc/rtc-proc.c | 33 ++---
 1 file changed, 2 insertions(+), 31 deletions(-)

diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c
index 31e7e23cc5be..a9dd9218fae2 100644
--- a/drivers/rtc/rtc-proc.c
+++ b/drivers/rtc/rtc-proc.c
@@ -107,40 +107,11 @@ static int rtc_proc_show(struct seq_file *seq, void 
*offset)
return 0;
 }
 
-static int rtc_proc_open(struct inode *inode, struct file *file)
-{
-   int ret;
-   struct rtc_device *rtc = PDE_DATA(inode);
-
-   if (!try_module_get(rtc->owner))
-   return -ENODEV;
-
-   ret = single_open(file, rtc_proc_show, rtc);
-   if (ret)
-   module_put(rtc->owner);
-   return ret;
-}
-
-static int rtc_proc_release(struct inode *inode, struct file *file)
-{
-   int res = single_release(inode, file);
-   struct rtc_device *rtc = PDE_DATA(inode);
-
-   module_put(rtc->owner);
-   return res;
-}
-
-static const struct file_operations rtc_proc_fops = {
-   .open   = rtc_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= rtc_proc_release,
-};
-
 void rtc_proc_add_device(struct rtc_device *rtc)
 {
if (is_rtc_hctosys(rtc))
-   proc_create_data("driver/rtc", 0, NULL, _proc_fops, rtc);
+   proc_create_single_data("driver/rtc", 0, NULL, rtc_proc_show,
+   rtc);
 }
 
 void rtc_proc_del_device(struct rtc_device *rtc)
-- 
2.17.0



[PATCH 36/42] atm: simplify procfs code

2018-05-16 Thread Christoph Hellwig
Use remove_proc_subtree to remove the whole subtree on cleanup, and
unwind the registration loop into individual calls.  Switch to use
proc_create_seq where applicable.

Also don't bother handling proc_create* failures - the driver works
perfectly fine without the proc files, and the cleanup will handle
missing files gracefully.

Signed-off-by: Christoph Hellwig 
---
 net/atm/proc.c | 65 ++
 1 file changed, 7 insertions(+), 58 deletions(-)

diff --git a/net/atm/proc.c b/net/atm/proc.c
index 55410c00c7e2..f272b0f59d82 100644
--- a/net/atm/proc.c
+++ b/net/atm/proc.c
@@ -257,18 +257,6 @@ static const struct seq_operations atm_dev_seq_ops = {
.show   = atm_dev_seq_show,
 };
 
-static int atm_dev_seq_open(struct inode *inode, struct file *file)
-{
-   return seq_open(file, _dev_seq_ops);
-}
-
-static const struct file_operations devices_seq_fops = {
-   .open   = atm_dev_seq_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= seq_release,
-};
-
 static int pvc_seq_show(struct seq_file *seq, void *v)
 {
static char atm_pvc_banner[] =
@@ -440,58 +428,19 @@ void atm_proc_dev_deregister(struct atm_dev *dev)
kfree(dev->proc_name);
 }
 
-static struct atm_proc_entry {
-   char *name;
-   const struct file_operations *proc_fops;
-   struct proc_dir_entry *dirent;
-} atm_proc_ents[] = {
-   { .name = "devices",.proc_fops = _seq_fops },
-   { .name = "pvc",.proc_fops = _seq_fops },
-   { .name = "svc",.proc_fops = _seq_fops },
-   { .name = "vc", .proc_fops = _seq_fops },
-   { .name = NULL, .proc_fops = NULL }
-};
-
-static void atm_proc_dirs_remove(void)
-{
-   static struct atm_proc_entry *e;
-
-   for (e = atm_proc_ents; e->name; e++) {
-   if (e->dirent)
-   remove_proc_entry(e->name, atm_proc_root);
-   }
-   remove_proc_entry("atm", init_net.proc_net);
-}
-
 int __init atm_proc_init(void)
 {
-   static struct atm_proc_entry *e;
-   int ret;
-
atm_proc_root = proc_net_mkdir(_net, "atm", init_net.proc_net);
if (!atm_proc_root)
-   goto err_out;
-   for (e = atm_proc_ents; e->name; e++) {
-   struct proc_dir_entry *dirent;
-
-   dirent = proc_create(e->name, 0444,
-atm_proc_root, e->proc_fops);
-   if (!dirent)
-   goto err_out_remove;
-   e->dirent = dirent;
-   }
-   ret = 0;
-out:
-   return ret;
-
-err_out_remove:
-   atm_proc_dirs_remove();
-err_out:
-   ret = -ENOMEM;
-   goto out;
+   return -ENOMEM;
+   proc_create_seq("devices", 0444, atm_proc_root, _dev_seq_ops);
+   proc_create("pvc", 0444, atm_proc_root, _seq_fops);
+   proc_create("svc", 0444, atm_proc_root, _seq_fops);
+   proc_create("vc", 0444, atm_proc_root, _seq_fops);
+   return 0;
 }
 
 void atm_proc_exit(void)
 {
-   atm_proc_dirs_remove();
+   remove_proc_subtree("atm", init_net.proc_net);
 }
-- 
2.17.0



[PATCH 30/42] bonding: switch to proc_create_seq_data

2018-05-16 Thread Christoph Hellwig
And use proc private data directly instead of doing a detour
through seq->private.

Signed-off-by: Christoph Hellwig 
---
 drivers/net/bonding/bond_procfs.c | 36 ++-
 1 file changed, 6 insertions(+), 30 deletions(-)

diff --git a/drivers/net/bonding/bond_procfs.c 
b/drivers/net/bonding/bond_procfs.c
index 01059f1a7bca..9f7d83e827c3 100644
--- a/drivers/net/bonding/bond_procfs.c
+++ b/drivers/net/bonding/bond_procfs.c
@@ -10,7 +10,7 @@
 static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
__acquires(RCU)
 {
-   struct bonding *bond = seq->private;
+   struct bonding *bond = PDE_DATA(file_inode(seq->file));
struct list_head *iter;
struct slave *slave;
loff_t off = 0;
@@ -29,7 +29,7 @@ static void *bond_info_seq_start(struct seq_file *seq, loff_t 
*pos)
 
 static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-   struct bonding *bond = seq->private;
+   struct bonding *bond = PDE_DATA(file_inode(seq->file));
struct list_head *iter;
struct slave *slave;
bool found = false;
@@ -56,7 +56,7 @@ static void bond_info_seq_stop(struct seq_file *seq, void *v)
 
 static void bond_info_show_master(struct seq_file *seq)
 {
-   struct bonding *bond = seq->private;
+   struct bonding *bond = PDE_DATA(file_inode(seq->file));
const struct bond_opt_value *optval;
struct slave *curr, *primary;
int i;
@@ -167,7 +167,7 @@ static void bond_info_show_master(struct seq_file *seq)
 static void bond_info_show_slave(struct seq_file *seq,
 const struct slave *slave)
 {
-   struct bonding *bond = seq->private;
+   struct bonding *bond = PDE_DATA(file_inode(seq->file));
 
seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
seq_printf(seq, "MII Status: %s\n", 
bond_slave_link_status(slave->link));
@@ -257,38 +257,14 @@ static const struct seq_operations bond_info_seq_ops = {
.show  = bond_info_seq_show,
 };
 
-static int bond_info_open(struct inode *inode, struct file *file)
-{
-   struct seq_file *seq;
-   int res;
-
-   res = seq_open(file, _info_seq_ops);
-   if (!res) {
-   /* recover the pointer buried in proc_dir_entry data */
-   seq = file->private_data;
-   seq->private = PDE_DATA(inode);
-   }
-
-   return res;
-}
-
-static const struct file_operations bond_info_fops = {
-   .owner   = THIS_MODULE,
-   .open= bond_info_open,
-   .read= seq_read,
-   .llseek  = seq_lseek,
-   .release = seq_release,
-};
-
 void bond_create_proc_entry(struct bonding *bond)
 {
struct net_device *bond_dev = bond->dev;
struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id);
 
if (bn->proc_dir) {
-   bond->proc_entry = proc_create_data(bond_dev->name,
-   0444, bn->proc_dir,
-   _info_fops, bond);
+   bond->proc_entry = proc_create_seq_data(bond_dev->name, 0444,
+   bn->proc_dir, _info_seq_ops, bond);
if (bond->proc_entry == NULL)
netdev_warn(bond_dev, "Cannot create /proc/net/%s/%s\n",
DRV_NAME, bond_dev->name);
-- 
2.17.0



[PATCH 39/42] ide: remove ide_driver_proc_write

2018-05-16 Thread Christoph Hellwig
The driver proc file hasn't been writeable for a long time, so this is
just dead code.

Signed-off-by: Christoph Hellwig 
Acked-by: "Eric W. Biederman" 
---
 drivers/ide/ide-proc.c | 46 --
 1 file changed, 46 deletions(-)

diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 863db44c7916..b3b8b8822d6a 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -528,58 +528,12 @@ static int ide_driver_proc_open(struct inode *inode, 
struct file *file)
return single_open(file, ide_driver_proc_show, PDE_DATA(inode));
 }
 
-static int ide_replace_subdriver(ide_drive_t *drive, const char *driver)
-{
-   struct device *dev = >gendev;
-   int ret = 1;
-   int err;
-
-   device_release_driver(dev);
-   /* FIXME: device can still be in use by previous driver */
-   strlcpy(drive->driver_req, driver, sizeof(drive->driver_req));
-   err = device_attach(dev);
-   if (err < 0)
-   printk(KERN_WARNING "IDE: %s: device_attach error: %d\n",
-   __func__, err);
-   drive->driver_req[0] = 0;
-   if (dev->driver == NULL) {
-   err = device_attach(dev);
-   if (err < 0)
-   printk(KERN_WARNING
-   "IDE: %s: device_attach(2) error: %d\n",
-   __func__, err);
-   }
-   if (dev->driver && !strcmp(dev->driver->name, driver))
-   ret = 0;
-
-   return ret;
-}
-
-static ssize_t ide_driver_proc_write(struct file *file, const char __user 
*buffer,
-size_t count, loff_t *pos)
-{
-   ide_drive_t *drive = PDE_DATA(file_inode(file));
-   char name[32];
-
-   if (!capable(CAP_SYS_ADMIN))
-   return -EACCES;
-   if (count > 31)
-   count = 31;
-   if (copy_from_user(name, buffer, count))
-   return -EFAULT;
-   name[count] = '\0';
-   if (ide_replace_subdriver(drive, name))
-   return -EINVAL;
-   return count;
-}
-
 static const struct file_operations ide_driver_proc_fops = {
.owner  = THIS_MODULE,
.open   = ide_driver_proc_open,
.read   = seq_read,
.llseek = seq_lseek,
.release= single_release,
-   .write  = ide_driver_proc_write,
 };
 
 static int ide_media_proc_show(struct seq_file *m, void *v)
-- 
2.17.0



[PATCH 32/42] neigh: switch to proc_create_seq_data

2018-05-16 Thread Christoph Hellwig
And use proc private data directly instead of doing a detour
through seq->private.

Signed-off-by: Christoph Hellwig 
---
 net/core/neighbour.c | 31 ++-
 1 file changed, 6 insertions(+), 25 deletions(-)

diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index ce519861be59..1fb43bff417d 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -59,7 +59,7 @@ static int pneigh_ifdown_and_unlock(struct neigh_table *tbl,
struct net_device *dev);
 
 #ifdef CONFIG_PROC_FS
-static const struct file_operations neigh_stat_seq_fops;
+static const struct seq_operations neigh_stat_seq_ops;
 #endif
 
 /*
@@ -1558,8 +1558,8 @@ void neigh_table_init(int index, struct neigh_table *tbl)
panic("cannot create neighbour cache statistics");
 
 #ifdef CONFIG_PROC_FS
-   if (!proc_create_data(tbl->id, 0, init_net.proc_net_stat,
- _stat_seq_fops, tbl))
+   if (!proc_create_seq_data(tbl->id, 0, init_net.proc_net_stat,
+ _stat_seq_ops, tbl))
panic("cannot create neighbour proc dir entry");
 #endif
 
@@ -2786,7 +2786,7 @@ EXPORT_SYMBOL(neigh_seq_stop);
 
 static void *neigh_stat_seq_start(struct seq_file *seq, loff_t *pos)
 {
-   struct neigh_table *tbl = seq->private;
+   struct neigh_table *tbl = PDE_DATA(file_inode(seq->file));
int cpu;
 
if (*pos == 0)
@@ -2803,7 +2803,7 @@ static void *neigh_stat_seq_start(struct seq_file *seq, 
loff_t *pos)
 
 static void *neigh_stat_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-   struct neigh_table *tbl = seq->private;
+   struct neigh_table *tbl = PDE_DATA(file_inode(seq->file));
int cpu;
 
for (cpu = *pos; cpu < nr_cpu_ids; ++cpu) {
@@ -2822,7 +2822,7 @@ static void neigh_stat_seq_stop(struct seq_file *seq, 
void *v)
 
 static int neigh_stat_seq_show(struct seq_file *seq, void *v)
 {
-   struct neigh_table *tbl = seq->private;
+   struct neigh_table *tbl = PDE_DATA(file_inode(seq->file));
struct neigh_statistics *st = v;
 
if (v == SEQ_START_TOKEN) {
@@ -2861,25 +2861,6 @@ static const struct seq_operations neigh_stat_seq_ops = {
.stop   = neigh_stat_seq_stop,
.show   = neigh_stat_seq_show,
 };
-
-static int neigh_stat_seq_open(struct inode *inode, struct file *file)
-{
-   int ret = seq_open(file, _stat_seq_ops);
-
-   if (!ret) {
-   struct seq_file *sf = file->private_data;
-   sf->private = PDE_DATA(inode);
-   }
-   return ret;
-};
-
-static const struct file_operations neigh_stat_seq_fops = {
-   .open= neigh_stat_seq_open,
-   .read= seq_read,
-   .llseek  = seq_lseek,
-   .release = seq_release,
-};
-
 #endif /* CONFIG_PROC_FS */
 
 static inline size_t neigh_nlmsg_size(void)
-- 
2.17.0



[PATCH 40/42] ide: replace ->proc_fops with ->proc_show

2018-05-16 Thread Christoph Hellwig
Just set up the show callback in the tty_operations, and use
proc_create_single_data to create the file without additional
boilerplace code.

Signed-off-by: Christoph Hellwig 
---
 drivers/ide/ide-cd.c  |  15 +---
 drivers/ide/ide-disk_proc.c   |  62 ++--
 drivers/ide/ide-floppy_proc.c |  17 +
 drivers/ide/ide-proc.c| 136 +-
 drivers/ide/ide-tape.c|  17 +
 include/linux/ide.h   |   6 +-
 6 files changed, 31 insertions(+), 222 deletions(-)

diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 5a8e8e3c22cd..b52a7bdace52 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -1426,21 +1426,8 @@ static int idecd_capacity_proc_show(struct seq_file *m, 
void *v)
return 0;
 }
 
-static int idecd_capacity_proc_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, idecd_capacity_proc_show, PDE_DATA(inode));
-}
-
-static const struct file_operations idecd_capacity_proc_fops = {
-   .owner  = THIS_MODULE,
-   .open   = idecd_capacity_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
-
 static ide_proc_entry_t idecd_proc[] = {
-   { "capacity", S_IFREG|S_IRUGO, _capacity_proc_fops },
+   { "capacity", S_IFREG|S_IRUGO, idecd_capacity_proc_show },
{}
 };
 
diff --git a/drivers/ide/ide-disk_proc.c b/drivers/ide/ide-disk_proc.c
index 82a36ced4e96..95d239b2f646 100644
--- a/drivers/ide/ide-disk_proc.c
+++ b/drivers/ide/ide-disk_proc.c
@@ -52,19 +52,6 @@ static int idedisk_cache_proc_show(struct seq_file *m, void 
*v)
return 0;
 }
 
-static int idedisk_cache_proc_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, idedisk_cache_proc_show, PDE_DATA(inode));
-}
-
-static const struct file_operations idedisk_cache_proc_fops = {
-   .owner  = THIS_MODULE,
-   .open   = idedisk_cache_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
-
 static int idedisk_capacity_proc_show(struct seq_file *m, void *v)
 {
ide_drive_t*drive = (ide_drive_t *)m->private;
@@ -73,19 +60,6 @@ static int idedisk_capacity_proc_show(struct seq_file *m, 
void *v)
return 0;
 }
 
-static int idedisk_capacity_proc_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, idedisk_capacity_proc_show, PDE_DATA(inode));
-}
-
-static const struct file_operations idedisk_capacity_proc_fops = {
-   .owner  = THIS_MODULE,
-   .open   = idedisk_capacity_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
-
 static int __idedisk_proc_show(struct seq_file *m, ide_drive_t *drive, u8 
sub_cmd)
 {
u8 *buf;
@@ -114,43 +88,17 @@ static int idedisk_sv_proc_show(struct seq_file *m, void 
*v)
return __idedisk_proc_show(m, m->private, ATA_SMART_READ_VALUES);
 }
 
-static int idedisk_sv_proc_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, idedisk_sv_proc_show, PDE_DATA(inode));
-}
-
-static const struct file_operations idedisk_sv_proc_fops = {
-   .owner  = THIS_MODULE,
-   .open   = idedisk_sv_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
-
 static int idedisk_st_proc_show(struct seq_file *m, void *v)
 {
return __idedisk_proc_show(m, m->private, ATA_SMART_READ_THRESHOLDS);
 }
 
-static int idedisk_st_proc_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, idedisk_st_proc_show, PDE_DATA(inode));
-}
-
-static const struct file_operations idedisk_st_proc_fops = {
-   .owner  = THIS_MODULE,
-   .open   = idedisk_st_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
-
 ide_proc_entry_t ide_disk_proc[] = {
-   { "cache",S_IFREG|S_IRUGO, _cache_proc_fops },
-   { "capacity", S_IFREG|S_IRUGO, _capacity_proc_fops  },
-   { "geometry", S_IFREG|S_IRUGO, _geometry_proc_fops  },
-   { "smart_values", S_IFREG|S_IRUSR, _sv_proc_fops},
-   { "smart_thresholds", S_IFREG|S_IRUSR, _st_proc_fops},
+   { "cache",S_IFREG|S_IRUGO, idedisk_cache_proc_show  },
+   { "capacity", S_IFREG|S_IRUGO, idedisk_capacity_proc_show   },
+   { "geometry", S_IFREG|S_IRUGO, ide_geometry_proc_show   },
+   { "smart_values", S_IFREG|S_IRUSR, idedisk_sv_proc_show },
+   { "smart_thresholds", S_IFREG|S_IRUSR, idedisk_st_proc_show },
{}
 };
 
diff --git a/drivers/ide/ide-floppy_proc.c b/drivers/ide/ide-floppy_proc.c
index 471457ebea67..7f697ddb5fe5 100644
--- 

[PATCH 33/42] netfilter/xt_hashlimit: switch to proc_create_{seq,single}_data

2018-05-16 Thread Christoph Hellwig
And use proc private data directly instead of doing a detour
through seq->private.

Signed-off-by: Christoph Hellwig 
---
 net/netfilter/xt_hashlimit.c | 92 +++-
 1 file changed, 18 insertions(+), 74 deletions(-)

diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index 0cd73567e7ff..9b16402f29af 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -57,9 +57,9 @@ static inline struct hashlimit_net *hashlimit_pernet(struct 
net *net)
 }
 
 /* need to declare this at the top */
-static const struct file_operations dl_file_ops_v2;
-static const struct file_operations dl_file_ops_v1;
-static const struct file_operations dl_file_ops;
+static const struct seq_operations dl_seq_ops_v2;
+static const struct seq_operations dl_seq_ops_v1;
+static const struct seq_operations dl_seq_ops;
 
 /* hash table crap */
 struct dsthash_dst {
@@ -272,7 +272,7 @@ static int htable_create(struct net *net, struct 
hashlimit_cfg3 *cfg,
 {
struct hashlimit_net *hashlimit_net = hashlimit_pernet(net);
struct xt_hashlimit_htable *hinfo;
-   const struct file_operations *fops;
+   const struct seq_operations *ops;
unsigned int size, i;
int ret;
 
@@ -321,19 +321,19 @@ static int htable_create(struct net *net, struct 
hashlimit_cfg3 *cfg,
 
switch (revision) {
case 1:
-   fops = _file_ops_v1;
+   ops = _seq_ops_v1;
break;
case 2:
-   fops = _file_ops_v2;
+   ops = _seq_ops_v2;
break;
default:
-   fops = _file_ops;
+   ops = _seq_ops;
}
 
-   hinfo->pde = proc_create_data(name, 0,
+   hinfo->pde = proc_create_seq_data(name, 0,
(family == NFPROTO_IPV4) ?
hashlimit_net->ipt_hashlimit : hashlimit_net->ip6t_hashlimit,
-   fops, hinfo);
+   ops, hinfo);
if (hinfo->pde == NULL) {
kfree(hinfo->name);
vfree(hinfo);
@@ -1057,7 +1057,7 @@ static struct xt_match hashlimit_mt_reg[] __read_mostly = 
{
 static void *dl_seq_start(struct seq_file *s, loff_t *pos)
__acquires(htable->lock)
 {
-   struct xt_hashlimit_htable *htable = s->private;
+   struct xt_hashlimit_htable *htable = PDE_DATA(file_inode(s->private));
unsigned int *bucket;
 
spin_lock_bh(>lock);
@@ -1074,7 +1074,7 @@ static void *dl_seq_start(struct seq_file *s, loff_t *pos)
 
 static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos)
 {
-   struct xt_hashlimit_htable *htable = s->private;
+   struct xt_hashlimit_htable *htable = PDE_DATA(file_inode(s->private));
unsigned int *bucket = v;
 
*pos = ++(*bucket);
@@ -1088,7 +1088,7 @@ static void *dl_seq_next(struct seq_file *s, void *v, 
loff_t *pos)
 static void dl_seq_stop(struct seq_file *s, void *v)
__releases(htable->lock)
 {
-   struct xt_hashlimit_htable *htable = s->private;
+   struct xt_hashlimit_htable *htable = PDE_DATA(file_inode(s->private));
unsigned int *bucket = v;
 
if (!IS_ERR(bucket))
@@ -1130,7 +1130,7 @@ static void dl_seq_print(struct dsthash_ent *ent, 
u_int8_t family,
 static int dl_seq_real_show_v2(struct dsthash_ent *ent, u_int8_t family,
   struct seq_file *s)
 {
-   const struct xt_hashlimit_htable *ht = s->private;
+   struct xt_hashlimit_htable *ht = PDE_DATA(file_inode(s->private));
 
spin_lock(>lock);
/* recalculate to show accurate numbers */
@@ -1145,7 +1145,7 @@ static int dl_seq_real_show_v2(struct dsthash_ent *ent, 
u_int8_t family,
 static int dl_seq_real_show_v1(struct dsthash_ent *ent, u_int8_t family,
   struct seq_file *s)
 {
-   const struct xt_hashlimit_htable *ht = s->private;
+   struct xt_hashlimit_htable *ht = PDE_DATA(file_inode(s->private));
 
spin_lock(>lock);
/* recalculate to show accurate numbers */
@@ -1160,7 +1160,7 @@ static int dl_seq_real_show_v1(struct dsthash_ent *ent, 
u_int8_t family,
 static int dl_seq_real_show(struct dsthash_ent *ent, u_int8_t family,
struct seq_file *s)
 {
-   const struct xt_hashlimit_htable *ht = s->private;
+   struct xt_hashlimit_htable *ht = PDE_DATA(file_inode(s->private));
 
spin_lock(>lock);
/* recalculate to show accurate numbers */
@@ -1174,7 +1174,7 @@ static int dl_seq_real_show(struct dsthash_ent *ent, 
u_int8_t family,
 
 static int dl_seq_show_v2(struct seq_file *s, void *v)
 {
-   struct xt_hashlimit_htable *htable = s->private;
+   struct xt_hashlimit_htable *htable = PDE_DATA(file_inode(s->private));
unsigned int *bucket = (unsigned int *)v;
struct dsthash_ent *ent;
 
@@ -1188,7 +1188,7 @@ static int dl_seq_show_v2(struct seq_file *s, void *v)
 
 static int dl_seq_show_v1(struct seq_file *s, 

[PATCH 41/42] tty: replace ->proc_fops with ->proc_show

2018-05-16 Thread Christoph Hellwig
Just set up the show callback in the tty_operations, and use
proc_create_single_data to create the file without additional
boilerplace code.

Signed-off-by: Christoph Hellwig 
---
 arch/ia64/hp/sim/simserial.c| 15 +--
 arch/xtensa/platforms/iss/console.c | 15 +--
 drivers/char/pcmcia/synclink_cs.c   | 15 +--
 drivers/mmc/core/sdio_uart.c| 15 +--
 drivers/staging/fwserial/fwserial.c | 15 +--
 drivers/tty/amiserial.c | 15 +--
 drivers/tty/cyclades.c  | 15 +--
 drivers/tty/serial/serial_core.c| 15 +--
 drivers/tty/synclink.c  | 15 +--
 drivers/tty/synclink_gt.c   | 15 +--
 drivers/tty/synclinkmp.c| 15 +--
 drivers/usb/serial/usb-serial.c | 15 +--
 fs/proc/proc_tty.c  |  6 +++---
 include/linux/tty_driver.h  |  2 +-
 14 files changed, 16 insertions(+), 172 deletions(-)

diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
index a419ccf33cde..663388a73d4e 100644
--- a/arch/ia64/hp/sim/simserial.c
+++ b/arch/ia64/hp/sim/simserial.c
@@ -435,19 +435,6 @@ static int rs_proc_show(struct seq_file *m, void *v)
return 0;
 }
 
-static int rs_proc_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, rs_proc_show, NULL);
-}
-
-static const struct file_operations rs_proc_fops = {
-   .owner  = THIS_MODULE,
-   .open   = rs_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
-
 static const struct tty_operations hp_ops = {
.open = rs_open,
.close = rs_close,
@@ -462,7 +449,7 @@ static const struct tty_operations hp_ops = {
.unthrottle = rs_unthrottle,
.send_xchar = rs_send_xchar,
.hangup = rs_hangup,
-   .proc_fops = _proc_fops,
+   .proc_show = rs_proc_show,
 };
 
 static const struct tty_port_operations hp_port_ops = {
diff --git a/arch/xtensa/platforms/iss/console.c 
b/arch/xtensa/platforms/iss/console.c
index 92f567f9a21e..af81a62faba6 100644
--- a/arch/xtensa/platforms/iss/console.c
+++ b/arch/xtensa/platforms/iss/console.c
@@ -153,19 +153,6 @@ static int rs_proc_show(struct seq_file *m, void *v)
return 0;
 }
 
-static int rs_proc_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, rs_proc_show, NULL);
-}
-
-static const struct file_operations rs_proc_fops = {
-   .owner  = THIS_MODULE,
-   .open   = rs_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
-
 static const struct tty_operations serial_ops = {
.open = rs_open,
.close = rs_close,
@@ -176,7 +163,7 @@ static const struct tty_operations serial_ops = {
.chars_in_buffer = rs_chars_in_buffer,
.hangup = rs_hangup,
.wait_until_sent = rs_wait_until_sent,
-   .proc_fops = _proc_fops,
+   .proc_show = rs_proc_show,
 };
 
 int __init rs_init(void)
diff --git a/drivers/char/pcmcia/synclink_cs.c 
b/drivers/char/pcmcia/synclink_cs.c
index aa502e9fb7fa..66b04194aa9f 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -2616,19 +2616,6 @@ static int mgslpc_proc_show(struct seq_file *m, void *v)
return 0;
 }
 
-static int mgslpc_proc_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, mgslpc_proc_show, NULL);
-}
-
-static const struct file_operations mgslpc_proc_fops = {
-   .owner  = THIS_MODULE,
-   .open   = mgslpc_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
-
 static int rx_alloc_buffers(MGSLPC_INFO *info)
 {
/* each buffer has header and data */
@@ -2815,7 +2802,7 @@ static const struct tty_operations mgslpc_ops = {
.tiocmget = tiocmget,
.tiocmset = tiocmset,
.get_icount = mgslpc_get_icount,
-   .proc_fops = _proc_fops,
+   .proc_show = mgslpc_proc_show,
 };
 
 static int __init synclink_cs_init(void)
diff --git a/drivers/mmc/core/sdio_uart.c b/drivers/mmc/core/sdio_uart.c
index d3c91f412b69..25e113001a3c 100644
--- a/drivers/mmc/core/sdio_uart.c
+++ b/drivers/mmc/core/sdio_uart.c
@@ -1008,19 +1008,6 @@ static int sdio_uart_proc_show(struct seq_file *m, void 
*v)
return 0;
 }
 
-static int sdio_uart_proc_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, sdio_uart_proc_show, NULL);
-}
-
-static const struct file_operations sdio_uart_proc_fops = {
-   .owner  = THIS_MODULE,
-   .open   = sdio_uart_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
-
 static const struct 

[PATCH 42/42] proc: update SIZEOF_PDE_INLINE_NAME for the new pde fields

2018-05-16 Thread Christoph Hellwig
This makes Alexey happy and Al groan.  Based on a patch from
Alexey Dobriyan.

Signed-off-by: Christoph Hellwig 
---
 fs/proc/internal.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 84c68508a256..a318ae5b36b4 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -62,9 +62,9 @@ struct proc_dir_entry {
umode_t mode;
u8 namelen;
 #ifdef CONFIG_64BIT
-#define SIZEOF_PDE_INLINE_NAME (192-139)
+#define SIZEOF_PDE_INLINE_NAME (192-155)
 #else
-#define SIZEOF_PDE_INLINE_NAME (128-87)
+#define SIZEOF_PDE_INLINE_NAME (128-95)
 #endif
char inline_name[SIZEOF_PDE_INLINE_NAME];
 } __randomize_layout;
-- 
2.17.0



[PATCH 35/42] bluetooth: switch to proc_create_seq_data

2018-05-16 Thread Christoph Hellwig
And use proc private data directly instead of doing a detour
through seq->private and private state.

Signed-off-by: Christoph Hellwig 
---
 net/bluetooth/af_bluetooth.c | 40 +---
 1 file changed, 5 insertions(+), 35 deletions(-)

diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 84d92a077834..3264e1873219 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -605,15 +605,10 @@ int bt_sock_wait_ready(struct sock *sk, unsigned long 
flags)
 EXPORT_SYMBOL(bt_sock_wait_ready);
 
 #ifdef CONFIG_PROC_FS
-struct bt_seq_state {
-   struct bt_sock_list *l;
-};
-
 static void *bt_seq_start(struct seq_file *seq, loff_t *pos)
__acquires(seq->private->l->lock)
 {
-   struct bt_seq_state *s = seq->private;
-   struct bt_sock_list *l = s->l;
+   struct bt_sock_list *l = PDE_DATA(file_inode(seq->file));
 
read_lock(>lock);
return seq_hlist_start_head(>head, *pos);
@@ -621,8 +616,7 @@ static void *bt_seq_start(struct seq_file *seq, loff_t *pos)
 
 static void *bt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-   struct bt_seq_state *s = seq->private;
-   struct bt_sock_list *l = s->l;
+   struct bt_sock_list *l = PDE_DATA(file_inode(seq->file));
 
return seq_hlist_next(v, >head, pos);
 }
@@ -630,16 +624,14 @@ static void *bt_seq_next(struct seq_file *seq, void *v, 
loff_t *pos)
 static void bt_seq_stop(struct seq_file *seq, void *v)
__releases(seq->private->l->lock)
 {
-   struct bt_seq_state *s = seq->private;
-   struct bt_sock_list *l = s->l;
+   struct bt_sock_list *l = PDE_DATA(file_inode(seq->file));
 
read_unlock(>lock);
 }
 
 static int bt_seq_show(struct seq_file *seq, void *v)
 {
-   struct bt_seq_state *s = seq->private;
-   struct bt_sock_list *l = s->l;
+   struct bt_sock_list *l = PDE_DATA(file_inode(seq->file));
 
if (v == SEQ_START_TOKEN) {
seq_puts(seq ,"sk   RefCnt Rmem   Wmem   User   
Inode  Parent");
@@ -681,35 +673,13 @@ static const struct seq_operations bt_seq_ops = {
.show  = bt_seq_show,
 };
 
-static int bt_seq_open(struct inode *inode, struct file *file)
-{
-   struct bt_sock_list *sk_list;
-   struct bt_seq_state *s;
-
-   sk_list = PDE_DATA(inode);
-   s = __seq_open_private(file, _seq_ops,
-  sizeof(struct bt_seq_state));
-   if (!s)
-   return -ENOMEM;
-
-   s->l = sk_list;
-   return 0;
-}
-
-static const struct file_operations bt_fops = {
-   .open = bt_seq_open,
-   .read = seq_read,
-   .llseek = seq_lseek,
-   .release = seq_release_private
-};
-
 int bt_procfs_init(struct net *net, const char *name,
   struct bt_sock_list *sk_list,
   int (* seq_show)(struct seq_file *, void *))
 {
sk_list->custom_seq_show = seq_show;
 
-   if (!proc_create_data(name, 0, net->proc_net, _fops, sk_list))
+   if (!proc_create_seq_data(name, 0, net->proc_net, _seq_ops, sk_list))
return -ENOMEM;
return 0;
 }
-- 
2.17.0



[PATCH 37/42] atm: switch to proc_create_seq_private

2018-05-16 Thread Christoph Hellwig
And remove proc boilerplate code.

Signed-off-by: Christoph Hellwig 
---
 net/atm/proc.c | 72 +-
 1 file changed, 13 insertions(+), 59 deletions(-)

diff --git a/net/atm/proc.c b/net/atm/proc.c
index f272b0f59d82..0b0495a41bbe 100644
--- a/net/atm/proc.c
+++ b/net/atm/proc.c
@@ -68,7 +68,6 @@ static void atm_dev_info(struct seq_file *seq, const struct 
atm_dev *dev)
 struct vcc_state {
int bucket;
struct sock *sk;
-   int family;
 };
 
 static inline int compare_family(struct sock *sk, int family)
@@ -106,23 +105,13 @@ static int __vcc_walk(struct sock **sock, int family, int 
*bucket, loff_t l)
return (l < 0);
 }
 
-static inline void *vcc_walk(struct vcc_state *state, loff_t l)
+static inline void *vcc_walk(struct seq_file *seq, loff_t l)
 {
-   return __vcc_walk(>sk, state->family, >bucket, l) ?
-  state : NULL;
-}
-
-static int __vcc_seq_open(struct inode *inode, struct file *file,
-   int family, const struct seq_operations *ops)
-{
-   struct vcc_state *state;
-
-   state = __seq_open_private(file, ops, sizeof(*state));
-   if (state == NULL)
-   return -ENOMEM;
+   struct vcc_state *state = seq->private;
+   int family = (uintptr_t)(PDE_DATA(file_inode(seq->file)));
 
-   state->family = family;
-   return 0;
+   return __vcc_walk(>sk, family, >bucket, l) ?
+  state : NULL;
 }
 
 static void *vcc_seq_start(struct seq_file *seq, loff_t *pos)
@@ -133,7 +122,7 @@ static void *vcc_seq_start(struct seq_file *seq, loff_t 
*pos)
 
read_lock(_sklist_lock);
state->sk = SEQ_START_TOKEN;
-   return left ? vcc_walk(state, left) : SEQ_START_TOKEN;
+   return left ? vcc_walk(seq, left) : SEQ_START_TOKEN;
 }
 
 static void vcc_seq_stop(struct seq_file *seq, void *v)
@@ -144,9 +133,7 @@ static void vcc_seq_stop(struct seq_file *seq, void *v)
 
 static void *vcc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-   struct vcc_state *state = seq->private;
-
-   v = vcc_walk(state, 1);
+   v = vcc_walk(seq, 1);
*pos += !!PTR_ERR(v);
return v;
 }
@@ -280,18 +267,6 @@ static const struct seq_operations pvc_seq_ops = {
.show   = pvc_seq_show,
 };
 
-static int pvc_seq_open(struct inode *inode, struct file *file)
-{
-   return __vcc_seq_open(inode, file, PF_ATMPVC, _seq_ops);
-}
-
-static const struct file_operations pvc_seq_fops = {
-   .open   = pvc_seq_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= seq_release_private,
-};
-
 static int vcc_seq_show(struct seq_file *seq, void *v)
 {
if (v == SEQ_START_TOKEN) {
@@ -314,18 +289,6 @@ static const struct seq_operations vcc_seq_ops = {
.show   = vcc_seq_show,
 };
 
-static int vcc_seq_open(struct inode *inode, struct file *file)
-{
-   return __vcc_seq_open(inode, file, 0, _seq_ops);
-}
-
-static const struct file_operations vcc_seq_fops = {
-   .open   = vcc_seq_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= seq_release_private,
-};
-
 static int svc_seq_show(struct seq_file *seq, void *v)
 {
static const char atm_svc_banner[] =
@@ -349,18 +312,6 @@ static const struct seq_operations svc_seq_ops = {
.show   = svc_seq_show,
 };
 
-static int svc_seq_open(struct inode *inode, struct file *file)
-{
-   return __vcc_seq_open(inode, file, PF_ATMSVC, _seq_ops);
-}
-
-static const struct file_operations svc_seq_fops = {
-   .open   = svc_seq_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= seq_release_private,
-};
-
 static ssize_t proc_dev_atm_read(struct file *file, char __user *buf,
 size_t count, loff_t *pos)
 {
@@ -434,9 +385,12 @@ int __init atm_proc_init(void)
if (!atm_proc_root)
return -ENOMEM;
proc_create_seq("devices", 0444, atm_proc_root, _dev_seq_ops);
-   proc_create("pvc", 0444, atm_proc_root, _seq_fops);
-   proc_create("svc", 0444, atm_proc_root, _seq_fops);
-   proc_create("vc", 0444, atm_proc_root, _seq_fops);
+   proc_create_seq_private("pvc", 0444, atm_proc_root, _seq_ops,
+   sizeof(struct vcc_state), (void *)(uintptr_t)PF_ATMPVC);
+   proc_create_seq_private("svc", 0444, atm_proc_root, _seq_ops,
+   sizeof(struct vcc_state), (void *)(uintptr_t)PF_ATMSVC);
+   proc_create_seq_private("vc", 0444, atm_proc_root, _seq_ops,
+   sizeof(struct vcc_state), NULL);
return 0;
 }
 
-- 
2.17.0



[PATCH 38/42] isdn: replace ->proc_fops with ->proc_show

2018-05-16 Thread Christoph Hellwig
And switch to proc_create_single_data.

Signed-off-by: Christoph Hellwig 
---
 drivers/isdn/capi/kcapi.c  |  3 ++-
 drivers/isdn/gigaset/capi.c| 16 +---
 drivers/isdn/hardware/avm/avmcard.h|  4 ++--
 drivers/isdn/hardware/avm/b1.c | 17 ++---
 drivers/isdn/hardware/avm/b1dma.c  | 17 ++---
 drivers/isdn/hardware/avm/b1isa.c  |  2 +-
 drivers/isdn/hardware/avm/b1pci.c  |  4 ++--
 drivers/isdn/hardware/avm/b1pcmcia.c   |  2 +-
 drivers/isdn/hardware/avm/c4.c | 15 +--
 drivers/isdn/hardware/avm/t1isa.c  |  2 +-
 drivers/isdn/hardware/avm/t1pci.c  |  2 +-
 drivers/isdn/hardware/eicon/capimain.c | 15 +--
 drivers/isdn/hysdn/hycapi.c| 15 +--
 include/linux/isdn/capilli.h   |  2 +-
 net/bluetooth/cmtp/capi.c  | 14 +-
 15 files changed, 20 insertions(+), 110 deletions(-)

diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
index 46c189ad8d94..0ff517d3c98f 100644
--- a/drivers/isdn/capi/kcapi.c
+++ b/drivers/isdn/capi/kcapi.c
@@ -534,7 +534,8 @@ int attach_capi_ctr(struct capi_ctr *ctr)
init_waitqueue_head(>state_wait_queue);
 
sprintf(ctr->procfn, "capi/controllers/%d", ctr->cnr);
-   ctr->procent = proc_create_data(ctr->procfn, 0, NULL, ctr->proc_fops, 
ctr);
+   ctr->procent = proc_create_single_data(ctr->procfn, 0, NULL,
+   ctr->proc_show, ctr);
 
ncontrollers++;
 
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c
index ccec7778cad2..dac5cd35e901 100644
--- a/drivers/isdn/gigaset/capi.c
+++ b/drivers/isdn/gigaset/capi.c
@@ -2437,19 +2437,6 @@ static int gigaset_proc_show(struct seq_file *m, void *v)
return 0;
 }
 
-static int gigaset_proc_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, gigaset_proc_show, PDE_DATA(inode));
-}
-
-static const struct file_operations gigaset_proc_fops = {
-   .owner  = THIS_MODULE,
-   .open   = gigaset_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
-
 /**
  * gigaset_isdn_regdev() - register device to LL
  * @cs:device descriptor structure.
@@ -2478,8 +2465,7 @@ int gigaset_isdn_regdev(struct cardstate *cs, const char 
*isdnid)
iif->ctr.register_appl = gigaset_register_appl;
iif->ctr.release_appl  = gigaset_release_appl;
iif->ctr.send_message  = gigaset_send_message;
-   iif->ctr.procinfo  = gigaset_procinfo;
-   iif->ctr.proc_fops = _proc_fops;
+   iif->ctr.proc_show = gigaset_proc_show,
INIT_LIST_HEAD(>appls);
skb_queue_head_init(>sendqueue);
atomic_set(>sendqlen, 0);
diff --git a/drivers/isdn/hardware/avm/avmcard.h 
b/drivers/isdn/hardware/avm/avmcard.h
index c95712dbfa9f..cdfa89c71997 100644
--- a/drivers/isdn/hardware/avm/avmcard.h
+++ b/drivers/isdn/hardware/avm/avmcard.h
@@ -556,7 +556,7 @@ u16  b1_send_message(struct capi_ctr *ctrl, struct sk_buff 
*skb);
 void b1_parse_version(avmctrl_info *card);
 irqreturn_t b1_interrupt(int interrupt, void *devptr);
 
-extern const struct file_operations b1ctl_proc_fops;
+int b1_proc_show(struct seq_file *m, void *v);
 
 avmcard_dmainfo *avmcard_dma_alloc(char *name, struct pci_dev *,
   long rsize, long ssize);
@@ -576,6 +576,6 @@ void b1dma_register_appl(struct capi_ctr *ctrl,
 capi_register_params *rp);
 void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl);
 u16  b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
-extern const struct file_operations b1dmactl_proc_fops;
+int b1dma_proc_show(struct seq_file *m, void *v);
 
 #endif /* _AVMCARD_H_ */
diff --git a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c
index b1833d08a5fe..5ee5489d3f15 100644
--- a/drivers/isdn/hardware/avm/b1.c
+++ b/drivers/isdn/hardware/avm/b1.c
@@ -637,7 +637,7 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr)
 }
 
 /* - */
-static int b1ctl_proc_show(struct seq_file *m, void *v)
+int b1_proc_show(struct seq_file *m, void *v)
 {
struct capi_ctr *ctrl = m->private;
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
@@ -699,20 +699,7 @@ static int b1ctl_proc_show(struct seq_file *m, void *v)
 
return 0;
 }
-
-static int b1ctl_proc_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, b1ctl_proc_show, PDE_DATA(inode));
-}
-
-const struct file_operations b1ctl_proc_fops = {
-   .owner  = THIS_MODULE,
-   .open   = b1ctl_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
-EXPORT_SYMBOL(b1ctl_proc_fops);
+EXPORT_SYMBOL(b1_proc_show);
 
 /* 

[PATCH 23/42] afs: simplify procfs code

2018-05-16 Thread Christoph Hellwig
Use remove_proc_subtree to remove the whole subtree on cleanup, and
unwind the registration loop into individual calls.  Switch to use
proc_create_seq where applicable.

Signed-off-by: Christoph Hellwig 
---
 fs/afs/proc.c | 134 ++
 1 file changed, 15 insertions(+), 119 deletions(-)

diff --git a/fs/afs/proc.c b/fs/afs/proc.c
index 839a22280606..3aad32762989 100644
--- a/fs/afs/proc.c
+++ b/fs/afs/proc.c
@@ -62,7 +62,6 @@ static const struct file_operations afs_proc_rootcell_fops = {
.llseek = no_llseek,
 };
 
-static int afs_proc_cell_volumes_open(struct inode *inode, struct file *file);
 static void *afs_proc_cell_volumes_start(struct seq_file *p, loff_t *pos);
 static void *afs_proc_cell_volumes_next(struct seq_file *p, void *v,
loff_t *pos);
@@ -76,15 +75,6 @@ static const struct seq_operations afs_proc_cell_volumes_ops 
= {
.show   = afs_proc_cell_volumes_show,
 };
 
-static const struct file_operations afs_proc_cell_volumes_fops = {
-   .open   = afs_proc_cell_volumes_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= seq_release,
-};
-
-static int afs_proc_cell_vlservers_open(struct inode *inode,
-   struct file *file);
 static void *afs_proc_cell_vlservers_start(struct seq_file *p, loff_t *pos);
 static void *afs_proc_cell_vlservers_next(struct seq_file *p, void *v,
  loff_t *pos);
@@ -98,14 +88,6 @@ static const struct seq_operations 
afs_proc_cell_vlservers_ops = {
.show   = afs_proc_cell_vlservers_show,
 };
 
-static const struct file_operations afs_proc_cell_vlservers_fops = {
-   .open   = afs_proc_cell_vlservers_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= seq_release,
-};
-
-static int afs_proc_servers_open(struct inode *inode, struct file *file);
 static void *afs_proc_servers_start(struct seq_file *p, loff_t *pos);
 static void *afs_proc_servers_next(struct seq_file *p, void *v,
loff_t *pos);
@@ -119,13 +101,6 @@ static const struct seq_operations afs_proc_servers_ops = {
.show   = afs_proc_servers_show,
 };
 
-static const struct file_operations afs_proc_servers_fops = {
-   .open   = afs_proc_servers_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= seq_release,
-};
-
 static int afs_proc_sysname_open(struct inode *inode, struct file *file);
 static int afs_proc_sysname_release(struct inode *inode, struct file *file);
 static void *afs_proc_sysname_start(struct seq_file *p, loff_t *pos);
@@ -152,7 +127,7 @@ static const struct file_operations afs_proc_sysname_fops = 
{
.write  = afs_proc_sysname_write,
 };
 
-static const struct file_operations afs_proc_stats_fops;
+static int afs_proc_stats_show(struct seq_file *m, void *v);
 
 /*
  * initialise the /proc/fs/afs/ directory
@@ -167,8 +142,8 @@ int afs_proc_init(struct afs_net *net)
 
if (!proc_create("cells", 0644, net->proc_afs, _proc_cells_fops) ||
!proc_create("rootcell", 0644, net->proc_afs, 
_proc_rootcell_fops) ||
-   !proc_create("servers", 0644, net->proc_afs, 
_proc_servers_fops) ||
-   !proc_create("stats", 0644, net->proc_afs, _proc_stats_fops) ||
+   !proc_create_seq("servers", 0644, net->proc_afs, 
_proc_servers_ops) ||
+   !proc_create_single("stats", 0644, net->proc_afs, 
afs_proc_stats_show) ||
!proc_create("sysname", 0644, net->proc_afs, 
_proc_sysname_fops))
goto error_tree;
 
@@ -196,16 +171,7 @@ void afs_proc_cleanup(struct afs_net *net)
  */
 static int afs_proc_cells_open(struct inode *inode, struct file *file)
 {
-   struct seq_file *m;
-   int ret;
-
-   ret = seq_open(file, _proc_cells_ops);
-   if (ret < 0)
-   return ret;
-
-   m = file->private_data;
-   m->private = PDE_DATA(inode);
-   return 0;
+   return seq_open(file, _proc_cells_ops);
 }
 
 /*
@@ -430,10 +396,11 @@ int afs_proc_cell_setup(struct afs_net *net, struct 
afs_cell *cell)
if (!dir)
goto error_dir;
 
-   if (!proc_create_data("vlservers", 0, dir,
- _proc_cell_vlservers_fops, cell) ||
-   !proc_create_data("volumes", 0, dir,
- _proc_cell_volumes_fops, cell))
+   if (!proc_create_seq_data("vlservers", 0, dir,
+   _proc_cell_vlservers_ops, cell))
+   goto error_tree;
+   if (!proc_create_seq_data("volumes", 0, dir, _proc_cell_volumes_ops,
+   cell))
goto error_tree;
 
_leave(" = 0");
@@ -458,29 +425,6 @@ void afs_proc_cell_remove(struct afs_net *net, struct 
afs_cell *cell)

[PATCH 28/42] drbd: switch to proc_create_single

2018-05-16 Thread Christoph Hellwig
And stop messing with try_module_get on THIS_MODULE, which doesn't make
any sense here.

Signed-off-by: Christoph Hellwig 
---
 drivers/block/drbd/drbd_int.h  |  2 +-
 drivers/block/drbd/drbd_main.c |  3 ++-
 drivers/block/drbd/drbd_proc.c | 34 +-
 3 files changed, 4 insertions(+), 35 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 06ecee1b528e..461ddec04e7c 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1643,7 +1643,7 @@ void drbd_bump_write_ordering(struct drbd_resource 
*resource, struct drbd_backin
 
 /* drbd_proc.c */
 extern struct proc_dir_entry *drbd_proc;
-extern const struct file_operations drbd_proc_fops;
+int drbd_seq_show(struct seq_file *seq, void *v);
 
 /* drbd_actlog.c */
 extern bool drbd_al_begin_io_prepare(struct drbd_device *device, struct 
drbd_interval *i);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 185f1ef00a7c..c2d154faac02 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -3010,7 +3010,8 @@ static int __init drbd_init(void)
goto fail;
 
err = -ENOMEM;
-   drbd_proc = proc_create_data("drbd", S_IFREG | S_IRUGO , NULL, 
_proc_fops, NULL);
+   drbd_proc = proc_create_single("drbd", S_IFREG | S_IRUGO , NULL,
+   drbd_seq_show);
if (!drbd_proc) {
pr_err("unable to register proc file\n");
goto fail;
diff --git a/drivers/block/drbd/drbd_proc.c b/drivers/block/drbd/drbd_proc.c
index 582caeb0de86..74ef29247bb5 100644
--- a/drivers/block/drbd/drbd_proc.c
+++ b/drivers/block/drbd/drbd_proc.c
@@ -33,18 +33,7 @@
 #include 
 #include "drbd_int.h"
 
-static int drbd_proc_open(struct inode *inode, struct file *file);
-static int drbd_proc_release(struct inode *inode, struct file *file);
-
-
 struct proc_dir_entry *drbd_proc;
-const struct file_operations drbd_proc_fops = {
-   .owner  = THIS_MODULE,
-   .open   = drbd_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= drbd_proc_release,
-};
 
 static void seq_printf_with_thousands_grouping(struct seq_file *seq, long v)
 {
@@ -235,7 +224,7 @@ static void drbd_syncer_progress(struct drbd_device 
*device, struct seq_file *se
}
 }
 
-static int drbd_seq_show(struct seq_file *seq, void *v)
+int drbd_seq_show(struct seq_file *seq, void *v)
 {
int i, prev_i = -1;
const char *sn;
@@ -345,24 +334,3 @@ static int drbd_seq_show(struct seq_file *seq, void *v)
 
return 0;
 }
-
-static int drbd_proc_open(struct inode *inode, struct file *file)
-{
-   int err;
-
-   if (try_module_get(THIS_MODULE)) {
-   err = single_open(file, drbd_seq_show, NULL);
-   if (err)
-   module_put(THIS_MODULE);
-   return err;
-   }
-   return -ENODEV;
-}
-
-static int drbd_proc_release(struct inode *inode, struct file *file)
-{
-   module_put(THIS_MODULE);
-   return single_release(inode, file);
-}
-
-/* PROC FS stuff end */
-- 
2.17.0



[PATCH 21/42] megaraid: simplify procfs code

2018-05-16 Thread Christoph Hellwig
Use remove_proc_subtree to remove the whole subtree on cleanup, and
unwind the registration loop into individual calls.  Switch to use
proc_create_single.

Also don't bother handling proc_create* failures - the driver works
perfectly fine without the proc files, and the cleanup will handle
missing files gracefully.

Signed-off-by: Christoph Hellwig 
---
 drivers/scsi/megaraid.c | 140 +++-
 drivers/scsi/megaraid.h |  12 
 2 files changed, 36 insertions(+), 116 deletions(-)

diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 7195cff51d4c..91f5e2c68dbc 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -2731,53 +2731,6 @@ proc_show_rdrv_40(struct seq_file *m, void *v)
return proc_show_rdrv(m, m->private, 30, 39);
 }
 
-
-/*
- * seq_file wrappers for procfile show routines.
- */
-static int mega_proc_open(struct inode *inode, struct file *file)
-{
-   adapter_t *adapter = proc_get_parent_data(inode);
-   int (*show)(struct seq_file *, void *) = PDE_DATA(inode);
-
-   return single_open(file, show, adapter);
-}
-
-static const struct file_operations mega_proc_fops = {
-   .open   = mega_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
-
-/*
- * Table of proc files we need to create.
- */
-struct mega_proc_file {
-   const char *name;
-   unsigned short ptr_offset;
-   int (*show) (struct seq_file *m, void *v);
-};
-
-static const struct mega_proc_file mega_proc_files[] = {
-   { "config",   offsetof(adapter_t, proc_read), proc_show_config 
},
-   { "stat", offsetof(adapter_t, proc_stat), proc_show_stat },
-   { "mailbox",  offsetof(adapter_t, proc_mbox), proc_show_mbox },
-#if MEGA_HAVE_ENH_PROC
-   { "rebuild-rate", offsetof(adapter_t, proc_rr), 
proc_show_rebuild_rate },
-   { "battery-status",   offsetof(adapter_t, proc_battery), 
proc_show_battery },
-   { "diskdrives-ch0",   offsetof(adapter_t, proc_pdrvstat[0]), 
proc_show_pdrv_ch0 },
-   { "diskdrives-ch1",   offsetof(adapter_t, proc_pdrvstat[1]), 
proc_show_pdrv_ch1 },
-   { "diskdrives-ch2",   offsetof(adapter_t, proc_pdrvstat[2]), 
proc_show_pdrv_ch2 },
-   { "diskdrives-ch3",   offsetof(adapter_t, proc_pdrvstat[3]), 
proc_show_pdrv_ch3 },
-   { "raiddrives-0-9",   offsetof(adapter_t, proc_rdrvstat[0]), 
proc_show_rdrv_10 },
-   { "raiddrives-10-19", offsetof(adapter_t, proc_rdrvstat[1]), 
proc_show_rdrv_20 },
-   { "raiddrives-20-29", offsetof(adapter_t, proc_rdrvstat[2]), 
proc_show_rdrv_30 },
-   { "raiddrives-30-39", offsetof(adapter_t, proc_rdrvstat[3]), 
proc_show_rdrv_40 },
-#endif
-   { NULL }
-};
-
 /**
  * mega_create_proc_entry()
  * @index - index in soft state array
@@ -2788,31 +2741,45 @@ static const struct mega_proc_file mega_proc_files[] = {
 static void
 mega_create_proc_entry(int index, struct proc_dir_entry *parent)
 {
-   const struct mega_proc_file *f;
-   adapter_t   *adapter = hba_soft_state[index];
-   struct proc_dir_entry   *dir, *de, **ppde;
-   u8  string[16];
+   adapter_t *adapter = hba_soft_state[index];
+   struct proc_dir_entry *dir;
+   u8 string[16];
 
sprintf(string, "hba%d", adapter->host->host_no);
-
-   dir = adapter->controller_proc_dir_entry =
-   proc_mkdir_data(string, 0, parent, adapter);
-   if(!dir) {
+   dir = proc_mkdir_data(string, 0, parent, adapter);
+   if (!dir) {
dev_warn(>dev->dev, "proc_mkdir failed\n");
return;
}
 
-   for (f = mega_proc_files; f->name; f++) {
-   de = proc_create_data(f->name, S_IRUSR, dir, _proc_fops,
- f->show);
-   if (!de) {
-   dev_warn(>dev->dev, "proc_create failed\n");
-   return;
-   }
-
-   ppde = (void *)adapter + f->ptr_offset;
-   *ppde = de;
-   }
+   proc_create_single_data("config", S_IRUSR, dir,
+   proc_show_config, adapter);
+   proc_create_single_data("stat", S_IRUSR, dir,
+   proc_show_stat, adapter);
+   proc_create_single_data("mailbox", S_IRUSR, dir,
+   proc_show_mbox, adapter);
+#if MEGA_HAVE_ENH_PROC
+   proc_create_single_data("rebuild-rate", S_IRUSR, dir,
+   proc_show_rebuild_rate, adapter);
+   proc_create_single_data("battery-status", S_IRUSR, dir,
+   proc_show_battery, adapter);
+   proc_create_single_data("diskdrives-ch0", S_IRUSR, dir,
+   proc_show_pdrv_ch0, adapter);
+   proc_create_single_data("diskdrives-ch1", S_IRUSR, dir,
+   proc_show_pdrv_ch1, adapter);
+   proc_create_single_data("diskdrives-ch2", S_IRUSR, 

[PATCH 18/42] proc: introduce proc_create_net_single

2018-05-16 Thread Christoph Hellwig
Variant of proc_create_data that directly take a seq_file show
callback and deals with network namespaces in ->open and ->release.
All callers of proc_create + single_open_net converted over, and
single_{open,release}_net are removed entirely.

Signed-off-by: Christoph Hellwig 
---
 fs/proc/proc_net.c |  49 -
 include/linux/proc_fs.h|   4 ++
 include/linux/seq_file_net.h   |   7 +-
 net/can/bcm.c  |  16 +
 net/can/proc.c | 127 ++---
 net/ipv4/fib_trie.c|  16 +
 net/ipv4/proc.c|  48 ++---
 net/ipv6/proc.c|  31 ++--
 net/ipv6/route.c   |  15 +---
 net/kcm/kcmproc.c  |  16 +
 net/netfilter/ipvs/ip_vs_ctl.c |  31 ++--
 net/sctp/proc.c|  17 +
 net/xfrm/xfrm_proc.c   |  16 +
 13 files changed, 86 insertions(+), 307 deletions(-)

diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c
index c99fd183f034..7d94fa005b0d 100644
--- a/fs/proc/proc_net.c
+++ b/fs/proc/proc_net.c
@@ -93,37 +93,50 @@ struct proc_dir_entry *proc_create_net_data(const char 
*name, umode_t mode,
 }
 EXPORT_SYMBOL_GPL(proc_create_net_data);
 
-int single_open_net(struct inode *inode, struct file *file,
-   int (*show)(struct seq_file *, void *))
+static int single_open_net(struct inode *inode, struct file *file)
 {
-   int err;
+   struct proc_dir_entry *de = PDE(inode);
struct net *net;
+   int err;
 
-   err = -ENXIO;
net = get_proc_net(inode);
-   if (net == NULL)
-   goto err_net;
-
-   err = single_open(file, show, net);
-   if (err < 0)
-   goto err_open;
-
-   return 0;
+   if (!net)
+   return -ENXIO;
 
-err_open:
-   put_net(net);
-err_net:
+   err = single_open(file, de->single_show, net);
+   if (err)
+   put_net(net);
return err;
 }
-EXPORT_SYMBOL_GPL(single_open_net);
 
-int single_release_net(struct inode *ino, struct file *f)
+static int single_release_net(struct inode *ino, struct file *f)
 {
struct seq_file *seq = f->private_data;
put_net(seq->private);
return single_release(ino, f);
 }
-EXPORT_SYMBOL_GPL(single_release_net);
+
+static const struct file_operations proc_net_single_fops = {
+   .open   = single_open_net,
+   .read   = seq_read,
+   .llseek = seq_lseek,
+   .release= single_release_net,
+};
+
+struct proc_dir_entry *proc_create_net_single(const char *name, umode_t mode,
+   struct proc_dir_entry *parent,
+   int (*show)(struct seq_file *, void *), void *data)
+{
+   struct proc_dir_entry *p;
+
+   p = proc_create_reg(name, mode, , data);
+   if (!p)
+   return NULL;
+   p->proc_fops = _net_single_fops;
+   p->single_show = show;
+   return proc_register(parent, p);
+}
+EXPORT_SYMBOL_GPL(proc_create_net_single);
 
 static struct net *get_proc_task_net(struct inode *dir)
 {
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 9dcde9644253..e518352137e7 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -58,6 +58,9 @@ struct proc_dir_entry *proc_create_net_data(const char *name, 
umode_t mode,
unsigned int state_size, void *data);
 #define proc_create_net(name, mode, parent, state_size, ops) \
proc_create_net_data(name, mode, parent, state_size, ops, NULL)
+struct proc_dir_entry *proc_create_net_single(const char *name, umode_t mode,
+   struct proc_dir_entry *parent,
+   int (*show)(struct seq_file *, void *), void *data);
 
 #else /* CONFIG_PROC_FS */
 
@@ -97,6 +100,7 @@ static inline int remove_proc_subtree(const char *name, 
struct proc_dir_entry *p
 
 #define proc_create_net_data(name, mode, parent, ops, state_size, data) 
({NULL;})
 #define proc_create_net(name, mode, parent, state_size, ops) ({NULL;})
+#define proc_create_net_single(name, mode, parent, show, data) ({NULL;})
 
 #endif /* CONFIG_PROC_FS */
 
diff --git a/include/linux/seq_file_net.h b/include/linux/seq_file_net.h
index 5ea18a16291a..0fdbe1ddd8d1 100644
--- a/include/linux/seq_file_net.h
+++ b/include/linux/seq_file_net.h
@@ -13,9 +13,6 @@ struct seq_net_private {
 #endif
 };
 
-int single_open_net(struct inode *, struct file *file,
-   int (*show)(struct seq_file *, void *));
-int single_release_net(struct inode *, struct file *);
 static inline struct net *seq_file_net(struct seq_file *seq)
 {
 #ifdef CONFIG_NET_NS
@@ -26,8 +23,8 @@ static inline struct net *seq_file_net(struct seq_file *seq)
 }
 
 /*
- * This one is needed for single_open_net since net is stored directly in
- * private not as a struct i.e. seq_file_net can't be used.
+ * This one is needed for proc_create_net_single since net is stored directly
+ * in private not as a struct i.e. seq_file_net 

[PATCH 16/42] net: move seq_file_single_net to

2018-05-16 Thread Christoph Hellwig
This helper deals with single_{open,release}_net internals and thus
belongs here.

Signed-off-by: Christoph Hellwig 
---
 include/linux/seq_file_net.h | 13 +
 include/net/ip_vs.h  | 12 
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/include/linux/seq_file_net.h b/include/linux/seq_file_net.h
index 43ccd84127b6..ed20faa99e05 100644
--- a/include/linux/seq_file_net.h
+++ b/include/linux/seq_file_net.h
@@ -28,4 +28,17 @@ static inline struct net *seq_file_net(struct seq_file *seq)
 #endif
 }
 
+/*
+ * This one is needed for single_open_net since net is stored directly in
+ * private not as a struct i.e. seq_file_net can't be used.
+ */
+static inline struct net *seq_file_single_net(struct seq_file *seq)
+{
+#ifdef CONFIG_NET_NS
+   return (struct net *)seq->private;
+#else
+   return _net;
+#endif
+}
+
 #endif
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index eb0bec043c96..aea7a124e66b 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -41,18 +41,6 @@ static inline struct netns_ipvs *net_ipvs(struct net* net)
return net->ipvs;
 }
 
-/* This one needed for single_open_net since net is stored directly in
- * private not as a struct i.e. seq_file_net can't be used.
- */
-static inline struct net *seq_file_single_net(struct seq_file *seq)
-{
-#ifdef CONFIG_NET_NS
-   return (struct net *)seq->private;
-#else
-   return _net;
-#endif
-}
-
 /* Connections' size value needed by ip_vs_ctl.c */
 extern int ip_vs_conn_tab_size;
 
-- 
2.17.0



RE: [PATCH 4/4] scsi: ufs: make ufshcd_config_pwr_mode of non-static func

2018-05-16 Thread Avri Altman


> -Original Message-
> From: linux-scsi-ow...@vger.kernel.org 
> On Behalf Of Alim Akhtar
> Sent: Sunday, May 06, 2018 1:14 PM
> To: linux-scsi@vger.kernel.org; linux-ker...@vger.kernel.org
> Cc: j...@linux.vnet.ibm.com; martin.peter...@oracle.com;
> vivek.gau...@codeaurora.org; subha...@codeaurora.org;
> vinholika...@gmail.com; o...@lixom.net; alim.akh...@samsung.com
> Subject: [PATCH 4/4] scsi: ufs: make ufshcd_config_pwr_mode of non-static
> func
> 
> This makes ufshcd_config_pwr_mode non-static so that other vendors like
> exynos can use the same.
> 
> Signed-off-by: Seungwon Jeon 
> Signed-off-by: Alim Akhtar 
Acked-by: Avri Altman 

Might be also useful exporting an API for all uic commands?

Thanks,
Avri