[PATCH 09/12] hpsa: reduce warning messages on device removal

2017-10-20 Thread Don Brace
Reviewed-by: Scott Benesh 
Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 27a1aca..228d744 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1865,11 +1865,13 @@ static void 
hpsa_wait_for_outstanding_commands_for_dev(struct ctlr_info *h,
break;
if (++waits > 20)
break;
+   msleep(1000);
+   }
+
+   if (waits > 20)
dev_warn(>pdev->dev,
"%s: removing device with %d outstanding commands!\n",
__func__, cmds);
-   msleep(1000);
-   }
 }
 
 static void hpsa_remove_device(struct ctlr_info *h,



[PATCH 10/12] hpsa: correct logical volume removal

2017-10-20 Thread Don Brace
Suggested-by: Martin Wilck 
Reviewed-by: Scott Benesh 
Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 228d744..a536ed6 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1882,6 +1882,12 @@ static void hpsa_remove_device(struct ctlr_info *h,
if (!h->scsi_host)
return;
 
+   /*
+* Allow for commands to drain
+*/
+   device->removed = 1;
+   hpsa_wait_for_outstanding_commands_for_dev(h, device);
+
if (is_logical_device(device)) { /* RAID */
sdev = scsi_device_lookup(h->scsi_host, device->bus,
device->target, device->lun);
@@ -1899,9 +1905,6 @@ static void hpsa_remove_device(struct ctlr_info *h,
}
} else { /* HBA */
 
-   device->removed = 1;
-   hpsa_wait_for_outstanding_commands_for_dev(h, device);
-
hpsa_remove_sas_device(device);
}
 }



[PATCH 08/12] hpsa: update queue depth for externals

2017-10-20 Thread Don Brace
- preserve external device queue depth during a
  scan operation.

Reviewed-by: Scott Benesh 
Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 6a998b0..27a1aca 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1765,8 +1765,12 @@ static void hpsa_figure_phys_disk_ptrs(struct ctlr_info 
*h,
 * way too high for partial stripe writes
 */
logical_drive->queue_depth = qdepth;
-   else
-   logical_drive->queue_depth = h->nr_cmds;
+   else {
+   if (logical_drive->external)
+   logical_drive->queue_depth = EXTERNAL_QD;
+   else
+   logical_drive->queue_depth = h->nr_cmds;
+   }
 }
 
 static void hpsa_update_log_drive_phys_drive_ptrs(struct ctlr_info *h,



[PATCH 07/12] hpsa: correct smart path enabled

2017-10-20 Thread Don Brace
- correct re-enabling ioaccel after:
  1) RAID transformations and
  2) multi-path fail-overs.

Reviewed-by: Scott Benesh 
Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |  189 +--
 1 file changed, 151 insertions(+), 38 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 4ab53df..6a998b0 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -787,7 +787,12 @@ static ssize_t host_show_hp_ssd_smart_path_enabled(struct 
device *dev,
}
offload_enabled = hdev->offload_enabled;
spin_unlock_irqrestore(>lock, flags);
-   return snprintf(buf, 20, "%d\n", offload_enabled);
+
+   if (hdev->devtype == TYPE_DISK || hdev->devtype == TYPE_ZBC)
+   return snprintf(buf, 20, "%d\n", offload_enabled);
+   else
+   return snprintf(buf, 40, "%s\n",
+   "Not applicable for a controller");
 }
 
 #define MAX_PATHS 8
@@ -1270,7 +1275,7 @@ static void hpsa_show_dev_msg(const char *level, struct 
ctlr_info *h,
dev->model,
label,
dev->offload_config ? '+' : '-',
-   dev->offload_enabled ? '+' : '-',
+   dev->offload_to_be_enabled ? '+' : '-',
dev->expose_device);
 }
 
@@ -1345,36 +1350,42 @@ static int hpsa_scsi_add_entry(struct ctlr_info *h,
(*nadded)++;
hpsa_show_dev_msg(KERN_INFO, h, device,
device->expose_device ? "added" : "masked");
-   device->offload_to_be_enabled = device->offload_enabled;
-   device->offload_enabled = 0;
return 0;
 }
 
