aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-31 18:31:23 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-31 18:31:23 -0500
commit4e13c5d0212f25d69a97606b9d5a85edb52a7737 (patch)
tree002f59b9151f42a6388656762f0e7963d08b89ef /lib
parentdeb2a1d29bf0168ff2575e714e5c1f156be663fb (diff)
parent5259a06ef97068b710f45d092a587e8d740f750f (diff)
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull SCSI target updates from Nicholas Bellinger: "The highlights this round include: - add support for SCSI Referrals (Hannes) - add support for T10 DIF into target core (nab + mkp) - add support for T10 DIF emulation in FILEIO + RAMDISK backends (Sagi + nab) - add support for T10 DIF -> bio_integrity passthrough in IBLOCK backend (nab) - prep changes to iser-target for >= v3.15 T10 DIF support (Sagi) - add support for qla2xxx N_Port ID Virtualization - NPIV (Saurav + Quinn) - allow percpu_ida_alloc() to receive task state bitmask (Kent) - fix >= v3.12 iscsi-target session reset hung task regression (nab) - fix >= v3.13 percpu_ref se_lun->lun_ref_active race (nab) - fix a long-standing network portal creation race (Andy)" * 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (51 commits) target: Fix percpu_ref_put race in transport_lun_remove_cmd target/iscsi: Fix network portal creation race target: Report bad sector in sense data for DIF errors iscsi-target: Convert gfp_t parameter to task state bitmask iscsi-target: Fix connection reset hang with percpu_ida_alloc percpu_ida: Make percpu_ida_alloc + callers accept task state bitmask iscsi-target: Pre-allocate more tags to avoid ack starvation qla2xxx: Configure NPIV fc_vport via tcm_qla2xxx_npiv_make_lport qla2xxx: Enhancements to enable NPIV support for QLOGIC ISPs with TCM/LIO. qla2xxx: Fix scsi_host leak on qlt_lport_register callback failure IB/isert: pass scatterlist instead of cmd to fast_reg_mr routine IB/isert: Move fastreg descriptor creation to a function IB/isert: Avoid frwr notation, user fastreg IB/isert: seperate connection protection domains and dma MRs tcm_loop: Enable DIF/DIX modes in SCSI host LLD target/rd: Add DIF protection into rd_execute_rw target/rd: Add support for protection SGL setup + release target/rd: Refactor rd_build_device_space + rd_release_device_space target/file: Add DIF protection support to fd_execute_rw target/file: Add DIF protection init/format support ...
Diffstat (limited to 'lib')
-rw-r--r--lib/percpu_ida.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/lib/percpu_ida.c b/lib/percpu_ida.c
index 9d054bf91d0f..7be235f1a70b 100644
--- a/lib/percpu_ida.c
+++ b/lib/percpu_ida.c
@@ -132,22 +132,22 @@ static inline unsigned alloc_local_tag(struct percpu_ida_cpu *tags)
132/** 132/**
133 * percpu_ida_alloc - allocate a tag 133 * percpu_ida_alloc - allocate a tag
134 * @pool: pool to allocate from 134 * @pool: pool to allocate from
135 * @gfp: gfp flags 135 * @state: task state for prepare_to_wait
136 * 136 *
137 * Returns a tag - an integer in the range [0..nr_tags) (passed to 137 * Returns a tag - an integer in the range [0..nr_tags) (passed to
138 * tag_pool_init()), or otherwise -ENOSPC on allocation failure. 138 * tag_pool_init()), or otherwise -ENOSPC on allocation failure.
139 * 139 *
140 * Safe to be called from interrupt context (assuming it isn't passed 140 * Safe to be called from interrupt context (assuming it isn't passed
141 * __GFP_WAIT, of course). 141 * TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, of course).
142 * 142 *
143 * @gfp indicates whether or not to wait until a free id is available (it's not 143 * @gfp indicates whether or not to wait until a free id is available (it's not
144 * used for internal memory allocations); thus if passed __GFP_WAIT we may sleep 144 * used for internal memory allocations); thus if passed __GFP_WAIT we may sleep
145 * however long it takes until another thread frees an id (same semantics as a 145 * however long it takes until another thread frees an id (same semantics as a
146 * mempool). 146 * mempool).
147 * 147 *
148 * Will not fail if passed __GFP_WAIT. 148 * Will not fail if passed TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE.
149 */ 149 */
150int percpu_ida_alloc(struct percpu_ida *pool, gfp_t gfp) 150int percpu_ida_alloc(struct percpu_ida *pool, int state)
151{ 151{
152 DEFINE_WAIT(wait); 152 DEFINE_WAIT(wait);
153 struct percpu_ida_cpu *tags; 153 struct percpu_ida_cpu *tags;
@@ -174,7 +174,8 @@ int percpu_ida_alloc(struct percpu_ida *pool, gfp_t gfp)
174 * 174 *
175 * global lock held and irqs disabled, don't need percpu lock 175 * global lock held and irqs disabled, don't need percpu lock
176 */ 176 */
177 prepare_to_wait(&pool->wait, &wait, TASK_UNINTERRUPTIBLE); 177 if (state != TASK_RUNNING)
178 prepare_to_wait(&pool->wait, &wait, state);
178 179
179 if (!tags->nr_free) 180 if (!tags->nr_free)
180 alloc_global_tags(pool, tags); 181 alloc_global_tags(pool, tags);
@@ -191,16 +192,22 @@ int percpu_ida_alloc(struct percpu_ida *pool, gfp_t gfp)
191 spin_unlock(&pool->lock); 192 spin_unlock(&pool->lock);
192 local_irq_restore(flags); 193 local_irq_restore(flags);
193 194
194 if (tag >= 0 || !(gfp & __GFP_WAIT)) 195 if (tag >= 0 || state == TASK_RUNNING)
195 break; 196 break;
196 197
198 if (signal_pending_state(state, current)) {
199 tag = -ERESTARTSYS;
200 break;
201 }
202
197 schedule(); 203 schedule();
198 204
199 local_irq_save(flags); 205 local_irq_save(flags);
200 tags = this_cpu_ptr(pool->tag_cpu); 206 tags = this_cpu_ptr(pool->tag_cpu);
201 } 207 }
208 if (state != TASK_RUNNING)
209 finish_wait(&pool->wait, &wait);
202 210
203 finish_wait(&pool->wait, &wait);
204 return tag; 211 return tag;
205} 212}
206EXPORT_SYMBOL_GPL(percpu_ida_alloc); 213EXPORT_SYMBOL_GPL(percpu_ida_alloc);