From: Greg Kroah-Hartman Date: Mon, 14 Jan 2013 17:26:26 +0000 (-0800) Subject: 3.7-stable patches X-Git-Tag: v3.7.3~72 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=81653e2c4307756729b53d81d36ee7f26e9a7fcc;p=thirdparty%2Fkernel%2Fstable-queue.git 3.7-stable patches added patches: ib-mlx4-fix-spinlock-order-to-avoid-lockdep-warnings.patch libata-fix-null-pointer-dereference-on-disk-error.patch libata-set-dma_mode-to-0xff-in-reset.patch mlx4_core-fix-potential-deadlock-in-mlx4_eq_int.patch pstore-ram-fix-undefined-usage-of-rounddown_pow_of_two-0.patch sbp-target-fix-error-path-in-sbp_make_tpg.patch sony-laptop-fix-snc-buffer-calls-when-sn06-returns-integers.patch target-file-fix-32-bit-highmem-breakage-for-sgl-iovec-mapping.patch target-tcm_fc-fix-the-lockdep-warning-due-to-inconsistent-lock-state.patch --- diff --git a/queue-3.7/ib-mlx4-fix-spinlock-order-to-avoid-lockdep-warnings.patch b/queue-3.7/ib-mlx4-fix-spinlock-order-to-avoid-lockdep-warnings.patch new file mode 100644 index 00000000000..6a40f740887 --- /dev/null +++ b/queue-3.7/ib-mlx4-fix-spinlock-order-to-avoid-lockdep-warnings.patch @@ -0,0 +1,45 @@ +From ceb7decb366591e9b67d70832e07f5d240572a3d Mon Sep 17 00:00:00 2001 +From: Jack Morgenstein +Date: Tue, 27 Nov 2012 16:24:29 +0000 +Subject: IB/mlx4: Fix spinlock order to avoid lockdep warnings + +From: Jack Morgenstein + +commit ceb7decb366591e9b67d70832e07f5d240572a3d upstream. + +lockdep warns about taking a hard-irq-unsafe lock (sriov->id_map_lock) +inside a hard-irq-safe lock (sriov->going_down_lock). + +Since id_map_lock is never taken in the interrupt context, we can +simply reverse the order of taking the two spinlocks, thus avoiding +the warning and the depencency. + +Signed-off-by: Jack Morgenstein +Signed-off-by: Or Gerlitz +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx4/cm.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/infiniband/hw/mlx4/cm.c ++++ b/drivers/infiniband/hw/mlx4/cm.c +@@ -268,15 +268,15 @@ static void schedule_delayed(struct ib_d + struct mlx4_ib_sriov *sriov = &to_mdev(ibdev)->sriov; + unsigned long flags; + +- spin_lock_irqsave(&sriov->going_down_lock, flags); + spin_lock(&sriov->id_map_lock); ++ spin_lock_irqsave(&sriov->going_down_lock, flags); + /*make sure that there is no schedule inside the scheduled work.*/ + if (!sriov->is_going_down) { + id->scheduled_delete = 1; + schedule_delayed_work(&id->timeout, CM_CLEANUP_CACHE_TIMEOUT); + } +- spin_unlock(&sriov->id_map_lock); + spin_unlock_irqrestore(&sriov->going_down_lock, flags); ++ spin_unlock(&sriov->id_map_lock); + } + + int mlx4_ib_multiplex_cm_handler(struct ib_device *ibdev, int port, int slave_id, diff --git a/queue-3.7/libata-fix-null-pointer-dereference-on-disk-error.patch b/queue-3.7/libata-fix-null-pointer-dereference-on-disk-error.patch new file mode 100644 index 00000000000..98d8431ffe1 --- /dev/null +++ b/queue-3.7/libata-fix-null-pointer-dereference-on-disk-error.patch @@ -0,0 +1,56 @@ +From 26cd4d65deba587f3cf2329b6869ce02bcbe68ec Mon Sep 17 00:00:00 2001 +From: Xiaotian Feng +Date: Thu, 13 Dec 2012 16:12:18 +0800 +Subject: libata: fix Null pointer dereference on disk error + +From: Xiaotian Feng + +commit 26cd4d65deba587f3cf2329b6869ce02bcbe68ec upstream. + +Following oops were observed when disk error happened: + +[ 4272.896937] sd 0:0:0:0: [sda] Unhandled error code +[ 4272.896939] sd 0:0:0:0: [sda] Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK +[ 4272.896942] sd 0:0:0:0: [sda] CDB: Read(10): 28 00 00 5a de a7 00 00 08 00 +[ 4272.896951] end_request: I/O error, dev sda, sector 5955239 +[ 4291.574947] BUG: unable to handle kernel NULL pointer dereference at (null) +[ 4291.658305] IP: [] ahci_activity_show+0x1/0x40 +[ 4291.730090] PGD 76dbbc067 PUD 6c4fba067 PMD 0 +[ 4291.783408] Oops: 0000 [#1] SMP +[ 4291.822100] last sysfs file: /sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/sw_activity +[ 4291.934235] CPU 9 +[ 4291.958301] Pid: 27942, comm: hwinfo ...... + +ata_scsi_find_dev could return NULL, so ata_scsi_activity_{show,store} should check if atadev is NULL. + +Signed-off-by: Xiaotian Feng +Cc: James Bottomley +Signed-off-by: Jeff Garzik +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ata/libata-scsi.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/ata/libata-scsi.c ++++ b/drivers/ata/libata-scsi.c +@@ -309,7 +309,8 @@ ata_scsi_activity_show(struct device *de + struct ata_port *ap = ata_shost_to_port(sdev->host); + struct ata_device *atadev = ata_scsi_find_dev(ap, sdev); + +- if (ap->ops->sw_activity_show && (ap->flags & ATA_FLAG_SW_ACTIVITY)) ++ if (atadev && ap->ops->sw_activity_show && ++ (ap->flags & ATA_FLAG_SW_ACTIVITY)) + return ap->ops->sw_activity_show(atadev, buf); + return -EINVAL; + } +@@ -324,7 +325,8 @@ ata_scsi_activity_store(struct device *d + enum sw_activity val; + int rc; + +- if (ap->ops->sw_activity_store && (ap->flags & ATA_FLAG_SW_ACTIVITY)) { ++ if (atadev && ap->ops->sw_activity_store && ++ (ap->flags & ATA_FLAG_SW_ACTIVITY)) { + val = simple_strtoul(buf, NULL, 0); + switch (val) { + case OFF: case BLINK_ON: case BLINK_OFF: diff --git a/queue-3.7/libata-set-dma_mode-to-0xff-in-reset.patch b/queue-3.7/libata-set-dma_mode-to-0xff-in-reset.patch new file mode 100644 index 00000000000..aef05b42484 --- /dev/null +++ b/queue-3.7/libata-set-dma_mode-to-0xff-in-reset.patch @@ -0,0 +1,50 @@ +From 5416912af75de9cba5d1c75b99a7888b0bbbd2fb Mon Sep 17 00:00:00 2001 +From: Aaron Lu +Date: Mon, 3 Dec 2012 11:35:02 +0800 +Subject: libata: set dma_mode to 0xff in reset + +From: Aaron Lu + +commit 5416912af75de9cba5d1c75b99a7888b0bbbd2fb upstream. + +ata_device->dma_mode's initial value is zero, which is not a valid dma +mode, but ata_dma_enabled will return true for this value. This patch +sets dma_mode to 0xff in reset function, so that ata_dma_enabled will +not return true for this case, or it will cause problem for pata_acpi. + +The corrsponding bugzilla page is at: +https://bugzilla.kernel.org/show_bug.cgi?id=49151 + +Reported-by: Phillip Wood +Signed-off-by: Aaron Lu +Tested-by: Szymon Janc +Tested-by: Dutra Julio +Acked-by: Alan Cox +Signed-off-by: Jeff Garzik +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ata/libata-core.c | 1 + + drivers/ata/libata-eh.c | 1 + + 2 files changed, 2 insertions(+) + +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -2560,6 +2560,7 @@ int ata_bus_probe(struct ata_port *ap) + * bus as we may be talking too fast. + */ + dev->pio_mode = XFER_PIO_0; ++ dev->dma_mode = 0xff; + + /* If the controller has a pio mode setup function + * then use it to set the chipset to rights. Don't +--- a/drivers/ata/libata-eh.c ++++ b/drivers/ata/libata-eh.c +@@ -2657,6 +2657,7 @@ int ata_eh_reset(struct ata_link *link, + * bus as we may be talking too fast. + */ + dev->pio_mode = XFER_PIO_0; ++ dev->dma_mode = 0xff; + + /* If the controller has a pio mode setup function + * then use it to set the chipset to rights. Don't diff --git a/queue-3.7/mlx4_core-fix-potential-deadlock-in-mlx4_eq_int.patch b/queue-3.7/mlx4_core-fix-potential-deadlock-in-mlx4_eq_int.patch new file mode 100644 index 00000000000..10015671e3f --- /dev/null +++ b/queue-3.7/mlx4_core-fix-potential-deadlock-in-mlx4_eq_int.patch @@ -0,0 +1,107 @@ +From 311f813a2daefcba03f706a692fe0c67888d7622 Mon Sep 17 00:00:00 2001 +From: Jack Morgenstein +Date: Tue, 27 Nov 2012 16:24:30 +0000 +Subject: mlx4_core: Fix potential deadlock in mlx4_eq_int() + +From: Jack Morgenstein + +commit 311f813a2daefcba03f706a692fe0c67888d7622 upstream. + +The slave_state_lock spinlock is used in both interrupt context and +process context, hence irq locking must be used. Found by lockdep. + +Signed-off-by: Jack Morgenstein +Signed-off-by: Or Gerlitz +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ethernet/mellanox/mlx4/cmd.c | 9 +++++---- + drivers/net/ethernet/mellanox/mlx4/eq.c | 10 ++++++---- + 2 files changed, 11 insertions(+), 8 deletions(-) + +--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c ++++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c +@@ -1498,6 +1498,7 @@ static void mlx4_master_do_cmd(struct ml + u32 reply; + u8 is_going_down = 0; + int i; ++ unsigned long flags; + + slave_state[slave].comm_toggle ^= 1; + reply = (u32) slave_state[slave].comm_toggle << 31; +@@ -1576,12 +1577,12 @@ static void mlx4_master_do_cmd(struct ml + mlx4_warn(dev, "Bad comm cmd:%d from slave:%d\n", cmd, slave); + goto reset_slave; + } +- spin_lock(&priv->mfunc.master.slave_state_lock); ++ spin_lock_irqsave(&priv->mfunc.master.slave_state_lock, flags); + if (!slave_state[slave].is_slave_going_down) + slave_state[slave].last_cmd = cmd; + else + is_going_down = 1; +- spin_unlock(&priv->mfunc.master.slave_state_lock); ++ spin_unlock_irqrestore(&priv->mfunc.master.slave_state_lock, flags); + if (is_going_down) { + mlx4_warn(dev, "Slave is going down aborting command(%d)" + " executing from slave:%d\n", +@@ -1597,10 +1598,10 @@ static void mlx4_master_do_cmd(struct ml + reset_slave: + /* cleanup any slave resources */ + mlx4_delete_all_resources_for_slave(dev, slave); +- spin_lock(&priv->mfunc.master.slave_state_lock); ++ spin_lock_irqsave(&priv->mfunc.master.slave_state_lock, flags); + if (!slave_state[slave].is_slave_going_down) + slave_state[slave].last_cmd = MLX4_COMM_CMD_RESET; +- spin_unlock(&priv->mfunc.master.slave_state_lock); ++ spin_unlock_irqrestore(&priv->mfunc.master.slave_state_lock, flags); + /*with slave in the middle of flr, no need to clean resources again.*/ + inform_slave_state: + memset(&slave_state[slave].event_eq, 0, +--- a/drivers/net/ethernet/mellanox/mlx4/eq.c ++++ b/drivers/net/ethernet/mellanox/mlx4/eq.c +@@ -401,6 +401,7 @@ void mlx4_master_handle_slave_flr(struct + struct mlx4_slave_state *slave_state = priv->mfunc.master.slave_state; + int i; + int err; ++ unsigned long flags; + + mlx4_dbg(dev, "mlx4_handle_slave_flr\n"); + +@@ -412,10 +413,10 @@ void mlx4_master_handle_slave_flr(struct + + mlx4_delete_all_resources_for_slave(dev, i); + /*return the slave to running mode*/ +- spin_lock(&priv->mfunc.master.slave_state_lock); ++ spin_lock_irqsave(&priv->mfunc.master.slave_state_lock, flags); + slave_state[i].last_cmd = MLX4_COMM_CMD_RESET; + slave_state[i].is_slave_going_down = 0; +- spin_unlock(&priv->mfunc.master.slave_state_lock); ++ spin_unlock_irqrestore(&priv->mfunc.master.slave_state_lock, flags); + /*notify the FW:*/ + err = mlx4_cmd(dev, 0, i, 0, MLX4_CMD_INFORM_FLR_DONE, + MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); +@@ -440,6 +441,7 @@ static int mlx4_eq_int(struct mlx4_dev * + u8 update_slave_state; + int i; + enum slave_port_gen_event gen_event; ++ unsigned long flags; + + while ((eqe = next_eqe_sw(eq))) { + /* +@@ -647,13 +649,13 @@ static int mlx4_eq_int(struct mlx4_dev * + } else + update_slave_state = 1; + +- spin_lock(&priv->mfunc.master.slave_state_lock); ++ spin_lock_irqsave(&priv->mfunc.master.slave_state_lock, flags); + if (update_slave_state) { + priv->mfunc.master.slave_state[flr_slave].active = false; + priv->mfunc.master.slave_state[flr_slave].last_cmd = MLX4_COMM_CMD_FLR; + priv->mfunc.master.slave_state[flr_slave].is_slave_going_down = 1; + } +- spin_unlock(&priv->mfunc.master.slave_state_lock); ++ spin_unlock_irqrestore(&priv->mfunc.master.slave_state_lock, flags); + queue_work(priv->mfunc.master.comm_wq, + &priv->mfunc.master.slave_flr_event_work); + break; diff --git a/queue-3.7/pstore-ram-fix-undefined-usage-of-rounddown_pow_of_two-0.patch b/queue-3.7/pstore-ram-fix-undefined-usage-of-rounddown_pow_of_two-0.patch new file mode 100644 index 00000000000..7e1c36fd4b4 --- /dev/null +++ b/queue-3.7/pstore-ram-fix-undefined-usage-of-rounddown_pow_of_two-0.patch @@ -0,0 +1,47 @@ +From b042e47491ba5f487601b5141a3f1d8582304170 Mon Sep 17 00:00:00 2001 +From: Maxime Bizon +Date: Mon, 22 Oct 2012 11:19:28 +0200 +Subject: pstore/ram: Fix undefined usage of rounddown_pow_of_two(0) + +From: Maxime Bizon + +commit b042e47491ba5f487601b5141a3f1d8582304170 upstream. + +record_size / console_size / ftrace_size can be 0 (this is how you disable +the feature), but rounddown_pow_of_two(0) is undefined. As suggested by +Kees Cook, use !is_power_of_2() as a condition to call +rounddown_pow_of_two and avoid its undefined behavior on the value 0. This +issue has been present since commit 1894a253 (ramoops: Move to +fs/pstore/ram.c). + +Signed-off-by: Maxime Bizon +Signed-off-by: Florian Fainelli +Acked-by: Kees Cook +Signed-off-by: Anton Vorontsov +Signed-off-by: Greg Kroah-Hartman + +--- + fs/pstore/ram.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +--- a/fs/pstore/ram.c ++++ b/fs/pstore/ram.c +@@ -374,10 +374,14 @@ static int __devinit ramoops_probe(struc + goto fail_out; + } + +- pdata->mem_size = rounddown_pow_of_two(pdata->mem_size); +- pdata->record_size = rounddown_pow_of_two(pdata->record_size); +- pdata->console_size = rounddown_pow_of_two(pdata->console_size); +- pdata->ftrace_size = rounddown_pow_of_two(pdata->ftrace_size); ++ if (!is_power_of_2(pdata->mem_size)) ++ pdata->mem_size = rounddown_pow_of_two(pdata->mem_size); ++ if (!is_power_of_2(pdata->record_size)) ++ pdata->record_size = rounddown_pow_of_two(pdata->record_size); ++ if (!is_power_of_2(pdata->console_size)) ++ pdata->console_size = rounddown_pow_of_two(pdata->console_size); ++ if (!is_power_of_2(pdata->ftrace_size)) ++ pdata->ftrace_size = rounddown_pow_of_two(pdata->ftrace_size); + + cxt->dump_read_cnt = 0; + cxt->size = pdata->mem_size; diff --git a/queue-3.7/sbp-target-fix-error-path-in-sbp_make_tpg.patch b/queue-3.7/sbp-target-fix-error-path-in-sbp_make_tpg.patch new file mode 100644 index 00000000000..957be3c0272 --- /dev/null +++ b/queue-3.7/sbp-target-fix-error-path-in-sbp_make_tpg.patch @@ -0,0 +1,58 @@ +From e1fe2060d7e8f58a69374135e32e90f0bb79a7fd Mon Sep 17 00:00:00 2001 +From: Chris Boot +Date: Tue, 11 Dec 2012 21:58:48 +0000 +Subject: sbp-target: fix error path in sbp_make_tpg() + +From: Chris Boot + +commit e1fe2060d7e8f58a69374135e32e90f0bb79a7fd upstream. + +If the TPG memory is allocated successfully, but we fail further along +in the function, a dangling pointer to freed memory is left in the TPort +structure. This is mostly harmless, but does prevent re-trying the +operation without first removing the TPort altogether. + +Reported-by: Chen Gang +Signed-off-by: Chris Boot +Cc: Andy Grover +Cc: Nicholas A. Bellinger +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/sbp/sbp_target.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +--- a/drivers/target/sbp/sbp_target.c ++++ b/drivers/target/sbp/sbp_target.c +@@ -2207,20 +2207,23 @@ static struct se_portal_group *sbp_make_ + tport->mgt_agt = sbp_management_agent_register(tport); + if (IS_ERR(tport->mgt_agt)) { + ret = PTR_ERR(tport->mgt_agt); +- kfree(tpg); +- return ERR_PTR(ret); ++ goto out_free_tpg; + } + + ret = core_tpg_register(&sbp_fabric_configfs->tf_ops, wwn, + &tpg->se_tpg, (void *)tpg, + TRANSPORT_TPG_TYPE_NORMAL); +- if (ret < 0) { +- sbp_management_agent_unregister(tport->mgt_agt); +- kfree(tpg); +- return ERR_PTR(ret); +- } ++ if (ret < 0) ++ goto out_unreg_mgt_agt; + + return &tpg->se_tpg; ++ ++out_unreg_mgt_agt: ++ sbp_management_agent_unregister(tport->mgt_agt); ++out_free_tpg: ++ tport->tpg = NULL; ++ kfree(tpg); ++ return ERR_PTR(ret); + } + + static void sbp_drop_tpg(struct se_portal_group *se_tpg) diff --git a/queue-3.7/series b/queue-3.7/series index 81c091229ea..d84e5c9ae23 100644 --- a/queue-3.7/series +++ b/queue-3.7/series @@ -39,3 +39,12 @@ iscsi-target-always-send-a-response-before-terminating-iscsi-connection.patch iscsit-use-gfp_atomic-under-spin-lock.patch qla2xxx-look-up-lun-for-abort-requests.patch sata_promise-fix-hardreset-lockdep-error.patch +sony-laptop-fix-snc-buffer-calls-when-sn06-returns-integers.patch +ib-mlx4-fix-spinlock-order-to-avoid-lockdep-warnings.patch +mlx4_core-fix-potential-deadlock-in-mlx4_eq_int.patch +pstore-ram-fix-undefined-usage-of-rounddown_pow_of_two-0.patch +libata-set-dma_mode-to-0xff-in-reset.patch +libata-fix-null-pointer-dereference-on-disk-error.patch +target-file-fix-32-bit-highmem-breakage-for-sgl-iovec-mapping.patch +target-tcm_fc-fix-the-lockdep-warning-due-to-inconsistent-lock-state.patch +sbp-target-fix-error-path-in-sbp_make_tpg.patch diff --git a/queue-3.7/sony-laptop-fix-snc-buffer-calls-when-sn06-returns-integers.patch b/queue-3.7/sony-laptop-fix-snc-buffer-calls-when-sn06-returns-integers.patch new file mode 100644 index 00000000000..dd156cf5af9 --- /dev/null +++ b/queue-3.7/sony-laptop-fix-snc-buffer-calls-when-sn06-returns-integers.patch @@ -0,0 +1,65 @@ +From dcbeec264d73b7228ffdfe767eab69b2353099b1 Mon Sep 17 00:00:00 2001 +From: Mattia Dongili +Date: Fri, 21 Dec 2012 07:21:09 +0900 +Subject: sony-laptop: fix SNC buffer calls when SN06 returns Integers + +From: Mattia Dongili + +commit dcbeec264d73b7228ffdfe767eab69b2353099b1 upstream. + +SN06 in some cases returns an Integer instead of a buffer. While the +code handling the return value was trying to cope with the difference, +the memcpy call was not making any difference between the two types of +acpi_object union. This regression was introduced in 3.5. +While there also rework the return value logic to improve readability. + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=48671 +Cc: Fabrizio Narni +Cc: +Signed-off-by: Mattia Dongili +Signed-off-by: Matthew Garrett +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/platform/x86/sony-laptop.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +--- a/drivers/platform/x86/sony-laptop.c ++++ b/drivers/platform/x86/sony-laptop.c +@@ -786,28 +786,29 @@ static int sony_nc_int_call(acpi_handle + static int sony_nc_buffer_call(acpi_handle handle, char *name, u64 *value, + void *buffer, size_t buflen) + { ++ int ret = 0; + size_t len = len; + union acpi_object *object = __call_snc_method(handle, name, value); + + if (!object) + return -EINVAL; + +- if (object->type == ACPI_TYPE_BUFFER) ++ if (object->type == ACPI_TYPE_BUFFER) { + len = MIN(buflen, object->buffer.length); ++ memcpy(buffer, object->buffer.pointer, len); + +- else if (object->type == ACPI_TYPE_INTEGER) ++ } else if (object->type == ACPI_TYPE_INTEGER) { + len = MIN(buflen, sizeof(object->integer.value)); ++ memcpy(buffer, &object->integer.value, len); + +- else { ++ } else { + pr_warn("Invalid acpi_object: expected 0x%x got 0x%x\n", + ACPI_TYPE_BUFFER, object->type); +- kfree(object); +- return -EINVAL; ++ ret = -EINVAL; + } + +- memcpy(buffer, object->buffer.pointer, len); + kfree(object); +- return 0; ++ return ret; + } + + struct sony_nc_handles { diff --git a/queue-3.7/target-file-fix-32-bit-highmem-breakage-for-sgl-iovec-mapping.patch b/queue-3.7/target-file-fix-32-bit-highmem-breakage-for-sgl-iovec-mapping.patch new file mode 100644 index 00000000000..22001fc0f4b --- /dev/null +++ b/queue-3.7/target-file-fix-32-bit-highmem-breakage-for-sgl-iovec-mapping.patch @@ -0,0 +1,61 @@ +From 40ff2c3b3da35dd3a00ac6722056a59b4b3f2caf Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +Date: Wed, 5 Dec 2012 12:08:29 +0100 +Subject: target/file: Fix 32-bit highmem breakage for SGL -> iovec mapping + +From: Sebastian Andrzej Siewior + +commit 40ff2c3b3da35dd3a00ac6722056a59b4b3f2caf upstream. + +This patch changes vectored file I/O to use kmap + kunmap when mapping +incoming SGL memory -> struct iovec in order to properly support 32-bit +highmem configurations. This is because an extra bounce buffer may be +required when processing scatterlist pages allocated with GFP_KERNEL. + +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_file.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/target/target_core_file.c ++++ b/drivers/target/target_core_file.c +@@ -260,7 +260,7 @@ static int fd_do_readv(struct se_cmd *cm + + for_each_sg(sgl, sg, sgl_nents, i) { + iov[i].iov_len = sg->length; +- iov[i].iov_base = sg_virt(sg); ++ iov[i].iov_base = kmap(sg_page(sg)) + sg->offset; + } + + old_fs = get_fs(); +@@ -268,6 +268,8 @@ static int fd_do_readv(struct se_cmd *cm + ret = vfs_readv(fd, &iov[0], sgl_nents, &pos); + set_fs(old_fs); + ++ for_each_sg(sgl, sg, sgl_nents, i) ++ kunmap(sg_page(sg)); + kfree(iov); + /* + * Return zeros and GOOD status even if the READ did not return +@@ -313,7 +315,7 @@ static int fd_do_writev(struct se_cmd *c + + for_each_sg(sgl, sg, sgl_nents, i) { + iov[i].iov_len = sg->length; +- iov[i].iov_base = sg_virt(sg); ++ iov[i].iov_base = kmap(sg_page(sg)) + sg->offset; + } + + old_fs = get_fs(); +@@ -321,6 +323,9 @@ static int fd_do_writev(struct se_cmd *c + ret = vfs_writev(fd, &iov[0], sgl_nents, &pos); + set_fs(old_fs); + ++ for_each_sg(sgl, sg, sgl_nents, i) ++ kunmap(sg_page(sg)); ++ + kfree(iov); + + if (ret < 0 || ret != cmd->data_length) { diff --git a/queue-3.7/target-tcm_fc-fix-the-lockdep-warning-due-to-inconsistent-lock-state.patch b/queue-3.7/target-tcm_fc-fix-the-lockdep-warning-due-to-inconsistent-lock-state.patch new file mode 100644 index 00000000000..761212e63c2 --- /dev/null +++ b/queue-3.7/target-tcm_fc-fix-the-lockdep-warning-due-to-inconsistent-lock-state.patch @@ -0,0 +1,142 @@ +From 9f4ad44b264f8bb61ffdd607148215566568430d Mon Sep 17 00:00:00 2001 +From: Yi Zou +Date: Mon, 10 Dec 2012 17:04:00 -0800 +Subject: target/tcm_fc: fix the lockdep warning due to inconsistent lock state + +From: Yi Zou + +commit 9f4ad44b264f8bb61ffdd607148215566568430d upstream. + +The lockdep warning below is in theory correct but it will be in really weird +rare situation that ends up that deadlock since the tcm fc session is hashed +based the rport id. Nonetheless, the complaining below is about rcu callback +that does the transport_deregister_session() is happening in softirq, where +transport_register_session() that happens earlier is not. This triggers the +lockdep warning below. So, just fix this to make lockdep happy by disabling +the soft irq before calling transport_register_session() in ft_prli. + +BTW, this was found in FCoE VN2VN over two VMs, couple of create and destroy +would get this triggered. + +v1: was enforcing register to be in softirq context which was not righ. See, +http://www.spinics.net/lists/target-devel/msg03614.html + +v2: following comments from Roland&Nick (thanks), it seems we don't have to +do transport_deregister_session() in rcu callback, so move it into ft_sess_free() +but still do kfree() of the corresponding ft_sess struct in rcu callback to +make sure the ft_sess is not freed till the rcu callback. + +... +[ 1328.370592] scsi2 : FCoE Driver +[ 1328.383429] fcoe: No FDMI support. +[ 1328.384509] host2: libfc: Link up on port (000000) +[ 1328.934229] host2: Assigned Port ID 00a292 +[ 1357.232132] host2: rport 00a393: Remove port +[ 1357.232568] host2: rport 00a393: Port sending LOGO from Ready state +[ 1357.233692] host2: rport 00a393: Delete port +[ 1357.234472] host2: rport 00a393: work event 3 +[ 1357.234969] host2: rport 00a393: callback ev 3 +[ 1357.235979] host2: rport 00a393: Received a LOGO response closed +[ 1357.236706] host2: rport 00a393: work delete +[ 1357.237481] +[ 1357.237631] ================================= +[ 1357.238064] [ INFO: inconsistent lock state ] +[ 1357.238450] 3.7.0-rc7-yikvm+ #3 Tainted: G O +[ 1357.238450] --------------------------------- +[ 1357.238450] inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage. +[ 1357.238450] ksoftirqd/0/3 [HC0[0]:SC1[1]:HE0:SE0] takes: +[ 1357.238450] (&(&se_tpg->session_lock)->rlock){+.?...}, at: [] transport_deregister_session+0x41/0x148 [target_core_mod] +[ 1357.238450] {SOFTIRQ-ON-W} state was registered at: +[ 1357.238450] [] mark_held_locks+0x6d/0x95 +[ 1357.238450] [] trace_hardirqs_on_caller+0x12d/0x197 +[ 1357.238450] [] trace_hardirqs_on+0xd/0xf +[ 1357.238450] [] _raw_spin_unlock_irq+0x2d/0x45 +[ 1357.238450] [] __transport_register_session+0xb8/0x122 [target_core_mod] +[ 1357.238450] [] transport_register_session+0x44/0x5a [target_core_mod] +[ 1357.238450] [] ft_prli+0x1e3/0x275 [tcm_fc] +[ 1357.238450] [] fc_rport_recv_req+0x95e/0xdc5 [libfc] +[ 1357.238450] [] fc_lport_recv_els_req+0xc4/0xd5 [libfc] +[ 1357.238450] [] fc_lport_recv_req+0x12f/0x18f [libfc] +[ 1357.238450] [] fc_exch_recv+0x8ba/0x981 [libfc] +[ 1357.238450] [] fcoe_percpu_receive_thread+0x47a/0x4e2 [fcoe] +[ 1357.238450] [] kthread+0xb1/0xb9 +[ 1357.238450] [] ret_from_fork+0x7c/0xb0 +[ 1357.238450] irq event stamp: 275411 +[ 1357.238450] hardirqs last enabled at (275410): [] rcu_process_callbacks+0x229/0x42a +[ 1357.238450] hardirqs last disabled at (275411): [] _raw_spin_lock_irqsave+0x22/0x8e +[ 1357.238450] softirqs last enabled at (275394): [] __do_softirq+0x246/0x26f +[ 1357.238450] softirqs last disabled at (275399): [] run_ksoftirqd+0x29/0x62 +[ 1357.238450] +[ 1357.238450] other info that might help us debug this: +[ 1357.238450] Possible unsafe locking scenario: +[ 1357.238450] +[ 1357.238450] CPU0 +[ 1357.238450] ---- +[ 1357.238450] lock(&(&se_tpg->session_lock)->rlock); +[ 1357.238450] +[ 1357.238450] lock(&(&se_tpg->session_lock)->rlock); +[ 1357.238450] +[ 1357.238450] *** DEADLOCK *** +[ 1357.238450] +[ 1357.238450] no locks held by ksoftirqd/0/3. +[ 1357.238450] +[ 1357.238450] stack backtrace: +[ 1357.238450] Pid: 3, comm: ksoftirqd/0 Tainted: G O 3.7.0-rc7-yikvm+ #3 +[ 1357.238450] Call Trace: +[ 1357.238450] [] print_usage_bug+0x1f5/0x206 +[ 1357.238450] [] ? save_stack_trace+0x2c/0x49 +[ 1357.238450] [] ? print_irq_inversion_bug.part.14+0x1ae/0x1ae +[ 1357.238450] [] mark_lock+0x106/0x258 +[ 1357.238450] [] __lock_acquire+0x2e7/0xe53 +[ 1357.238450] [] ? pvclock_clocksource_read+0x48/0xb4 +[ 1357.238450] [] ? rcu_process_gp_end+0xc0/0xc9 +[ 1357.238450] [] ? transport_deregister_session+0x41/0x148 [target_core_mod] +[ 1357.238450] [] lock_acquire+0x119/0x143 +[ 1357.238450] [] ? transport_deregister_session+0x41/0x148 [target_core_mod] +[ 1357.238450] [] _raw_spin_lock_irqsave+0x54/0x8e +[ 1357.238450] [] ? transport_deregister_session+0x41/0x148 [target_core_mod] +[ 1357.238450] [] transport_deregister_session+0x41/0x148 [target_core_mod] +[ 1357.238450] [] ? rcu_process_callbacks+0x229/0x42a +[ 1357.238450] [] ft_sess_rcu_free+0x17/0x24 [tcm_fc] +[ 1357.238450] [] ? ft_sess_free+0x1b/0x1b [tcm_fc] +[ 1357.238450] [] rcu_process_callbacks+0x260/0x42a +[ 1357.238450] [] __do_softirq+0x13a/0x26f +[ 1357.238450] [] ? __schedule+0x65f/0x68e +[ 1357.238450] [] run_ksoftirqd+0x29/0x62 +[ 1357.238450] [] smpboot_thread_fn+0x1a5/0x1aa +[ 1357.238450] [] ? smpboot_unregister_percpu_thread+0x47/0x47 +[ 1357.238450] [] kthread+0xb1/0xb9 +[ 1357.238450] [] ? wait_for_common+0xbb/0x10a +[ 1357.238450] [] ? __init_kthread_worker+0x59/0x59 +[ 1357.238450] [] ret_from_fork+0x7c/0xb0 +[ 1357.238450] [] ? __init_kthread_worker+0x59/0x59 +[ 1417.440099] rport-2:0-0: blocked FC remote port time out: removing rport + +Signed-off-by: Yi Zou +Cc: Open-FCoE +Cc: Nicholas A. Bellinger +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/tcm_fc/tfc_sess.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/target/tcm_fc/tfc_sess.c ++++ b/drivers/target/tcm_fc/tfc_sess.c +@@ -430,7 +430,6 @@ static void ft_sess_rcu_free(struct rcu_ + { + struct ft_sess *sess = container_of(rcu, struct ft_sess, rcu); + +- transport_deregister_session(sess->se_sess); + kfree(sess); + } + +@@ -438,6 +437,7 @@ static void ft_sess_free(struct kref *kr + { + struct ft_sess *sess = container_of(kref, struct ft_sess, kref); + ++ transport_deregister_session(sess->se_sess); + call_rcu(&sess->rcu, ft_sess_rcu_free); + } +