-/* Update an entry in h->dev[] array. */
+/*
+ * Called during a scan operation.
+ *
+ * Update an entry in h->dev[] array.
+ */
 static void hpsa_scsi_update_entry(struct ctlr_info *h,
int entry, struct hpsa_scsi_dev_t *new_entry)
 {
-   int offload_enabled;
/* assumes h->devlock is held */
BUG_ON(entry < 0 || entry >= HPSA_MAX_DEVICES);
 
/* Raid level changed. */
h->dev[entry]->raid_level = new_entry->raid_level;
 
+   /*
+* ioacccel_handle may have changed for a dual domain disk
+*/
+   h->dev[entry]->ioaccel_handle = new_entry->ioaccel_handle;
+
/* Raid offload parameters changed.  Careful about the ordering. */
-   if (new_entry->offload_config && new_entry->offload_enabled) {
+   if (new_entry->offload_config && new_entry->offload_to_be_enabled) {
/*
 * if drive is newly offload_enabled, we want to copy the
 * raid map data first.  If previously offload_enabled and
 * offload_config were set, raid map data had better be
-* the same as it was before.  if raid map data is changed
+* the same as it was before. If raid map data has changed
 * then it had better be the case that
 * h->dev[entry]->offload_enabled is currently 0.
 */
h->dev[entry]->raid_map = new_entry->raid_map;
h->dev[entry]->ioaccel_handle = new_entry->ioaccel_handle;
}
-   if (new_entry->hba_ioaccel_enabled) {
+   if (new_entry->offload_to_be_enabled) {
h->dev[entry]->ioaccel_handle = new_entry->ioaccel_handle;
wmb(); /* set ioaccel_handle *before* hba_ioaccel_enabled */
}
@@ -1385,17 +1396,18 @@ static void hpsa_scsi_update_entry(struct ctlr_info *h,
 
/*
 * We can turn off ioaccel offload now, but need to delay turning
-* it on until we can update h->dev[entry]->phys_disk[], but we
+* ioaccel on until we can update h->dev[entry]->phys_disk[], but we
 * can't do that until all the devices are updated.
 */
-   h->dev[entry]->offload_to_be_enabled = new_entry->offload_enabled;
-   if (!new_entry->offload_enabled)
+   h->dev[entry]->offload_to_be_enabled = new_entry->offload_to_be_enabled;
+
+   /*
+* turn ioaccel off immediately if told to do so.
+*/
+   if (!new_entry->offload_to_be_enabled)
h->dev[entry]->offload_enabled = 0;
 
-   offload_enabled = h->dev[entry]->offload_enabled;
-   h->dev[entry]->offload_enabled = h->dev[entry]->offload_to_be_enabled;
hpsa_show_dev_msg(KERN_INFO, h, h->dev[entry], "updated");
-   h->dev[entry]->offload_enabled = offload_enabled;
 }
 
 /* Replace an entry from h->dev[] array. */
@@ -1421,9 +1433,8 @@ static void hpsa_scsi_replace_entry(struct ctlr_info *h,
h->dev[entry] = new_entry;
added[*nadded] = new_entry;
(*nadded)++;
+
hpsa_show_dev_msg(KERN_INFO, h, new_entry, "replaced");
-   new_entry->offload_to_be_enabled 

[PATCH 11/12] hpsa: add enclosure logical identifier

2017-10-20 Thread Don Brace
add support for enclosure logical identifier

Reviewed-by: Scott Benesh 
Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   69 ++-
 1 file changed, 67 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index a536ed6..5428a4c 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -2965,6 +2965,57 @@ static void hpsa_scsi_interpret_error(struct ctlr_info 
*h,
}
 }
 
+static int hpsa_do_receive_diagnostic(struct ctlr_info *h, u8 *scsi3addr,
+   u8 page, u8 *buf, size_t bufsize)
+{
+   int rc = IO_OK;
+   struct CommandList *c;
+   struct ErrorInfo *ei;
+
+   c = cmd_alloc(h);
+   if (fill_cmd(c, RECEIVE_DIAGNOSTIC, h, buf, bufsize,
+   page, scsi3addr, TYPE_CMD)) {
+   rc = -1;
+   goto out;
+   }
+   rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
+   PCI_DMA_FROMDEVICE, NO_TIMEOUT);
+   if (rc)
+   goto out;
+   ei = c->err_info;
+   if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) {
+   hpsa_scsi_interpret_error(h, c);
+   rc = -1;
+   }
+out:
+   cmd_free(h, c);
+   return rc;
+}
+
+static u64 hpsa_get_enclosure_logical_identifier(struct ctlr_info *h,
+   u8 *scsi3addr)
+{
+   u8 *buf;
+   u64 sa = 0;
+   int rc = 0;
+
+   buf = kzalloc(1024, GFP_KERNEL);
+   if (!buf)
+   return 0;
+
+   rc = hpsa_do_receive_diagnostic(h, scsi3addr, RECEIVE_DIAGNOSTIC,
+   buf, 1024);
+
+   if (rc)
+   goto out;
+
+   sa = get_unaligned_be64(buf+12);
+
+out:
+   kfree(buf);
+   return sa;
+}
+
 static int hpsa_scsi_do_inquiry(struct ctlr_info *h, unsigned char *scsi3addr,
u16 page, unsigned char *buf,
unsigned char bufsize)
@@ -3400,6 +3451,9 @@ static void hpsa_get_enclosure_info(struct ctlr_info *h,
 
bmic_device_index = GET_BMIC_DRIVE_NUMBER(>lunid[0]);
 
+   encl_dev->sas_address =
+   hpsa_get_enclosure_logical_identifier(h, scsi3addr);
+
if (encl_dev->target == -1 || encl_dev->lun == -1) {
rc = IO_OK;
goto out;
@@ -6571,6 +6625,17 @@ static int fill_cmd(struct CommandList *c, u8 cmd, 
struct ctlr_info *h,
c->Request.CDB[0] = HPSA_INQUIRY;
c->Request.CDB[4] = size & 0xFF;
break;
+   case RECEIVE_DIAGNOSTIC:
+   c->Request.CDBLen = 6;
+   c->Request.type_attr_dir =
+   TYPE_ATTR_DIR(cmd_type, ATTR_SIMPLE, XFER_READ);
+   c->Request.Timeout = 0;
+   c->Request.CDB[0] = cmd;
+   c->Request.CDB[1] = 1;
+   c->Request.CDB[2] = 1;
+   c->Request.CDB[3] = (size >> 8) & 0xFF;
+   c->Request.CDB[4] = size & 0xFF;
+   break;
case HPSA_REPORT_LOG:
case HPSA_REPORT_PHYS:
/* Talking to controller so It's a physical command
@@ -9508,7 +9573,7 @@ static int hpsa_add_sas_host(struct ctlr_info *h)
struct hpsa_sas_port *hpsa_sas_port;
struct hpsa_sas_phy *hpsa_sas_phy;
 
-   parent_dev = >scsi_host->shost_gendev;
+   parent_dev = >scsi_host->shost_dev;
 
hpsa_sas_node = hpsa_alloc_sas_node(parent_dev);
if (!hpsa_sas_node)
@@ -9599,7 +9664,7 @@ hpsa_sas_get_linkerrors(struct sas_phy *phy)
 static int
 hpsa_sas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
 {
-   *identifier = 0;
+   *identifier = rphy->identify.sas_address;
return 0;
 }
 



[PATCH 04/12] hpsa: add controller checkpoint

2017-10-20 Thread Don Brace
tell hpsa controller to generate a checkpoint for rare lockup
conditions.

Reviewed-by: Scott Benesh 
Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |4 
 drivers/scsi/hpsa_cmd.h |1 +
 2 files changed, 5 insertions(+)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 0330f17..9c491c5 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -8009,6 +8009,10 @@ static void controller_lockup_detected(struct ctlr_info 
*h)
spin_unlock_irqrestore(>lock, flags);
dev_warn(>pdev->dev, "Controller lockup detected: 0x%08x after %d\n",
lockup_detected, h->heartbeat_sample_interval / HZ);
+   if (lockup_detected == 0x) {
+   dev_warn(>pdev->dev, "Telling controller to do a CHKPT\n");
+   writel(DOORBELL_GENERATE_CHKPT, h->vaddr + SA5_DOORBELL);
+   }
pci_disable_device(h->pdev);
fail_all_outstanding_cmds(h);
 }
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index 078afe4..78c3b64 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -142,6 +142,7 @@
 #define DOORBELL_CTLR_RESET0x0004l
 #define DOORBELL_CTLR_RESET2   0x0020l
 #define DOORBELL_CLEAR_EVENTS  0x0040l
+#define DOORBELL_GENERATE_CHKPT0x0080l
 
 #define CFGTBL_Trans_Simple 0x0002l
 #define CFGTBL_Trans_Performant 0x0004l



[PATCH 12/12] hpsa: bump driver version

2017-10-20 Thread Don Brace
Reviewed-by: Gerry Morong 
Reviewed-by: Scott Benesh 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 5428a4c..e514489 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -60,7 +60,7 @@
  * HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.'
  * with an optional trailing '-' followed by a byte value (0-255).
  */
-#define HPSA_DRIVER_VERSION "3.4.20-0"
+#define HPSA_DRIVER_VERSION "3.4.20-125"
 #define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")"
 #define HPSA "hpsa"
 



[PATCH 00/12] hpsa updates

2017-10-20 Thread Don Brace
These patches are based on Linus's tree

The changes are:

hpsa: update discovery polling
 - Correct corner case for RBODs with no initial volumes.

hpsa: add controller checkpoint
 - Provide method to generate a controller checkpoint.

hpsa: change timeout for internal cmds
 - There are times when the default time-out value has
   proven to be too small.

hpsa: correct smart path enabled
 - Correct some corner cases where the ioaccel path is not
   re-enabled after a multipath failover or a transformation.

hpsa: update queue depth for externals
 - A re-scan can change the queue-depth of external
   logical volumes.

hpsa: reduce warning messages on device removal
 - Repeated warnings are not necessary.

hpsa: correct logical volume removal
 - Also check for outstanding commands during logical volume removal.

hpsa: add enclosure logical identifier
 - Populate sysfs enclosure_identifier.

hpsa: destroy sas transport properties before scsi_host
 - This patch was proposed by Martin Wilck on 10/21/2016:
   https://www.spinics.net/lists/linux-scsi/msg102085.html
 - but had no effect until Hannes's patch:
   commit 9441284fbc39 ("scsi-fixup-kernel-warning-during-rmmod")
   was applied to the kernel.
 - Re-submitting with Martin Wilck's permission.

hpsa: cleanup sas_phy structures in sysfs when unloading
 - This patch was proposed by Martin Wilck on 10/21/2016:
   https://www.spinics.net/lists/linux-scsi/msg102083.html
 - cleans up dangling symlinks in sysfs.
 - Re-submitting with Martin Wilck's permission.

hpsa: clear tmpdevice in scan thread
 - Clean up some meta data issues for devices during a re-scan.

hpsa: bump driver version

---

Bader Ali Saleh (1):
  hpsa: update discovery polling

Don Brace (8):
  hpsa: add controller checkpoint
  hpsa: change timeout for internal cmds
  hpsa: correct smart path enabled
  hpsa: update queue depth for externals
  hpsa: reduce warning messages on device removal
  hpsa: correct logical volume removal
  hpsa: add enclosure logical identifier
  hpsa: bump driver version

Martin Wilck (2):
  hpsa: destroy sas transport properties before scsi_host
  hpsa: cleanup sas_phy structures in sysfs when unloading

Scott Teel (1):
  hpsa: clear tmpdevice in scan thread


 drivers/scsi/hpsa.c |  356 +--
 drivers/scsi/hpsa_cmd.h |3 
 2 files changed, 284 insertions(+), 75 deletions(-)

--
Signature


[PATCH 05/12] hpsa: update discovery polling

2017-10-20 Thread Don Brace
From: Bader Ali Saleh 

Correct a corner case where newly created volumes are not
detected automatically on an external RAID controller that has
no configured volumes during initial device discovery.

The fix is to set the discovery_polling flag when an external
RAID controller is detected. This causes a device rescan
every 20-30 seconds, so that newly created volumes will
be detected automatically.

Reviewed-by: Scott Benesh 
Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   39 ++-
 drivers/scsi/hpsa_cmd.h |2 ++
 2 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 9c491c5..6056bbd 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3472,6 +3472,30 @@ static void hpsa_get_sas_address(struct ctlr_info *h, 
unsigned char *scsi3addr,
dev->sas_address = sa;
 }
 
+static void hpsa_ext_ctrl_present(struct ctlr_info *h,
+   struct ReportExtendedLUNdata *physdev)
+{
+   u32 nphysicals;
+   int i;
+
+   if (h->discovery_polling)
+   return;
+
+   nphysicals = (get_unaligned_be32(physdev->LUNListLength) / 24) + 1;
+
+   for (i = 0; i < nphysicals; i++) {
+   if (physdev->LUN[i].device_type ==
+   BMIC_DEVICE_TYPE_CONTROLLER
+   && !is_hba_lunid(physdev->LUN[i].lunid)) {
+   dev_info(>pdev->dev,
+   "External controller present, activate 
discovery polling and disable rld caching\n");
+   hpsa_disable_rld_caching(h);
+   h->discovery_polling = 1;
+   break;
+   }
+   }
+}
+
 /* Get a device id from inquiry page 0x83 */
 static bool hpsa_vpd_page_supported(struct ctlr_info *h,
unsigned char scsi3addr[], u8 page)
@@ -4228,6 +4252,8 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h)
 */
ndevs_to_allocate = nphysicals + nlogicals + MAX_EXT_TARGETS + 1;
 
+   hpsa_ext_ctrl_present(h, physdev_list);
+
/* Allocate the per device structures */
for (i = 0; i < ndevs_to_allocate; i++) {
if (i >= HPSA_MAX_DEVICES) {
@@ -4298,18 +4324,6 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h)
figure_bus_target_lun(h, lunaddrbytes, tmpdevice);
this_device = currentsd[ncurrent];
 
-   /* Turn on discovery_polling if there are ext target devices.
-* Event-based change notification is unreliable for those.
-*/
-   if (!h->discovery_polling) {
-   if (tmpdevice->external) {
-   h->discovery_polling = 1;
-   dev_info(>pdev->dev,
-   "External target, activate discovery 
polling.\n");
-   }
-   }
-
-
*this_device = *tmpdevice;
this_device->physical_device = physical_device;
 
@@ -8247,7 +8261,6 @@ static void hpsa_rescan_ctlr_worker(struct work_struct 
*work)
if (h->drv_req_rescan || hpsa_offline_devices_ready(h)) {
hpsa_perform_rescan(h);
} else if (h->discovery_polling) {
-   hpsa_disable_rld_caching(h);
if (hpsa_luns_changed(h)) {
dev_info(>pdev->dev,
"driver discovery polling rescan.\n");
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index 78c3b64..21a726e 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -780,6 +780,8 @@ struct bmic_identify_physical_device {
u8 phys_bay_in_box;  /* phys drv bay this drive resides */
__le32 rpm;  /* Drive rotational speed in rpm */
u8 device_type;   /* type of drive */
+#define BMIC_DEVICE_TYPE_CONTROLLER0x07
+
u8 sata_version; /* only valid when drive_type is SATA */
__le64 big_total_block_count;
__le64 ris_starting_lba;



[PATCH 06/12] hpsa: change timeout for internal cmds

2017-10-20 Thread Don Brace
There are times when the DEFAULT_TIMEOUT (30 seconds)
is not enough.

Reviewed-by: Scott Benesh 
Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 6056bbd..4ab53df 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -2929,7 +2929,7 @@ static int hpsa_scsi_do_inquiry(struct ctlr_info *h, 
unsigned char *scsi3addr,
goto out;
}
rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
-   PCI_DMA_FROMDEVICE, DEFAULT_TIMEOUT);
+   PCI_DMA_FROMDEVICE, NO_TIMEOUT);
if (rc)
goto out;
ei = c->err_info;
@@ -3213,7 +3213,7 @@ static int hpsa_get_raid_map(struct ctlr_info *h,
return -1;
}
rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
-   PCI_DMA_FROMDEVICE, DEFAULT_TIMEOUT);
+   PCI_DMA_FROMDEVICE, NO_TIMEOUT);
if (rc)
goto out;
ei = c->err_info;
@@ -3256,7 +3256,7 @@ static int hpsa_bmic_sense_subsystem_information(struct 
ctlr_info *h,
c->Request.CDB[9] = (bmic_device_index >> 8) & 0xff;
 
rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
-   PCI_DMA_FROMDEVICE, DEFAULT_TIMEOUT);
+   PCI_DMA_FROMDEVICE, NO_TIMEOUT);
if (rc)
goto out;
ei = c->err_info;
@@ -3284,7 +3284,7 @@ static int hpsa_bmic_id_controller(struct ctlr_info *h,
goto out;
 
rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
-   PCI_DMA_FROMDEVICE, DEFAULT_TIMEOUT);
+   PCI_DMA_FROMDEVICE, NO_TIMEOUT);
if (rc)
goto out;
ei = c->err_info;
@@ -3315,7 +3315,7 @@ static int hpsa_bmic_id_physical_device(struct ctlr_info 
*h,
c->Request.CDB[9] = (bmic_device_index >> 8) & 0xff;
 
hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE,
-   DEFAULT_TIMEOUT);
+   NO_TIMEOUT);
ei = c->err_info;
if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) {
hpsa_scsi_interpret_error(h, c);
@@ -3388,7 +3388,7 @@ static void hpsa_get_enclosure_info(struct ctlr_info *h,
c->Request.CDB[5] = 0;
 
rc = hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE,
-   DEFAULT_TIMEOUT);
+   NO_TIMEOUT);
if (rc)
goto out;
 
@@ -3628,7 +3628,7 @@ static int hpsa_scsi_do_report_luns(struct ctlr_info *h, 
int logical,
if (extended_response)
c->Request.CDB[1] = extended_response;
rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
-   PCI_DMA_FROMDEVICE, DEFAULT_TIMEOUT);
+   PCI_DMA_FROMDEVICE, NO_TIMEOUT);
if (rc)
goto out;
ei = c->err_info;
@@ -3763,7 +3763,7 @@ static unsigned char hpsa_volume_offline(struct ctlr_info 
*h,
 
(void) fill_cmd(c, TEST_UNIT_READY, h, NULL, 0, 0, scsi3addr, TYPE_CMD);
rc = hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE,
-   DEFAULT_TIMEOUT);
+   NO_TIMEOUT);
if (rc) {
cmd_free(h, c);
return HPSA_VPD_LV_STATUS_UNSUPPORTED;
@@ -8620,7 +8620,7 @@ static void hpsa_disable_rld_caching(struct ctlr_info *h)
goto errout;
 
rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
-   PCI_DMA_FROMDEVICE, DEFAULT_TIMEOUT);
+   PCI_DMA_FROMDEVICE, NO_TIMEOUT);
if ((rc != 0) || (c->err_info->CommandStatus != 0))
goto errout;
 
@@ -8632,7 +8632,7 @@ static void hpsa_disable_rld_caching(struct ctlr_info *h)
goto errout;
 
rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
-   PCI_DMA_TODEVICE, DEFAULT_TIMEOUT);
+   PCI_DMA_TODEVICE, NO_TIMEOUT);
if ((rc != 0)  || (c->err_info->CommandStatus != 0))
goto errout;
 
@@ -8642,7 +8642,7 @@ static void hpsa_disable_rld_caching(struct ctlr_info *h)
goto errout;
 
rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
-   PCI_DMA_FROMDEVICE, DEFAULT_TIMEOUT);
+   PCI_DMA_FROMDEVICE, NO_TIMEOUT);
if ((rc != 0)  || (c->err_info->CommandStatus != 0))
goto errout;
 



[PATCH 03/12] hpsa: clear tmpdevice in scan thread

2017-10-20 Thread Don Brace
From: Scott Teel 

clean up stale information.

Reviewed-by: Scott Benesh 
Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 76461c4..0330f17 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -4258,6 +4258,8 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h)
int phys_dev_index = i - (raid_ctlr_position == 0);
bool skip_device = false;
 
+   memset(tmpdevice, 0, sizeof(*tmpdevice));
+
physical_device = i < nphysicals + (raid_ctlr_position == 0);
 
/* Figure out where the LUN ID info is coming from */



[PATCH 01/12] hpsa: destroy sas transport properties before scsi_host

2017-10-20 Thread Don Brace
From: Martin Wilck 

This patch cleans up a lot of warnings when unloading the
driver.

A current example of the stack trace starts with:
[  142.570715] sysfs group 'power' not found for kobject 'port-5:0'
There can be hundreds of these messages during a driver unload.

I am resubmitting this patch on behalf of Martin Wilck with his
permission.

His original patch can be found here:
https://www.spinics.net/lists/linux-scsi/msg102085.html

This patch did not help until Hannes's
commit 9441284fbc39 ("scsi-fixup-kernel-warning-during-rmmod")
was applied to the kernel.

---
Original patch description:
---

Unloading the hpsa driver causes warnings

[ 1063.793652] WARNING: CPU: 1 PID: 4850 at ../fs/sysfs/group.c:237 
device_del+0x54/0x240()
[ 1063.793659] sysfs group 81cf21a0 not found for kobject 'port-2:0'

with two different stacks:
1)
[ 1063.793774]  [] device_del+0x54/0x240
[ 1063.793780]  [] transport_remove_classdev+0x4a/0x60
[ 1063.793784]  [] 
attribute_container_device_trigger+0xa6/0xb0
[ 1063.793802]  [] sas_port_delete+0x126/0x160 
[scsi_transport_sas]
[ 1063.793819]  [] hpsa_free_sas_port+0x3c/0x70 [hpsa]

2)
[ 1063.797103]  [] device_del+0x54/0x240
[ 1063.797118]  [] sas_port_delete+0x12e/0x160 
[scsi_transport_sas]
[ 1063.797134]  [] hpsa_free_sas_port+0x3c/0x70 [hpsa]

This is caused by the fact that host device hostX is deleted before the
SAS transport devices hostX/port-a:b.

This patch fixes this by reverting the order of device deletions.

Tested-by: Don Brace 
Reviewed-by: Don Brace 
Signed-off-by: Martin Wilck 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 9abe810..aff4a4f 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -8684,6 +8684,8 @@ static void hpsa_remove_one(struct pci_dev *pdev)
destroy_workqueue(h->rescan_ctlr_wq);
destroy_workqueue(h->resubmit_wq);
 
+   hpsa_delete_sas_host(h);
+
/*
 * Call before disabling interrupts.
 * scsi_remove_host can trigger I/O operations especially
@@ -8718,8 +8720,6 @@ static void hpsa_remove_one(struct pci_dev *pdev)
h->lockup_detected = NULL;  /* init_one 2 */
/* (void) pci_disable_pcie_error_reporting(pdev); *//* init_one 1 */
 
-   hpsa_delete_sas_host(h);
-
kfree(h);   /* init_one 1 */
 }
 



[PATCH 02/12] hpsa: cleanup sas_phy structures in sysfs when unloading

2017-10-20 Thread Don Brace
From: Martin Wilck 

I am resubmitting this patch on behalf of Martin Wilck
with his permission.

The original patch can be found here:
https://www.spinics.net/lists/linux-scsi/msg102083.html

This patch did not help until Hannes's
commit 9441284fbc39 ("scsi-fixup-kernel-warning-during-rmmod")
was applied to the kernel.

--
Original patch description from Martin:
--

When the hpsa module is unloaded using rmmod, dangling
symlinks remain under /sys/class/sas_phy. Fix this by
calling sas_phy_delete() rather than sas_phy_free (which,
according to comments, should not be called for PHYs that
have been set up successfully, anyway).

Tested-by: Don Brace 
Reviewed-by: Don Brace 
Signed-off-by: Martin Wilck 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index aff4a4f..76461c4 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -9207,9 +9207,9 @@ static void hpsa_free_sas_phy(struct hpsa_sas_phy 
*hpsa_sas_phy)
struct sas_phy *phy = hpsa_sas_phy->phy;
 
sas_port_delete_phy(hpsa_sas_phy->parent_port->port, phy);
-   sas_phy_free(phy);
if (hpsa_sas_phy->added_to_port)
list_del(_sas_phy->phy_list_entry);
+   sas_phy_delete(phy);
kfree(hpsa_sas_phy);
 }
 



[PATCH] smartpqi: correct spelling error in documentation

2017-10-20 Thread Don Brace
Correct spelling error.

Signed-off-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 Documentation/scsi/smartpqi.txt |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/scsi/smartpqi.txt b/Documentation/scsi/smartpqi.txt
index ab377d9..201f80c 100644
--- a/Documentation/scsi/smartpqi.txt
+++ b/Documentation/scsi/smartpqi.txt
@@ -21,7 +21,7 @@ http://www.t10.org/members/w_pqi2.htm
 
 Supported devices:
 --
-
+
 
 smartpqi specific entries in /sys
 -



[PATCH] Suppress a kernel warning in case the prep function returns BLKPREP_DEFER

2017-10-20 Thread Bart Van Assche
The legacy block layer handles requests as follows:
- If the prep function returns BLKPREP_OK, let blk_peek_request()
  return the pointer to that request.
- If the prep function returns BLKPREP_DEFER, keep the RQF_STARTED
  flag and retry calling the prep function later.
- If the prep function returns BLKPREP_KILL or BLKPREP_INVALID, end
  the request.

In none of these cases it is correct to clear the SCMD_INITIALIZED
flag from inside scsi_prep_fn(). Since scsi_prep_fn() already
guarantees that scsi_init_command() will be called once even if
scsi_prep_fn() is called multiple times, remove the code that clears
SCMD_INITIALIZED from scsi_prep_fn().

The scsi-mq code handles requests as follows:
- If scsi_mq_prep_fn() returns BLKPREP_OK, set the RQF_DONTPREP flag
  and submit the request to the SCSI LLD.
- If scsi_mq_prep_fn() returns BLKPREP_DEFER, call
  blk_mq_delay_run_hw_queue() and return BLK_STS_RESOURCE.
- If the prep function returns BLKPREP_KILL or BLKPREP_INVALID, call
  scsi_mq_uninit_cmd() and let the blk-mq core end the request.

In none of these cases scsi_mq_prep_fn() should clear the
SCMD_INITIALIZED flag. Hence remove the code from scsi_mq_prep_fn()
function that clears that flag.

This patch avoids that the following warning is triggered when using
the legacy block layer:

[ cut here ]
WARNING: CPU: 1 PID: 4198 at drivers/scsi/scsi_lib.c:654 
scsi_end_request+0x1de/0x220
CPU: 1 PID: 4198 Comm: mkfs.f2fs Not tainted 4.14.0-rc5+ #1
task: 91c147a4b800 task.stack: b282c37b8000
RIP: 0010:scsi_end_request+0x1de/0x220
Call Trace:

scsi_io_completion+0x204/0x5e0
scsi_finish_command+0xce/0xe0
scsi_softirq_done+0x126/0x130
blk_done_softirq+0x6e/0x80
__do_softirq+0xcf/0x2a8
irq_exit+0xab/0xb0
do_IRQ+0x7b/0xc0
common_interrupt+0x90/0x90

RIP: 0010:_raw_spin_unlock_irqrestore+0x9/0x10
__test_set_page_writeback+0xc7/0x2c0
__block_write_full_page+0x158/0x3b0
block_write_full_page+0xc4/0xd0
blkdev_writepage+0x13/0x20
__writepage+0x12/0x40
write_cache_pages+0x204/0x500
generic_writepages+0x48/0x70
blkdev_writepages+0x9/0x10
do_writepages+0x34/0xc0
__filemap_fdatawrite_range+0x6c/0x90
file_write_and_wait_range+0x31/0x90
blkdev_fsync+0x16/0x40
vfs_fsync_range+0x44/0xa0
do_fsync+0x38/0x60
SyS_fsync+0xb/0x10
entry_SYSCALL_64_fastpath+0x13/0x94
---[ end trace 86e8ef85a4a6c1d1 ]---

Fixes: commit 64104f703212 ("scsi: Call scsi_initialize_rq() for filesystem 
requests")
Signed-off-by: Bart Van Assche 
Cc: Damien Le Moal 
Cc: Christoph Hellwig 
Cc: Hannes Reinecke 
Cc: Johannes Thumshirn 
---
 drivers/scsi/scsi_lib.c | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 1779c8e91d09..5745af3e81bd 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1378,8 +1378,6 @@ static int scsi_prep_fn(struct request_queue *q, struct 
request *req)
 
ret = scsi_setup_cmnd(sdev, req);
 out:
-   if (ret != BLKPREP_OK)
-   cmd->flags &= ~SCMD_INITIALIZED;
return scsi_prep_return(q, req, ret);
 }
 
@@ -1899,7 +1897,6 @@ static int scsi_mq_prep_fn(struct request *req)
struct scsi_device *sdev = req->q->queuedata;
struct Scsi_Host *shost = sdev->host;
struct scatterlist *sg;
-   int ret;
 
scsi_init_command(sdev, cmd);
 
@@ -1933,10 +1930,7 @@ static int scsi_mq_prep_fn(struct request *req)
 
blk_mq_start_request(req);
 
-   ret = scsi_setup_cmnd(sdev, req);
-   if (ret != BLK_STS_OK)
-   cmd->flags &= ~SCMD_INITIALIZED;
-   return ret;
+   return scsi_setup_cmnd(sdev, req);
 }
 
 static void scsi_mq_done(struct scsi_cmnd *cmd)
-- 
2.14.2



Re: [PATCH 9/9] bsg: split handling of SCSI CDBs vs transport requeues

2017-10-20 Thread Benjamin Block
On Fri, Oct 20, 2017 at 06:26:30PM +0200, Christoph Hellwig wrote:
> On Thu, Oct 19, 2017 at 05:59:33PM +0200, Benjamin Block wrote:
> > > +#define ptr64(val) ((void __user *)(uintptr_t)(val))
> > 
> > Better to reflect the special property, that it is a user pointer, in
> > the name of the macro. Maybe something like user_ptr(64). The same
> > comment for the same macro in bsg.c.
> 
> Not sure it's worth it especially now that Martin has merged the patch.

He did? I only saw a mail that he picked patches 2-5. So all the bsg
changes are still open I think.

(Maybe I just missed that, I haven't exactly followed the list very
closely as of late)

> But given how many interface we have all over the kernel that use a u64
> to store a user pointer in ioctls and similar it might make sense to
> lift a helper like this to a generic header.  In that case we'll need
> a more descriptive name for sure.
> 
> > > +static int bsg_transport_check_proto(struct sg_io_v4 *hdr)
> > > +{
> > > + if (hdr->protocol != BSG_PROTOCOL_SCSI  ||
> > > + hdr->subprotocol != BSG_SUB_PROTOCOL_SCSI_TRANSPORT)
> > > + return -EINVAL;
> > > + if (!capable(CAP_SYS_RAWIO))
> > > + return -EPERM;
> > 
> > Any particular reason why this is not symmetric with bsg_scsi? IOW
> > permission checking done in bsg_transport_fill_hdr(), like it is done in
> > bsg_scsi_fill_hdr()?
> > 
> > We might save some time copying memory with this (we also only talk
> > about ~20 bytes here), but on the other hand the interface would be more
> > clean otherwise IMO (if we already do restructure the interface) -
> > similar callbacks have similar responsibilities.
> 
> I could move the capable check around, no sure why I had done it that
> way, it's been a while.  Probably because blk_verify_command needs the
> CDB while a simple capable() check does not.

That was my guess, too. I just though it would be more consistent otherwise.
Its not a big thing, really.


Beste Grüße / Best regards,
  - Benjamin Block
-- 
Linux on z Systems Development / IBM Systems & Technology Group
  IBM Deutschland Research & Development GmbH 
Vorsitz. AufsR.: Martina Koederitz /Geschäftsführung: Dirk Wittkopp
Sitz der Gesellschaft: Böblingen / Registergericht: AmtsG Stuttgart, HRB 243294



Re: [PATCH 9/9] bsg: split handling of SCSI CDBs vs transport requeues

2017-10-20 Thread Christoph Hellwig
On Thu, Oct 19, 2017 at 05:59:33PM +0200, Benjamin Block wrote:
> > +#define ptr64(val) ((void __user *)(uintptr_t)(val))
> 
> Better to reflect the special property, that it is a user pointer, in
> the name of the macro. Maybe something like user_ptr(64). The same
> comment for the same macro in bsg.c.

Not sure it's worth it especially now that Martin has merged the patch.
But given how many interface we have all over the kernel that use a u64
to store a user pointer in ioctls and similar it might make sense to
lift a helper like this to a generic header.  In that case we'll need
a more descriptive name for sure.

> > +static int bsg_transport_check_proto(struct sg_io_v4 *hdr)
> > +{
> > +   if (hdr->protocol != BSG_PROTOCOL_SCSI  ||
> > +   hdr->subprotocol != BSG_SUB_PROTOCOL_SCSI_TRANSPORT)
> > +   return -EINVAL;
> > +   if (!capable(CAP_SYS_RAWIO))
> > +   return -EPERM;
> 
> Any particular reason why this is not symmetric with bsg_scsi? IOW
> permission checking done in bsg_transport_fill_hdr(), like it is done in
> bsg_scsi_fill_hdr()?
> 
> We might save some time copying memory with this (we also only talk
> about ~20 bytes here), but on the other hand the interface would be more
> clean otherwise IMO (if we already do restructure the interface) -
> similar callbacks have similar responsibilities.

I could move the capable check around, no sure why I had done it that
way, it's been a while.  Probably because blk_verify_command needs the
CDB while a simple capable() check does not.

> If I understand this right, the this reflects the old code, if only
> written down a little different.
> 
> But I wonder why we do that? Wouldn't that be interesting to know for
> uspace, if more was received than it allocated space for? Isn't that the
> typical residual over run case (similar to LUN scanning in SCSI common
> code), and din_resid is signed after all? Well I guess it could be an
> ABI break, I don't know.
> 
> Ah well, at least the documentation for 'struct sg_io_v4' makes no such
> restrictions (that it can not be below 0).
> 
> Just a thought I had while reading it.

Maybe it would, but I really didn't want to change behavior.  If we
were to redo transport passthrough I would do it totally different today.

> > +   job->reply = kzalloc(SCSI_SENSE_BUFFERSIZE, gfp);
> 
> One suggestion here. Maybe we could get rid of this implicit knowledge
> about SCSI_SENSE_BUFFERSIZE being the max size for a bsg-reply?
> Especially if we use this patch and get rid of other similarities (like
> using scsi_request).
> 
> Maybe we can just define a extra macro in bsg-lib.c, or in one of the
> headers, and define its size to be SCSI_SENSE_BUFFERSIZE (for now) and
> then use that in all cases.
> 
> I tried something similar some time ego if you remember, but I couldn't
> follow up because other stuff got more important in the meantime. One
> could also static check the transport reply-types against that.
> 
> This way, should need to change that value for a sepcific transport, we
> only need to change one knob, and not 10 (I guess SCSI_SENSE_BUFFERSIZE
> could not be changed for such cases ;) ).

There shouldn't be any dependencies on SCSI_SENSE_BUFFERSIZE left,
so yes, this could be cleaned up.  Great opportunity for a follow on
patch.

> > -   /* if the LLD has been removed then the bsg_unregister_queue will
> > -* eventually be called and the class_dev was freed, so we can no
> > -* longer use this request_queue. Return no such address.
> > -*/
> 
> Why remove the comment? Has that changed?

Nothing, but then again it's standard behavior so the comment doesn't
really add any value.

> > +   rq->timeout = msecs_to_jiffies(hdr->timeout);
> > +   if (!rq->timeout)
> > +   rq->timeout = rq->q->sg_timeout;
> 
> No need to use the rq pointer, you already have a variable q with the
> same content.

True.

> > -   ret = blk_rq_map_user(q, rq, NULL, dxferp, dxfer_len,
> > - GFP_KERNEL);
> > -   if (ret)
> > -   goto out;
> > +   ret = blk_rq_map_user(q, rq, NULL, ptr64(hdr->din_xferp),
> > +   hdr->din_xfer_len, GFP_KERNEL);
> > +   } else {
> > +   ret = blk_rq_map_user(q, rq, NULL, NULL, 0, GFP_KERNEL);
> 
> Why do we behave differently in this case now? To prevent special
> handling elsewhere? Otherwise it seems a bit pointless/error-prone
> mapping zero length to nothing.

Yes, this could be removed again.  I'll send a follow up.


[PATCH 1/1] qla2xxx: Fix oops in qla2x00_probe_one error path

2017-10-20 Thread Douglas Miller
On error, kthread_create() returns an errno-encoded pointer, not NULL.
The routine qla2x00_probe_one() detects the error case and jumps
to probe_failed, but has already assigned the return value from
kthread_create() to ha->dpc_thread.  Then probe_failed checks to see
if ha->dpc_thread is not NULL before doing cleanup on it. Since in the
error case this is also not NULL, it ends up trying to access an invalid
task pointer.

Solution is to assign NULL to ha->dpc_thread in the error path to avoid
kthread cleanup in that case.

Signed-off-by: Douglas Miller 
---
 drivers/scsi/qla2xxx/qla_os.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 9372098..bd39bf2 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -3212,6 +3212,7 @@ static void qla2x00_iocb_work_fn(struct work_struct *work)
ql_log(ql_log_fatal, base_vha, 0x00ed,
"Failed to start DPC thread.\n");
ret = PTR_ERR(ha->dpc_thread);
+   ha->dpc_thread = NULL;
goto probe_failed;
}
ql_dbg(ql_dbg_init, base_vha, 0x00ee,
-- 
1.7.1



[PATCH 0/1] qla2xxx: Fix oops in qla2x00_probe_one error path

2017-10-20 Thread Douglas Miller
See [PATCH 1/1] qla2xxx: Fix oops in qla2x00_probe_one error path



IMPORTANT INFORMATION,

2017-10-20 Thread Mr Thomas Alpha
Good Day,


Please accept my apologies for writing you a surprise letter.I am Mr
Thomas Alpha, account Manager with an investment bank here in Burkina
Faso.

I have a very important business I want to discuss with you.There is a
draft account opened in my firm by a long-time client of our bank.I
have the opportunity of transferring the left over fund (10.Million Us
Dollars)Ten Million United States of American Dollars of one of my
Bank clients who died at the collapsing of the world trade center at
the United States on September 11th 2001.

I want to invest this funds and introduce you to our bank for this
deal.All I require is your honest co-operation and I guarantee you
that this will be executed under a legitimate arrangement that will
protect us from any breach of the law.I agree that 40% of this money
will be for you as my foreign partner,50% for me while 10% is for
establishing of foundation for the less privileges in your country.If
you are really interested in my proposal return my email with the
below information and i will forward a text of application letter to
you which you are going to fill and send to the bank for claiming of
the fund.

Your Full Name...
Your Age and Sex
Your Private Telephone...
Your Occupation...
Your Country


Yours Sincerely,
Mr Thomas Alpha.


RE: [PATCH 0/6] v4 block refcount conversion patches

2017-10-20 Thread Reshetova, Elena

> Elena Reshetova  writes:
> > Elena Reshetova (6):
> >   block: convert bio.__bi_cnt from atomic_t to refcount_t
> >   block: convert blk_queue_tag.refcnt from atomic_t to refcount_t
> >   block: convert blkcg_gq.refcnt from atomic_t to refcount_t
> >   block: convert io_context.active_ref from atomic_t to refcount_t
> >   block: convert bsg_device.ref_count from atomic_t to refcount_t
> >   drivers, block: convert xen_blkif.refcnt from atomic_t to refcount_t
> 
> Hi Elena,
> 
> While the bsg ref_count is cheap, do you have any numbers how the other
> conversions compare in performance (throughput and latency) vs atomics?
Hi Johannes,

The performance would depend on which "breed" of refcount_t is used underneath. 
We currently have 3 versions:

- refcount_t defaults to atomic_t (no CONFIG_REFCOUNT_FULL enabled, no arch. 
support)
  Impact is zero in this case since it is just atomic functions are used. 
- refcount_t uses arch. specific implementation (arch. enables 
ARCH_HAS_REFCOUNT)
 Impact depends on arch. implementation. Currently only x86 provides one. 
- refcount_t uses "full" arch. independent implementation.

Here are cycle numbers for comparing these 3 (https://lwn.net/Articles/728626/):
Just copy pasting for convenience:

">These are the cycle counts comparing a loop of refcount_inc() from 1
>to INT_MAX and back down to 0 (via refcount_dec_and_test()), between
>unprotected refcount_t (atomic_t), fully protected REFCOUNT_FULL
>(refcount_t-full), and this overflow-protected refcount (refcount_t-fast):

>2147483646 refcount_inc()s and 2147483647 refcount_dec_and_test()s:
cycles  protections
>atomic_t  82249267387  none
>refcount_t-fast82211446892 overflow, untested dec-to-zero
>refcount_t-full   144814735193 overflow, untested dec-to-zero, inc-from-zero"

So, the middle option (called here refcount_t-fast) with arch. specific
implementation gives a negligible impact. The "full" one is more pricey, but it 
is
disabled by default anyway, so only people who want strict security enable it.  

Are these numbers convincing enough that we don't have to measure
the block devices? :)

Best Regards,
Elena.


> 
> It should be quite easy to measure against a null_blk device.
> 
> Thanks a lot,
>Johannes
> 
> --
> Johannes Thumshirn  Storage
> jthumsh...@suse.de+49 911 74053 689
> SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
> GF: Felix Imendörffer, Jane Smithard, Graham Norton
> HRB 21284 (AG Nürnberg)
> Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850


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

2017-10-20 Thread Arnd Bergmann
On Fri, Oct 20, 2017 at 10:52 AM, Li Wei  wrote:
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt
> @@ -0,0 +1,46 @@
> +* 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" for hisi ufs host controller
> +present on Hi3660 chipset.
> +- reg   : should contain UFS register address space & UFS SYS 
> CTRL register address,
> +- interrupt-parent  : interrupt device
> +- interrupts: interrupt number
> +- clocks   : List of phandle and clock specifier pairs
> +- clock-names   : List of clock input name strings sorted in the same
> + order as the clocks property. "clk_ref", "clk_phy" is 
> optional
> +- resets: reset node register, one reset the clk and the other 
> reset the controller
> +- reset-names   : describe reset node register

I think I've asked about this before, but I think this should be done more
consistently with the other UFS bindings.

In particular, I wonder if what you describe as the "UFS SYS CTRL"
area corresponds to what Qualcomm have described as their PHY
implementation. It certainly seems to driver some of the properties
that would normally be associated with a PHY.

For the "clock-names" property, you specify "clk_ref", which I
assume is the same as what Qualcomm call "ref_clk". I'd
suggest you use the existing name and add that as the
default name in the ufshcd-pltfrm.txt binding document.

The "clk_phy" property appears to be related to the PHY, so
it might be better to have a separate phy node with either just
the clk, or with the clk plus the "UFS SYS CTRL" register area,
whichever matches your hardware better, and then use teh
"phys/phy-names" property to refer to that.

The reset handling you describe here (both resets and reset-gpios)
appears to be completely generic, so I'd suggest adding those to
ufshcd-pltfrm.txt instead of your own binding, to ensure that future
drivers use the same identifiers.


  Arnd


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

2017-10-20 Thread Li Wei
add ufs node document for Hisilicon.

Signed-off-by: Li Wei 
---
 Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 47 ++
 1 file changed, 47 insertions(+)
 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 ..ee114a65143d
--- /dev/null
+++ b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt
@@ -0,0 +1,47 @@
+* 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" for hisi ufs host controller
+present on Hi3660 chipset.
+- reg   : should contain UFS register address space & UFS SYS CTRL 
register address,
+- interrupt-parent  : interrupt device
+- interrupts: interrupt number
+- clocks   : List of phandle and clock specifier pairs
+- clock-names   : List of clock input name strings sorted in the same
+ order as the clocks property. "clk_ref", "clk_phy" is 
optional
+- resets: reset node register, one reset the clk and the other 
reset the controller
+- reset-names   : describe reset node register
+
+Optional properties for board device:
+- reset-gpio   : specifies to reset devices
+
+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 = ;
+   clocks = <_ctrl HI3660_CLK_GATE_UFSIO_REF>,
+   <_ctrl HI3660_CLK_GATE_UFSPHY_CFG>;
+   clock-names = "clk_ref", "clk_phy";
+   freq-table-hz = <0 0>, <0 0>;
+   /* offset: 0x84; bit: 12 */
+   /* offset: 0x84; bit: 7  */
+   resets = <_rst 0x84 12>,
+   <_rst 0x84 7>;
+   reset-names = "rst", "assert";
+   };
+
+{
+   reset-gpio = < 1 0>;
+   status = "okay";
+   };
+
-- 
2.11.0



[PATCH v4 1/5] scsi: ufs: add Hisilicon ufs driver code

2017-10-20 Thread Li Wei
add Hisilicon ufs driver code.

Signed-off-by: Li Wei 
Signed-off-by: Geng Jianfeng 
Signed-off-by: Zang Leigang 
Signed-off-by: Yu Jianfeng 
---
 drivers/scsi/ufs/Kconfig|   9 +
 drivers/scsi/ufs/Makefile   |   1 +
 drivers/scsi/ufs/ufs-hisi.c | 625 
 drivers/scsi/ufs/ufs-hisi.h | 161 
 4 files changed, 796 insertions(+)
 create mode 100644 drivers/scsi/ufs/ufs-hisi.c
 create mode 100644 drivers/scsi/ufs/ufs-hisi.h

diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
index e27b4d4e6ae2..bf2ff5628b15 100644
--- a/drivers/scsi/ufs/Kconfig
+++ b/drivers/scsi/ufs/Kconfig
@@ -80,6 +80,15 @@ config SCSI_UFSHCD_PLATFORM
 
  If unsure, say N.
 
+config SCSI_UFS_HISI
+   tristate "Hisilicon specific hooks to UFS controller platform driver"
+   depends on (ARCH_HISI || COMPILE_TEST) && SCSI_UFSHCD_PLATFORM
+   ---help---
+ This selects the Hisilicon specific additions to UFSHCD platform 
driver.
+
+ Select this if you have UFS controller on Hisilicon chipset.
+ If unsure, say N.
+
 config SCSI_UFS_DWC_TC_PLATFORM
tristate "DesignWare platform support using a G210 Test Chip"
depends on SCSI_UFSHCD_PLATFORM
diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile
index 6e77cb0bfee9..9f2c17029a38 100644
--- a/drivers/scsi/ufs/Makefile
+++ b/drivers/scsi/ufs/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o 
tc-dwc-g210.o
 obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o 
tc-dwc-g210.o
 obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o
+obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o
 obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o
 obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o
 obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/scsi/ufs/ufs-hisi.c
new file mode 100644
index ..8b7aea2d44c5
--- /dev/null
+++ b/drivers/scsi/ufs/ufs-hisi.c
@@ -0,0 +1,625 @@
+/*
+ *
+ * HiSilicon Hi UFS Driver
+ *
+ * Copyright (c) 2016-2017 Linaro Ltd.
+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ufshcd.h"
+#include "ufshcd-pltfrm.h"
+#include "unipro.h"
+#include "ufs-hisi.h"
+#include "ufshci.h"
+
+static int ufs_hisi_check_hibern8(struct ufs_hba *hba)
+{
+   int err;
+   u32 tx_fsm_val_0;
+   u32 tx_fsm_val_1;
+   unsigned long timeout = jiffies + msecs_to_jiffies(HBRN8_POLL_TOUT_MS);
+
+   do {
+   err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0),
+ _fsm_val_0);
+   err |= ufshcd_dme_get(hba,
+   UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), _fsm_val_1);
+   if (err || (tx_fsm_val_0 == TX_FSM_HIBERN8 &&
+   tx_fsm_val_1 == TX_FSM_HIBERN8))
+   break;
+
+   /* sleep for max. 200us */
+   usleep_range(100, 200);
+   } while (time_before(jiffies, timeout));
+
+   /*
+* we might have scheduled out for long during polling so
+* check the state again.
+*/
+   if (time_after(jiffies, timeout)) {
+   err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0),
+_fsm_val_0);
+   err |= ufshcd_dme_get(hba,
+UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), _fsm_val_1);
+   }
+
+   if (err) {
+   dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n",
+   __func__, err);
+   } else if (tx_fsm_val_0 != TX_FSM_HIBERN8 ||
+tx_fsm_val_1 != TX_FSM_HIBERN8) {
+   err = -1;
+   dev_err(hba->dev, "%s: invalid TX_FSM_STATE, lane0 = %d, lane1 
= %d\n",
+   __func__, tx_fsm_val_0, tx_fsm_val_1);
+   }
+
+   return err;
+}
+
+static void ufs_hisi_clk_init(struct ufs_hba *hba)
+{
+   struct ufs_hisi_host *host = ufshcd_get_variant(hba);
+
+   ufs_sys_ctrl_clr_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL);
+   if (ufs_sys_ctrl_readl(host, PHY_CLK_CTRL) & BIT_SYSCTRL_REF_CLOCK_EN)
+   mdelay(1);
+   /* use abb clk */
+   ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_SRC_SEl, UFS_SYSCTRL);
+   ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_ISO_EN, PHY_ISO_EN);
+   /* open mphy ref clk */
+   ufs_sys_ctrl_set_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL);
+}
+
+static void 

[PATCH v4 4/5] arm64: defconfig: enable configs for Hisilicon ufs

2017-10-20 Thread Li Wei
This enable configs for Hisilicon Hi UFS driver.

Signed-off-by: Li Wei 
Signed-off-by: Zhangfei Gao 
Signed-off-by: Guodong Xu 
---
 arch/arm64/configs/defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 34480e9af2e7..8aff981915f5 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -168,6 +168,9 @@ CONFIG_BLK_DEV_SD=y
 CONFIG_SCSI_SAS_ATA=y
 CONFIG_SCSI_HISI_SAS=y
 CONFIG_SCSI_HISI_SAS_PCI=y
+CONFIG_SCSI_UFSHCD=y
+CONFIG_SCSI_UFSHCD_PLATFORM=y
+CONFIG_SCSI_UFS_HISI=y
 CONFIG_ATA=y
 CONFIG_SATA_AHCI=y
 CONFIG_SATA_AHCI_PLATFORM=y
-- 
2.11.0



[PATCH v5 0/5] scsi: ufs: add ufs driver code for Hisilicon Hi3660 SoC

2017-10-20 Thread Li Wei
This patchset adds driver support for UFS for Hi3660 SoC. It is verified on 
HiKey960 board.

Li Wei (5):
  scsi: ufs: add Hisilicon ufs driver code
  dt-bindings: scsi: ufs: add document for hisi-ufs
  arm64: dts: add ufs dts node
  arm64: defconfig: enable configs for Hisilicon ufs
  arm64: defconfig: enable f2fs and squashfs

 Documentation/devicetree/bindings/ufs/ufs-hisi.txt |  46 ++
 arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts  |   5 +
 arch/arm64/boot/dts/hisilicon/hi3660.dtsi  |  19 +
 arch/arm64/configs/defconfig   |  11 +
 drivers/scsi/ufs/Kconfig   |   9 +
 drivers/scsi/ufs/Makefile  |   1 +
 drivers/scsi/ufs/ufs-hisi.c| 625 +
 drivers/scsi/ufs/ufs-hisi.h| 161 ++
 8 files changed, 877 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt
 create mode 100644 drivers/scsi/ufs/ufs-hisi.c
 create mode 100644 drivers/scsi/ufs/ufs-hisi.h

-- 
2.11.0



[PATCH v5 4/5] arm64: defconfig: enable configs for Hisilicon ufs

2017-10-20 Thread Li Wei
This enable configs for Hisilicon Hi UFS driver.

Signed-off-by: Li Wei 
Signed-off-by: Zhangfei Gao 
Signed-off-by: Guodong Xu 
---
 arch/arm64/configs/defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 34480e9af2e7..8aff981915f5 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -168,6 +168,9 @@ CONFIG_BLK_DEV_SD=y
 CONFIG_SCSI_SAS_ATA=y
 CONFIG_SCSI_HISI_SAS=y
 CONFIG_SCSI_HISI_SAS_PCI=y
+CONFIG_SCSI_UFSHCD=y
+CONFIG_SCSI_UFSHCD_PLATFORM=y
+CONFIG_SCSI_UFS_HISI=y
 CONFIG_ATA=y
 CONFIG_SATA_AHCI=y
 CONFIG_SATA_AHCI_PLATFORM=y
-- 
2.11.0



[PATCH v5 5/5] arm64: defconfig: enable f2fs and squashfs

2017-10-20 Thread Li Wei
Partitions in HiKey960 are formatted as f2fs and squashfs.
f2fs is for userdata; squashfs is for system. Both partitions are required
by Android.

Signed-off-by: Li Wei 
Signed-off-by: Zhangfei Gao 
Signed-off-by: Guodong Xu 
---
 arch/arm64/configs/defconfig | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 8aff981915f5..0a8a843cd0be 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -555,6 +555,7 @@ CONFIG_ACPI_APEI_GHES=y
 CONFIG_ACPI_APEI_PCIEAER=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
+CONFIG_F2FS_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
 CONFIG_BTRFS_FS=m
 CONFIG_BTRFS_FS_POSIX_ACL=y
@@ -570,6 +571,13 @@ CONFIG_HUGETLBFS=y
 CONFIG_CONFIGFS_FS=y
 CONFIG_EFIVAR_FS=y
 CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_FILE_DIRECT=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZ4=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V4=y
 CONFIG_NFS_V4_1=y
-- 
2.11.0



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

2017-10-20 Thread Li Wei
add ufs node document for Hisilicon.

Signed-off-by: Li Wei 
---
 Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 46 ++
 1 file changed, 46 insertions(+)
 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 ..17da633c9ed5
--- /dev/null
+++ b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt
@@ -0,0 +1,46 @@
+* 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" for hisi ufs host controller
+present on Hi3660 chipset.
+- reg   : should contain UFS register address space & UFS SYS CTRL 
register address,
+- interrupt-parent  : interrupt device
+- interrupts: interrupt number
+- clocks   : List of phandle and clock specifier pairs
+- clock-names   : List of clock input name strings sorted in the same
+ order as the clocks property. "clk_ref", "clk_phy" is 
optional
+- resets: reset node register, one reset the clk and the other 
reset the controller
+- reset-names   : describe reset node register
+
+Optional properties for board device:
+- reset-gpios  : specifies to reset devices
+
+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 = ;
+   clocks = <_ctrl HI3660_CLK_GATE_UFSIO_REF>,
+   <_ctrl HI3660_CLK_GATE_UFSPHY_CFG>;
+   clock-names = "clk_ref", "clk_phy";
+   freq-table-hz = <0 0>, <0 0>;
+   /* offset: 0x84; bit: 12 */
+   /* offset: 0x84; bit: 7  */
+   resets = <_rst 0x84 12>,
+   <_rst 0x84 7>;
+   reset-names = "rst", "assert";
+   };
+
+{
+   reset-gpios = < 1 0>;
+   };
+
-- 
2.11.0



[PATCH v5 1/5] scsi: ufs: add Hisilicon ufs driver code

2017-10-20 Thread Li Wei
add Hisilicon ufs driver code.

Signed-off-by: Li Wei 
Signed-off-by: Geng Jianfeng 
Signed-off-by: Zang Leigang 
Signed-off-by: Yu Jianfeng 
---
 drivers/scsi/ufs/Kconfig|   9 +
 drivers/scsi/ufs/Makefile   |   1 +
 drivers/scsi/ufs/ufs-hisi.c | 625 
 drivers/scsi/ufs/ufs-hisi.h | 161 
 4 files changed, 796 insertions(+)
 create mode 100644 drivers/scsi/ufs/ufs-hisi.c
 create mode 100644 drivers/scsi/ufs/ufs-hisi.h

diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
index e27b4d4e6ae2..bf2ff5628b15 100644
--- a/drivers/scsi/ufs/Kconfig
+++ b/drivers/scsi/ufs/Kconfig
@@ -80,6 +80,15 @@ config SCSI_UFSHCD_PLATFORM
 
  If unsure, say N.
 
+config SCSI_UFS_HISI
+   tristate "Hisilicon specific hooks to UFS controller platform driver"
+   depends on (ARCH_HISI || COMPILE_TEST) && SCSI_UFSHCD_PLATFORM
+   ---help---
+ This selects the Hisilicon specific additions to UFSHCD platform 
driver.
+
+ Select this if you have UFS controller on Hisilicon chipset.
+ If unsure, say N.
+
 config SCSI_UFS_DWC_TC_PLATFORM
tristate "DesignWare platform support using a G210 Test Chip"
depends on SCSI_UFSHCD_PLATFORM
diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile
index 6e77cb0bfee9..9f2c17029a38 100644
--- a/drivers/scsi/ufs/Makefile
+++ b/drivers/scsi/ufs/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o 
tc-dwc-g210.o
 obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o 
tc-dwc-g210.o
 obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o
+obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o
 obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o
 obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o
 obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/scsi/ufs/ufs-hisi.c
new file mode 100644
index ..38a2e238c5e1
--- /dev/null
+++ b/drivers/scsi/ufs/ufs-hisi.c
@@ -0,0 +1,625 @@
+/*
+ *
+ * HiSilicon Hi UFS Driver
+ *
+ * Copyright (c) 2016-2017 Linaro Ltd.
+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ufshcd.h"
+#include "ufshcd-pltfrm.h"
+#include "unipro.h"
+#include "ufs-hisi.h"
+#include "ufshci.h"
+
+static int ufs_hisi_check_hibern8(struct ufs_hba *hba)
+{
+   int err;
+   u32 tx_fsm_val_0;
+   u32 tx_fsm_val_1;
+   unsigned long timeout = jiffies + msecs_to_jiffies(HBRN8_POLL_TOUT_MS);
+
+   do {
+   err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0),
+ _fsm_val_0);
+   err |= ufshcd_dme_get(hba,
+   UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), _fsm_val_1);
+   if (err || (tx_fsm_val_0 == TX_FSM_HIBERN8 &&
+   tx_fsm_val_1 == TX_FSM_HIBERN8))
+   break;
+
+   /* sleep for max. 200us */
+   usleep_range(100, 200);
+   } while (time_before(jiffies, timeout));
+
+   /*
+* we might have scheduled out for long during polling so
+* check the state again.
+*/
+   if (time_after(jiffies, timeout)) {
+   err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0),
+_fsm_val_0);
+   err |= ufshcd_dme_get(hba,
+UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), _fsm_val_1);
+   }
+
+   if (err) {
+   dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n",
+   __func__, err);
+   } else if (tx_fsm_val_0 != TX_FSM_HIBERN8 ||
+tx_fsm_val_1 != TX_FSM_HIBERN8) {
+   err = -1;
+   dev_err(hba->dev, "%s: invalid TX_FSM_STATE, lane0 = %d, lane1 
= %d\n",
+   __func__, tx_fsm_val_0, tx_fsm_val_1);
+   }
+
+   return err;
+}
+
+static void ufs_hisi_clk_init(struct ufs_hba *hba)
+{
+   struct ufs_hisi_host *host = ufshcd_get_variant(hba);
+
+   ufs_sys_ctrl_clr_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL);
+   if (ufs_sys_ctrl_readl(host, PHY_CLK_CTRL) & BIT_SYSCTRL_REF_CLOCK_EN)
+   mdelay(1);
+   /* use abb clk */
+   ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_SRC_SEl, UFS_SYSCTRL);
+   ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_ISO_EN, PHY_ISO_EN);
+   /* open mphy ref clk */
+   ufs_sys_ctrl_set_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL);
+}
+
+static void 

[PATCH v5 3/5] arm64: dts: add ufs dts node

2017-10-20 Thread Li Wei
arm64: dts: add ufs node for Hisilicon.

Signed-off-by: Li Wei 
---
 arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts |  5 +
 arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 19 +++
 2 files changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts 
b/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts
index fd4705c451e2..677d0e41667f 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts
+++ b/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts
@@ -276,3 +276,8 @@
interrupts = <3 IRQ_TYPE_EDGE_RISING>;
};
 };
+
+ {
+   reset-gpios = < 1 0>;
+   status = "okay";
+};
diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi 
b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
index b7a90d632959..a24ab8472347 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
@@ -978,5 +978,24 @@
clocks = <_ctrl HI3660_OSC32K>;
clock-names = "apb_pclk";
};
+
+   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 = ;
+   clocks = <_ctrl HI3660_CLK_GATE_UFSIO_REF>,
+   <_ctrl HI3660_CLK_GATE_UFSPHY_CFG>;
+   clock-names = "clk_ref", "clk_phy";
+   freq-table-hz = <0 0>, <0 0>;
+   /* offset: 0x84; bit: 12 */
+   /* offset: 0x84; bit: 7  */
+   resets = <_rst 0x84 12>,
+   <_rst 0x84 7>;
+   reset-names = "rst", "assert";
+   };
};
 };
-- 
2.11.0



[PATCH v4 5/5] arm64: defconfig: enable f2fs and squashfs

2017-10-20 Thread Li Wei
Partitions in HiKey960 are formatted as f2fs and squashfs.
f2fs is for userdata; squashfs is for system. Both partitions are required
by Android.

Signed-off-by: Li Wei 
Signed-off-by: Zhangfei Gao 
Signed-off-by: Guodong Xu 
---
 arch/arm64/configs/defconfig | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 8aff981915f5..0a8a843cd0be 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -555,6 +555,7 @@ CONFIG_ACPI_APEI_GHES=y
 CONFIG_ACPI_APEI_PCIEAER=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
+CONFIG_F2FS_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
 CONFIG_BTRFS_FS=m
 CONFIG_BTRFS_FS_POSIX_ACL=y
@@ -570,6 +571,13 @@ CONFIG_HUGETLBFS=y
 CONFIG_CONFIGFS_FS=y
 CONFIG_EFIVAR_FS=y
 CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_FILE_DIRECT=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZ4=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V4=y
 CONFIG_NFS_V4_1=y
-- 
2.11.0



[PATCH v4 3/5] arm64: dts: add ufs dts node

2017-10-20 Thread Li Wei
arm64: dts: add ufs node for Hisilicon.

Signed-off-by: Li Wei 
---
 arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts |  5 +
 arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 19 +++
 2 files changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts 
b/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts
index fd4705c451e2..457645a2b53f 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts
+++ b/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts
@@ -276,3 +276,8 @@
interrupts = <3 IRQ_TYPE_EDGE_RISING>;
};
 };
+
+ {
+   reset-gpio = < 1 0>;
+   status = "okay";
+};
diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi 
b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
index b7a90d632959..a24ab8472347 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
@@ -978,5 +978,24 @@
clocks = <_ctrl HI3660_OSC32K>;
clock-names = "apb_pclk";
};
+
+   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 = ;
+   clocks = <_ctrl HI3660_CLK_GATE_UFSIO_REF>,
+   <_ctrl HI3660_CLK_GATE_UFSPHY_CFG>;
+   clock-names = "clk_ref", "clk_phy";
+   freq-table-hz = <0 0>, <0 0>;
+   /* offset: 0x84; bit: 12 */
+   /* offset: 0x84; bit: 7  */
+   resets = <_rst 0x84 12>,
+   <_rst 0x84 7>;
+   reset-names = "rst", "assert";
+   };
};
 };
-- 
2.11.0



[PATCH v4 0/5] scsi: ufs: add ufs driver code for Hisilicon Hi3660 SoC

2017-10-20 Thread Li Wei
This patchset adds driver support for UFS for Hi3660 SoC. It is verified on 
HiKey960 board.

Li Wei (5):
  scsi: ufs: add Hisilicon ufs driver code
  dt-bindings: scsi: ufs: add document for hisi-ufs
  arm64: dts: add ufs dts node
  arm64: defconfig: enable configs for Hisilicon ufs
  arm64: defconfig: enable f2fs and squashfs

 Documentation/devicetree/bindings/ufs/ufs-hisi.txt |  47 ++
 arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts  |   5 +
 arch/arm64/boot/dts/hisilicon/hi3660.dtsi  |  19 +
 arch/arm64/configs/defconfig   |  11 +
 drivers/scsi/ufs/Kconfig   |   9 +
 drivers/scsi/ufs/Makefile  |   1 +
 drivers/scsi/ufs/ufs-hisi.c| 625 +
 drivers/scsi/ufs/ufs-hisi.h| 161 ++
 8 files changed, 878 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt
 create mode 100644 drivers/scsi/ufs/ufs-hisi.c
 create mode 100644 drivers/scsi/ufs/ufs-hisi.h

-- 
2.11.0



Re: [PATCH 0/6] v4 block refcount conversion patches

2017-10-20 Thread Johannes Thumshirn
Elena Reshetova  writes:
> Elena Reshetova (6):
>   block: convert bio.__bi_cnt from atomic_t to refcount_t
>   block: convert blk_queue_tag.refcnt from atomic_t to refcount_t
>   block: convert blkcg_gq.refcnt from atomic_t to refcount_t
>   block: convert io_context.active_ref from atomic_t to refcount_t
>   block: convert bsg_device.ref_count from atomic_t to refcount_t
>   drivers, block: convert xen_blkif.refcnt from atomic_t to refcount_t

Hi Elena,

While the bsg ref_count is cheap, do you have any numbers how the other
conversions compare in performance (throughput and latency) vs atomics?

It should be quite easy to measure against a null_blk device.

Thanks a lot,
   Johannes

-- 
Johannes Thumshirn  Storage
jthumsh...@suse.de+49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850


[PATCH 1/6] block: convert bio.__bi_cnt from atomic_t to refcount_t

2017-10-20 Thread Elena Reshetova
atomic_t variables are currently used to implement reference
counters with the following properties:
 - counter is initialized to 1 using atomic_set()
 - a resource is freed upon counter reaching zero
 - once counter reaches zero, its further
   increments aren't allowed
 - counter schema uses basic atomic operations
   (set, inc, inc_not_zero, dec_and_test, etc.)

Such atomic variables should be converted to a newly provided
refcount_t type and API that prevents accidental counter overflows
and underflows. This is important since overflows and underflows
can lead to use-after-free situation and be exploitable.

The variable bio.__bi_cnt is used as pure reference counter.
Convert it to refcount_t and fix up the operations.

Suggested-by: Kees Cook 
Reviewed-by: David Windsor 
Reviewed-by: Hans Liljestrand 
Signed-off-by: Elena Reshetova 
---
 block/bio.c   | 6 +++---
 fs/btrfs/volumes.c| 2 +-
 include/linux/bio.h   | 4 ++--
 include/linux/blk_types.h | 3 ++-
 4 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 101c2a9..58edc1b 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -279,7 +279,7 @@ void bio_init(struct bio *bio, struct bio_vec *table,
 {
memset(bio, 0, sizeof(*bio));
atomic_set(>__bi_remaining, 1);
-   atomic_set(>__bi_cnt, 1);
+   refcount_set(>__bi_cnt, 1);
 
bio->bi_io_vec = table;
bio->bi_max_vecs = max_vecs;
@@ -557,12 +557,12 @@ void bio_put(struct bio *bio)
if (!bio_flagged(bio, BIO_REFFED))
bio_free(bio);
else {
-   BIO_BUG_ON(!atomic_read(>__bi_cnt));
+   BIO_BUG_ON(!refcount_read(>__bi_cnt));
 
/*
 * last put frees it
 */
-   if (atomic_dec_and_test(>__bi_cnt))
+   if (refcount_dec_and_test(>__bi_cnt))
bio_free(bio);
}
 }
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index b397375..11812ee 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -450,7 +450,7 @@ static noinline void run_scheduled_bios(struct btrfs_device 
*device)
waitqueue_active(_info->async_submit_wait))
wake_up(_info->async_submit_wait);
 
-   BUG_ON(atomic_read(>__bi_cnt) == 0);
+   BUG_ON(refcount_read(>__bi_cnt) == 0);
 
/*
 * if we're doing the sync list, record that our
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 275c91c..0fa4dd2 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -253,7 +253,7 @@ static inline void bio_get(struct bio *bio)
 {
bio->bi_flags |= (1 << BIO_REFFED);
smp_mb__before_atomic();
-   atomic_inc(>__bi_cnt);
+   refcount_inc(>__bi_cnt);
 }
 
 static inline void bio_cnt_set(struct bio *bio, unsigned int count)
@@ -262,7 +262,7 @@ static inline void bio_cnt_set(struct bio *bio, unsigned 
int count)
bio->bi_flags |= (1 << BIO_REFFED);
smp_mb__before_atomic();
}
-   atomic_set(>__bi_cnt, count);
+   refcount_set(>__bi_cnt, count);
 }
 
 static inline bool bio_flagged(struct bio *bio, unsigned int bit)
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index a2d2aa7..1ec370e 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -7,6 +7,7 @@
 
 #include 
 #include 
+#include 
 
 struct bio_set;
 struct bio;
@@ -104,7 +105,7 @@ struct bio {
 
unsigned short  bi_max_vecs;/* max bvl_vecs we can hold */
 
-   atomic_t__bi_cnt;   /* pin count */
+   refcount_t  __bi_cnt;   /* pin count */
 
struct bio_vec  *bi_io_vec; /* the actual vec list */
 
-- 
2.7.4



[PATCH 3/6] block: convert blkcg_gq.refcnt from atomic_t to refcount_t

2017-10-20 Thread Elena Reshetova
atomic_t variables are currently used to implement reference
counters with the following properties:
 - counter is initialized to 1 using atomic_set()
 - a resource is freed upon counter reaching zero
 - once counter reaches zero, its further
   increments aren't allowed
 - counter schema uses basic atomic operations
   (set, inc, inc_not_zero, dec_and_test, etc.)

Such atomic variables should be converted to a newly provided
refcount_t type and API that prevents accidental counter overflows
and underflows. This is important since overflows and underflows
can lead to use-after-free situation and be exploitable.

The variable blkcg_gq.refcnt is used as pure reference counter.
Convert it to refcount_t and fix up the operations.

Suggested-by: Kees Cook 
Reviewed-by: David Windsor 
Reviewed-by: Hans Liljestrand 
Signed-off-by: Elena Reshetova 
---
 block/blk-cgroup.c |  2 +-
 include/linux/blk-cgroup.h | 11 ++-
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index d3f56ba..1e7cedc 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -107,7 +107,7 @@ static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, 
struct request_queue *q,
blkg->q = q;
INIT_LIST_HEAD(>q_node);
blkg->blkcg = blkcg;
-   atomic_set(>refcnt, 1);
+   refcount_set(>refcnt, 1);
 
/* root blkg uses @q->root_rl, init rl only for !root blkgs */
if (blkcg != _root) {
diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h
index 9d92153..c95d29d 100644
--- a/include/linux/blk-cgroup.h
+++ b/include/linux/blk-cgroup.h
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* percpu_counter batch for blkg_[rw]stats, per-cpu drift doesn't matter */
 #define BLKG_STAT_CPU_BATCH(INT_MAX / 2)
@@ -122,7 +123,7 @@ struct blkcg_gq {
struct request_list rl;
 
/* reference count */
-   atomic_trefcnt;
+   refcount_t  refcnt;
 
/* is this blkg online? protected by both blkcg and q locks */
boolonline;
@@ -354,8 +355,8 @@ static inline int blkg_path(struct blkcg_gq *blkg, char 
*buf, int buflen)
  */
 static inline void blkg_get(struct blkcg_gq *blkg)
 {
-   WARN_ON_ONCE(atomic_read(>refcnt) <= 0);
-   atomic_inc(>refcnt);
+   WARN_ON_ONCE(refcount_read(>refcnt) == 0);
+   refcount_inc(>refcnt);
 }
 
 void __blkg_release_rcu(struct rcu_head *rcu);
@@ -366,8 +367,8 @@ void __blkg_release_rcu(struct rcu_head *rcu);
  */
 static inline void blkg_put(struct blkcg_gq *blkg)
 {
-   WARN_ON_ONCE(atomic_read(>refcnt) <= 0);
-   if (atomic_dec_and_test(>refcnt))
+   WARN_ON_ONCE(refcount_read(>refcnt) == 0);
+   if (refcount_dec_and_test(>refcnt))
call_rcu(>rcu_head, __blkg_release_rcu);
 }
 
-- 
2.7.4



[PATCH 6/6] drivers, block: convert xen_blkif.refcnt from atomic_t to refcount_t

2017-10-20 Thread Elena Reshetova
atomic_t variables are currently used to implement reference
counters with the following properties:
 - counter is initialized to 1 using atomic_set()
 - a resource is freed upon counter reaching zero
 - once counter reaches zero, its further
   increments aren't allowed
 - counter schema uses basic atomic operations
   (set, inc, inc_not_zero, dec_and_test, etc.)

Such atomic variables should be converted to a newly provided
refcount_t type and API that prevents accidental counter overflows
and underflows. This is important since overflows and underflows
can lead to use-after-free situation and be exploitable.

The variable xen_blkif.refcnt is used as pure reference counter.
Convert it to refcount_t and fix up the operations.

Suggested-by: Kees Cook 
Reviewed-by: David Windsor 
Reviewed-by: Hans Liljestrand 
Signed-off-by: Elena Reshetova 
---
 drivers/block/xen-blkback/common.h | 7 ---
 drivers/block/xen-blkback/xenbus.c | 2 +-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/block/xen-blkback/common.h 
b/drivers/block/xen-blkback/common.h
index ecb35fe..0c3320d 100644
--- a/drivers/block/xen-blkback/common.h
+++ b/drivers/block/xen-blkback/common.h
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -319,7 +320,7 @@ struct xen_blkif {
struct xen_vbd  vbd;
/* Back pointer to the backend_info. */
struct backend_info *be;
-   atomic_trefcnt;
+   refcount_t  refcnt;
/* for barrier (drain) requests */
struct completion   drain_complete;
atomic_tdrain;
@@ -372,10 +373,10 @@ struct pending_req {
 (_v)->bdev->bd_part->nr_sects : \
  get_capacity((_v)->bdev->bd_disk))
 
-#define xen_blkif_get(_b) (atomic_inc(&(_b)->refcnt))
+#define xen_blkif_get(_b) (refcount_inc(&(_b)->refcnt))
 #define xen_blkif_put(_b)  \
do {\
-   if (atomic_dec_and_test(&(_b)->refcnt)) \
+   if (refcount_dec_and_test(&(_b)->refcnt))   \
schedule_work(&(_b)->free_work);\
} while (0)
 
diff --git a/drivers/block/xen-blkback/xenbus.c 
b/drivers/block/xen-blkback/xenbus.c
index 21c1be1..5955b61 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -176,7 +176,7 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid)
return ERR_PTR(-ENOMEM);
 
blkif->domid = domid;
-   atomic_set(>refcnt, 1);
+   refcount_set(>refcnt, 1);
init_completion(>drain_complete);
INIT_WORK(>free_work, xen_blkif_deferred_free);
 
-- 
2.7.4



[PATCH 4/6] block: convert io_context.active_ref from atomic_t to refcount_t

2017-10-20 Thread Elena Reshetova
atomic_t variables are currently used to implement reference
counters with the following properties:
 - counter is initialized to 1 using atomic_set()
 - a resource is freed upon counter reaching zero
 - once counter reaches zero, its further
   increments aren't allowed
 - counter schema uses basic atomic operations
   (set, inc, inc_not_zero, dec_and_test, etc.)

Such atomic variables should be converted to a newly provided
refcount_t type and API that prevents accidental counter overflows
and underflows. This is important since overflows and underflows
can lead to use-after-free situation and be exploitable.

The variable io_context.active_ref is used as pure reference counter.
Convert it to refcount_t and fix up the operations.

Suggested-by: Kees Cook 
Reviewed-by: David Windsor 
Reviewed-by: Hans Liljestrand 
Signed-off-by: Elena Reshetova 
---
 block/bfq-iosched.c   | 2 +-
 block/blk-ioc.c   | 4 ++--
 block/cfq-iosched.c   | 4 ++--
 include/linux/iocontext.h | 7 ---
 4 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index a4783da..1ec9b22 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -4030,7 +4030,7 @@ static void bfq_update_has_short_ttime(struct bfq_data 
*bfqd,
 * bfqq. Otherwise check average think time to
 * decide whether to mark as has_short_ttime
 */
-   if (atomic_read(>icq.ioc->active_ref) == 0 ||
+   if (refcount_read(>icq.ioc->active_ref) == 0 ||
(bfq_sample_valid(bfqq->ttime.ttime_samples) &&
 bfqq->ttime.ttime_mean > bfqd->bfq_slice_idle))
has_short_ttime = false;
diff --git a/block/blk-ioc.c b/block/blk-ioc.c
index 63898d2..69704d2 100644
--- a/block/blk-ioc.c
+++ b/block/blk-ioc.c
@@ -176,7 +176,7 @@ void put_io_context_active(struct io_context *ioc)
unsigned long flags;
struct io_cq *icq;
 
-   if (!atomic_dec_and_test(>active_ref)) {
+   if (!refcount_dec_and_test(>active_ref)) {
put_io_context(ioc);
return;
}
@@ -275,7 +275,7 @@ int create_task_io_context(struct task_struct *task, gfp_t 
gfp_flags, int node)
/* initialize */
atomic_long_set(>refcount, 1);
atomic_set(>nr_tasks, 1);
-   atomic_set(>active_ref, 1);
+   refcount_set(>active_ref, 1);
spin_lock_init(>lock);
INIT_RADIX_TREE(>icq_tree, GFP_ATOMIC | __GFP_HIGH);
INIT_HLIST_HEAD(>icq_list);
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 9f342ef..e6d5d6d 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -2941,7 +2941,7 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
 * task has exited, don't wait
 */
cic = cfqd->active_cic;
-   if (!cic || !atomic_read(>icq.ioc->active_ref))
+   if (!cic || !refcount_read(>icq.ioc->active_ref))
return;
 
/*
@@ -3933,7 +3933,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct 
cfq_queue *cfqq,
 
if (cfqq->next_rq && req_noidle(cfqq->next_rq))
enable_idle = 0;
-   else if (!atomic_read(>icq.ioc->active_ref) ||
+   else if (!refcount_read(>icq.ioc->active_ref) ||
 !cfqd->cfq_slice_idle ||
 (!cfq_cfqq_deep(cfqq) && CFQQ_SEEKY(cfqq)))
enable_idle = 0;
diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h
index df38db2..a1e28c3 100644
--- a/include/linux/iocontext.h
+++ b/include/linux/iocontext.h
@@ -3,6 +3,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 enum {
@@ -96,7 +97,7 @@ struct io_cq {
  */
 struct io_context {
atomic_long_t refcount;
-   atomic_t active_ref;
+   refcount_t active_ref;
atomic_t nr_tasks;
 
/* all the fields below are protected by this lock */
@@ -128,9 +129,9 @@ struct io_context {
 static inline void get_io_context_active(struct io_context *ioc)
 {
WARN_ON_ONCE(atomic_long_read(>refcount) <= 0);
-   WARN_ON_ONCE(atomic_read(>active_ref) <= 0);
+   WARN_ON_ONCE(refcount_read(>active_ref) == 0);
atomic_long_inc(>refcount);
-   atomic_inc(>active_ref);
+   refcount_inc(>active_ref);
 }
 
 static inline void ioc_task_link(struct io_context *ioc)
-- 
2.7.4



[PATCH 5/6] block: convert bsg_device.ref_count from atomic_t to refcount_t

2017-10-20 Thread Elena Reshetova
atomic_t variables are currently used to implement reference
counters with the following properties:
 - counter is initialized to 1 using atomic_set()
 - a resource is freed upon counter reaching zero
 - once counter reaches zero, its further
   increments aren't allowed
 - counter schema uses basic atomic operations
   (set, inc, inc_not_zero, dec_and_test, etc.)

Such atomic variables should be converted to a newly provided
refcount_t type and API that prevents accidental counter overflows
and underflows. This is important since overflows and underflows
can lead to use-after-free situation and be exploitable.

The variable bsg_device.ref_count is used as pure reference counter.
Convert it to refcount_t and fix up the operations.

Suggested-by: Kees Cook 
Reviewed-by: David Windsor 
Reviewed-by: Hans Liljestrand 
Signed-off-by: Elena Reshetova 
---
 block/bsg.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/block/bsg.c b/block/bsg.c
index ee1335c..6c98422 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -38,7 +39,7 @@ struct bsg_device {
struct list_head busy_list;
struct list_head done_list;
struct hlist_node dev_list;
-   atomic_t ref_count;
+   refcount_t ref_count;
int queued_cmds;
int done_cmds;
wait_queue_head_t wq_done;
@@ -710,7 +711,7 @@ static int bsg_put_device(struct bsg_device *bd)
 
mutex_lock(_mutex);
 
-   do_free = atomic_dec_and_test(>ref_count);
+   do_free = refcount_dec_and_test(>ref_count);
if (!do_free) {
mutex_unlock(_mutex);
goto out;
@@ -768,7 +769,7 @@ static struct bsg_device *bsg_add_device(struct inode 
*inode,
 
bsg_set_block(bd, file);
 
-   atomic_set(>ref_count, 1);
+   refcount_set(>ref_count, 1);
mutex_lock(_mutex);
hlist_add_head(>dev_list, bsg_dev_idx_hash(iminor(inode)));
 
@@ -788,7 +789,7 @@ static struct bsg_device *__bsg_get_device(int minor, 
struct request_queue *q)
 
hlist_for_each_entry(bd, bsg_dev_idx_hash(minor), dev_list) {
if (bd->queue == q) {
-   atomic_inc(>ref_count);
+   refcount_inc(>ref_count);
goto found;
}
}
-- 
2.7.4



[PATCH 2/6] block: convert blk_queue_tag.refcnt from atomic_t to refcount_t

2017-10-20 Thread Elena Reshetova
atomic_t variables are currently used to implement reference
counters with the following properties:
 - counter is initialized to 1 using atomic_set()
 - a resource is freed upon counter reaching zero
 - once counter reaches zero, its further
   increments aren't allowed
 - counter schema uses basic atomic operations
   (set, inc, inc_not_zero, dec_and_test, etc.)

Such atomic variables should be converted to a newly provided
refcount_t type and API that prevents accidental counter overflows
and underflows. This is important since overflows and underflows
can lead to use-after-free situation and be exploitable.

The variable blk_queue_tag.refcnt is used as pure reference counter.
Convert it to refcount_t and fix up the operations.

Suggested-by: Kees Cook 
Reviewed-by: David Windsor 
Reviewed-by: Hans Liljestrand 
Signed-off-by: Elena Reshetova 
---
 block/blk-tag.c| 8 
 include/linux/blkdev.h | 3 ++-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/block/blk-tag.c b/block/blk-tag.c
index e1a9c15..a7263e3 100644
--- a/block/blk-tag.c
+++ b/block/blk-tag.c
@@ -35,7 +35,7 @@ EXPORT_SYMBOL(blk_queue_find_tag);
  */
 void blk_free_tags(struct blk_queue_tag *bqt)
 {
-   if (atomic_dec_and_test(>refcnt)) {
+   if (refcount_dec_and_test(>refcnt)) {
BUG_ON(find_first_bit(bqt->tag_map, bqt->max_depth) <
bqt->max_depth);
 
@@ -130,7 +130,7 @@ static struct blk_queue_tag *__blk_queue_init_tags(struct 
request_queue *q,
if (init_tag_map(q, tags, depth))
goto fail;
 
-   atomic_set(>refcnt, 1);
+   refcount_set(>refcnt, 1);
tags->alloc_policy = alloc_policy;
tags->next_tag = 0;
return tags;
@@ -180,7 +180,7 @@ int blk_queue_init_tags(struct request_queue *q, int depth,
queue_flag_set(QUEUE_FLAG_QUEUED, q);
return 0;
} else
-   atomic_inc(>refcnt);
+   refcount_inc(>refcnt);
 
/*
 * assign it, all done
@@ -225,7 +225,7 @@ int blk_queue_resize_tags(struct request_queue *q, int 
new_depth)
 * Currently cannot replace a shared tag map with a new
 * one, so error out if this is the case
 */
-   if (atomic_read(>refcnt) != 1)
+   if (refcount_read(>refcnt) != 1)
return -EBUSY;
 
/*
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 02fa42d..1fefdbb 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include 
+#include 
 
 struct module;
 struct scsi_ioctl_command;
@@ -295,7 +296,7 @@ struct blk_queue_tag {
unsigned long *tag_map; /* bit map of free/busy tags */
int max_depth;  /* what we will send to device */
int real_max_depth; /* what the array can hold */
-   atomic_t refcnt;/* map can be shared */
+   refcount_t refcnt;  /* map can be shared */
int alloc_policy;   /* tag allocation policy */
int next_tag;   /* next tag */
 };
-- 
2.7.4



[PATCH 0/6] v4 block refcount conversion patches

2017-10-20 Thread Elena Reshetova
Changes in v4:
 - Improved commit messages and signoff info.
 - Rebase on top of linux-next as of yesterday.
 - WARN_ONs are restored since x86 refcount_t does not WARN on zero

Changes in v3:
No changes in patches apart from trivial rebases, but now by
default refcount_t = atomic_t and uses all atomic standard operations
unless CONFIG_REFCOUNT_FULL is enabled. This is a compromize for the
systems that are critical on performance and cannot accept even
slight delay on the refcounter operations.

Changes in v2:
Not needed WARNs are removed since refcount_t warns by itself.
BUG_ONs are left as it is, since refcount_t doesn't bug by default.

This series, for block subsystem, replaces atomic_t reference
counters with the new refcount_t type and API (see include/linux/refcount.h).
By doing this we prevent intentional or accidental
underflows or overflows that can lead to use-after-free vulnerabilities.

The patches are fully independent and can be cherry-picked separately.
If there are no objections to the patches, please merge them via respective 
trees.

Elena Reshetova (6):
  block: convert bio.__bi_cnt from atomic_t to refcount_t
  block: convert blk_queue_tag.refcnt from atomic_t to refcount_t
  block: convert blkcg_gq.refcnt from atomic_t to refcount_t
  block: convert io_context.active_ref from atomic_t to refcount_t
  block: convert bsg_device.ref_count from atomic_t to refcount_t
  drivers, block: convert xen_blkif.refcnt from atomic_t to refcount_t

 block/bfq-iosched.c|  2 +-
 block/bio.c|  6 +++---
 block/blk-cgroup.c |  2 +-
 block/blk-ioc.c|  4 ++--
 block/blk-tag.c|  8 
 block/bsg.c|  9 +
 block/cfq-iosched.c|  4 ++--
 drivers/block/xen-blkback/common.h |  7 ---
 drivers/block/xen-blkback/xenbus.c |  2 +-
 fs/btrfs/volumes.c |  2 +-
 include/linux/bio.h|  4 ++--
 include/linux/blk-cgroup.h | 11 ++-
 include/linux/blk_types.h  |  3 ++-
 include/linux/blkdev.h |  3 ++-
 include/linux/iocontext.h  |  7 ---
 15 files changed, 40 insertions(+), 34 deletions(-)

-- 
2.7.4



Re: [PATCH v2 02/15] usb: gadget: make config_item_type structures const

2017-10-20 Thread Bhumika Goyal
On Thu, Oct 19, 2017 at 5:05 PM, Laurent Pinchart
 wrote:
> Hi Christoph,
>
> On Thursday, 19 October 2017 17:06:57 EEST Christoph Hellwig wrote:
>> > Now we have 9 const instances of the config_item_type structure that are
>> > identical, with only the .ct_owner field set. Should they be all merged
>> > into a single structure ?
>>
>> I think that's a good idea.
>>
>> But I'm about to slurp up this whole series into my tree, how about making
>> that an incremental patch?
>
> I'm fine with that.
>
> Bhumika, would you like to submit an incremental patch, or should I do it ?
>

I will submit a patch for merging these structures.
But should I make a separate patch for this particular change or send
a v3 for the whole series?

Thanks,
Bhumika

> --
> Regards,
>
> Laurent Pinchart
>


Re: [PATCH v2 02/15] usb: gadget: make config_item_type structures const

2017-10-20 Thread Julia Lawall


On Thu, 19 Oct 2017, Laurent Pinchart wrote:

> Hi Christoph,
>
> On Thursday, 19 October 2017 17:06:57 EEST Christoph Hellwig wrote:
> > > Now we have 9 const instances of the config_item_type structure that are
> > > identical, with only the .ct_owner field set. Should they be all merged
> > > into a single structure ?
> >
> > I think that's a good idea.
> >
> > But I'm about to slurp up this whole series into my tree, how about making
> > that an incremental patch?
>
> I'm fine with that.
>
> Bhumika, would you like to submit an incremental patch, or should I do it ?

For various types, there seem to be a few hundred of these, eg:

static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
};

static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
};

Would it be desirable to remove them?  I guess one would have to check
that there are not any pointer equality checks on these values.  Would it
be useful to put a #define to keep the orignal names?

julia


Re: [PATCH] scsi/eh: fix hang adding ehandler wakeups after decrementing host_busy

2017-10-20 Thread Pavel Tikhomirov

ping

On 09/05/2017 03:54 PM, Pavel Tikhomirov wrote:

We have a problem on several our nodes with scsi EH. Imagine such an
order of execution of two threads:

CPU1 scsi_eh_scmd_add   CPU2 scsi_host_queue_ready
/* shost->host_busy == 1 initialy */

if (shost->shost_state == SHOST_RECOVERY)
/* does not get here */
return 0;

lock(shost->host_lock);
shost->shost_state = SHOST_RECOVERY;

busy = shost->host_busy++;
/* host->can_queue == 1 initialy, busy == 1
 * - go to starved label */
lock(shost->host_lock) /* wait */

shost->host_failed++;
/* shost->host_busy == 2, shost->host_failed == 1 */
call scsi_eh_wakeup(shost) {
if (host_busy == host_failed) {
/* does not get here */
wake_up_process(shost->ehandler)
}
}
unlock(shost->host_lock)

/* acquire lock */
shost->host_busy--;

Finaly we do not wakeup scsi_error_handler and all other commands
coming will hang as we are in never ending recovery state as there
is no one left to wakeup handler.

So scsi disc in these host becomes unresponsive and all bio on node
hangs. (We trigger these problem when scsi cmnds to DVD drive timeout.)

Main idea of the fix is to try to do wake up every time we decrement
host_busy or increment host_failed(the latter is already OK).

Now the very *last* one of busy threads getting host_lock after
decrementing host_busy will see all write operations on host's
shost_state, host_busy and host_failed completed thanks to implied
memory barriers on spin_lock/unlock, so at the time of busy==failed
we will trigger wakeup in at least one thread. (Thats why putting
recovery and failed checks under lock)

Signed-off-by: Pavel Tikhomirov 
---
  drivers/scsi/scsi_lib.c | 21 +
  1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index f6097b89d5d3..6c99221d60aa 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -320,12 +320,11 @@ void scsi_device_unbusy(struct scsi_device *sdev)
if (starget->can_queue > 0)
atomic_dec(>target_busy);
  
+	spin_lock_irqsave(shost->host_lock, flags);

if (unlikely(scsi_host_in_recovery(shost) &&
-(shost->host_failed || shost->host_eh_scheduled))) {
-   spin_lock_irqsave(shost->host_lock, flags);
+(shost->host_failed || shost->host_eh_scheduled)))
scsi_eh_wakeup(shost);
-   spin_unlock_irqrestore(shost->host_lock, flags);
-   }
+   spin_unlock_irqrestore(shost->host_lock, flags);
  
  	atomic_dec(>device_busy);

  }
@@ -1503,6 +1502,13 @@ static inline int scsi_host_queue_ready(struct 
request_queue *q,
spin_unlock_irq(shost->host_lock);
  out_dec:
atomic_dec(>host_busy);
+
+   spin_lock_irq(shost->host_lock);
+   if (unlikely(scsi_host_in_recovery(shost) &&
+(shost->host_failed || shost->host_eh_scheduled)))
+   scsi_eh_wakeup(shost);
+   spin_unlock_irq(shost->host_lock);
+
return 0;
  }
  
@@ -1964,6 +1970,13 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
  
  out_dec_host_busy:

atomic_dec(>host_busy);
+
+   spin_lock_irq(shost->host_lock);
+   if (unlikely(scsi_host_in_recovery(shost) &&
+(shost->host_failed || shost->host_eh_scheduled)))
+   scsi_eh_wakeup(shost);
+   spin_unlock_irq(shost->host_lock);
+
  out_dec_target_busy:
if (scsi_target(sdev)->can_queue > 0)
atomic_dec(_target(sdev)->target_busy);



--
Best regards, Tikhomirov Pavel
Software Developer, Virtuozzo.