@@ -98,163 +98,6 @@ EXPORT_SYMBOL(scsi_sd_probe_domain);
98
98
ASYNC_DOMAIN_EXCLUSIVE (scsi_sd_pm_domain );
99
99
EXPORT_SYMBOL (scsi_sd_pm_domain );
100
100
101
- struct scsi_host_cmd_pool {
102
- struct kmem_cache * cmd_slab ;
103
- unsigned int users ;
104
- char * cmd_name ;
105
- };
106
-
107
- static struct scsi_host_cmd_pool scsi_cmd_pool = {
108
- .cmd_name = "scsi_cmd_cache" ,
109
- };
110
-
111
- static DEFINE_MUTEX (host_cmd_pool_mutex );
112
-
113
- /**
114
- * scsi_host_free_command - internal function to release a command
115
- * @shost: host to free the command for
116
- * @cmd: command to release
117
- *
118
- * the command must previously have been allocated by
119
- * scsi_host_alloc_command.
120
- */
121
- static void
122
- scsi_host_free_command (struct Scsi_Host * shost , struct scsi_cmnd * cmd )
123
- {
124
- struct scsi_host_cmd_pool * pool = shost -> cmd_pool ;
125
-
126
- if (cmd -> prot_sdb )
127
- kmem_cache_free (scsi_sdb_cache , cmd -> prot_sdb );
128
- scsi_free_sense_buffer (shost , cmd -> sense_buffer );
129
- kmem_cache_free (pool -> cmd_slab , cmd );
130
- }
131
-
132
- /**
133
- * scsi_host_alloc_command - internal function to allocate command
134
- * @shost: SCSI host whose pool to allocate from
135
- * @gfp_mask: mask for the allocation
136
- *
137
- * Returns a fully allocated command with sense buffer and protection
138
- * data buffer (where applicable) or NULL on failure
139
- */
140
- static struct scsi_cmnd *
141
- scsi_host_alloc_command (struct Scsi_Host * shost , gfp_t gfp_mask )
142
- {
143
- struct scsi_host_cmd_pool * pool = shost -> cmd_pool ;
144
- struct scsi_cmnd * cmd ;
145
-
146
- cmd = kmem_cache_zalloc (pool -> cmd_slab , gfp_mask );
147
- if (!cmd )
148
- goto fail ;
149
-
150
- cmd -> sense_buffer = scsi_alloc_sense_buffer (shost , gfp_mask ,
151
- NUMA_NO_NODE );
152
- if (!cmd -> sense_buffer )
153
- goto fail_free_cmd ;
154
-
155
- if (scsi_host_get_prot (shost ) >= SHOST_DIX_TYPE0_PROTECTION ) {
156
- cmd -> prot_sdb = kmem_cache_zalloc (scsi_sdb_cache , gfp_mask );
157
- if (!cmd -> prot_sdb )
158
- goto fail_free_sense ;
159
- }
160
-
161
- return cmd ;
162
-
163
- fail_free_sense :
164
- scsi_free_sense_buffer (shost , cmd -> sense_buffer );
165
- fail_free_cmd :
166
- kmem_cache_free (pool -> cmd_slab , cmd );
167
- fail :
168
- return NULL ;
169
- }
170
-
171
- /**
172
- * __scsi_get_command - Allocate a struct scsi_cmnd
173
- * @shost: host to transmit command
174
- * @gfp_mask: allocation mask
175
- *
176
- * Description: allocate a struct scsi_cmd from host's slab, recycling from the
177
- * host's free_list if necessary.
178
- */
179
- static struct scsi_cmnd *
180
- __scsi_get_command (struct Scsi_Host * shost , gfp_t gfp_mask )
181
- {
182
- struct scsi_cmnd * cmd = scsi_host_alloc_command (shost , gfp_mask );
183
-
184
- if (unlikely (!cmd )) {
185
- unsigned long flags ;
186
-
187
- spin_lock_irqsave (& shost -> free_list_lock , flags );
188
- if (likely (!list_empty (& shost -> free_list ))) {
189
- cmd = list_entry (shost -> free_list .next ,
190
- struct scsi_cmnd , list );
191
- list_del_init (& cmd -> list );
192
- }
193
- spin_unlock_irqrestore (& shost -> free_list_lock , flags );
194
-
195
- if (cmd ) {
196
- void * buf , * prot ;
197
-
198
- buf = cmd -> sense_buffer ;
199
- prot = cmd -> prot_sdb ;
200
-
201
- memset (cmd , 0 , sizeof (* cmd ));
202
-
203
- cmd -> sense_buffer = buf ;
204
- cmd -> prot_sdb = prot ;
205
- }
206
- }
207
-
208
- return cmd ;
209
- }
210
-
211
- /**
212
- * scsi_get_command - Allocate and setup a scsi command block
213
- * @dev: parent scsi device
214
- * @gfp_mask: allocator flags
215
- *
216
- * Returns: The allocated scsi command structure.
217
- */
218
- struct scsi_cmnd * scsi_get_command (struct scsi_device * dev , gfp_t gfp_mask )
219
- {
220
- struct scsi_cmnd * cmd = __scsi_get_command (dev -> host , gfp_mask );
221
- unsigned long flags ;
222
-
223
- if (unlikely (cmd == NULL ))
224
- return NULL ;
225
-
226
- cmd -> device = dev ;
227
- INIT_LIST_HEAD (& cmd -> list );
228
- INIT_DELAYED_WORK (& cmd -> abort_work , scmd_eh_abort_handler );
229
- spin_lock_irqsave (& dev -> list_lock , flags );
230
- list_add_tail (& cmd -> list , & dev -> cmd_list );
231
- spin_unlock_irqrestore (& dev -> list_lock , flags );
232
- cmd -> jiffies_at_alloc = jiffies ;
233
- return cmd ;
234
- }
235
-
236
- /**
237
- * __scsi_put_command - Free a struct scsi_cmnd
238
- * @shost: dev->host
239
- * @cmd: Command to free
240
- */
241
- static void __scsi_put_command (struct Scsi_Host * shost , struct scsi_cmnd * cmd )
242
- {
243
- unsigned long flags ;
244
-
245
- if (unlikely (list_empty (& shost -> free_list ))) {
246
- spin_lock_irqsave (& shost -> free_list_lock , flags );
247
- if (list_empty (& shost -> free_list )) {
248
- list_add (& cmd -> list , & shost -> free_list );
249
- cmd = NULL ;
250
- }
251
- spin_unlock_irqrestore (& shost -> free_list_lock , flags );
252
- }
253
-
254
- if (likely (cmd != NULL ))
255
- scsi_host_free_command (shost , cmd );
256
- }
257
-
258
101
/**
259
102
* scsi_put_command - Free a scsi command block
260
103
* @cmd: command block to free
@@ -274,168 +117,6 @@ void scsi_put_command(struct scsi_cmnd *cmd)
274
117
spin_unlock_irqrestore (& cmd -> device -> list_lock , flags );
275
118
276
119
BUG_ON (delayed_work_pending (& cmd -> abort_work ));
277
-
278
- __scsi_put_command (cmd -> device -> host , cmd );
279
- }
280
-
281
- static struct scsi_host_cmd_pool *
282
- scsi_find_host_cmd_pool (struct Scsi_Host * shost )
283
- {
284
- if (shost -> hostt -> cmd_size )
285
- return shost -> hostt -> cmd_pool ;
286
- return & scsi_cmd_pool ;
287
- }
288
-
289
- static void
290
- scsi_free_host_cmd_pool (struct scsi_host_cmd_pool * pool )
291
- {
292
- kfree (pool -> cmd_name );
293
- kfree (pool );
294
- }
295
-
296
- static struct scsi_host_cmd_pool *
297
- scsi_alloc_host_cmd_pool (struct Scsi_Host * shost )
298
- {
299
- struct scsi_host_template * hostt = shost -> hostt ;
300
- struct scsi_host_cmd_pool * pool ;
301
-
302
- pool = kzalloc (sizeof (* pool ), GFP_KERNEL );
303
- if (!pool )
304
- return NULL ;
305
-
306
- pool -> cmd_name = kasprintf (GFP_KERNEL , "%s_cmd" , hostt -> proc_name );
307
- if (!pool -> cmd_name ) {
308
- scsi_free_host_cmd_pool (pool );
309
- return NULL ;
310
- }
311
-
312
- if (hostt -> cmd_size )
313
- hostt -> cmd_pool = pool ;
314
-
315
- return pool ;
316
- }
317
-
318
- static struct scsi_host_cmd_pool *
319
- scsi_get_host_cmd_pool (struct Scsi_Host * shost )
320
- {
321
- struct scsi_host_template * hostt = shost -> hostt ;
322
- struct scsi_host_cmd_pool * retval = NULL , * pool ;
323
- size_t cmd_size = sizeof (struct scsi_cmnd ) + hostt -> cmd_size ;
324
-
325
- /*
326
- * Select a command slab for this host and create it if not
327
- * yet existent.
328
- */
329
- mutex_lock (& host_cmd_pool_mutex );
330
- pool = scsi_find_host_cmd_pool (shost );
331
- if (!pool ) {
332
- pool = scsi_alloc_host_cmd_pool (shost );
333
- if (!pool )
334
- goto out ;
335
- }
336
-
337
- if (!pool -> users ) {
338
- pool -> cmd_slab = kmem_cache_create (pool -> cmd_name , cmd_size , 0 ,
339
- SLAB_HWCACHE_ALIGN , NULL );
340
- if (!pool -> cmd_slab )
341
- goto out_free_pool ;
342
- }
343
-
344
- pool -> users ++ ;
345
- retval = pool ;
346
- out :
347
- mutex_unlock (& host_cmd_pool_mutex );
348
- return retval ;
349
-
350
- out_free_pool :
351
- if (hostt -> cmd_size ) {
352
- scsi_free_host_cmd_pool (pool );
353
- hostt -> cmd_pool = NULL ;
354
- }
355
- goto out ;
356
- }
357
-
358
- static void scsi_put_host_cmd_pool (struct Scsi_Host * shost )
359
- {
360
- struct scsi_host_template * hostt = shost -> hostt ;
361
- struct scsi_host_cmd_pool * pool ;
362
-
363
- mutex_lock (& host_cmd_pool_mutex );
364
- pool = scsi_find_host_cmd_pool (shost );
365
-
366
- /*
367
- * This may happen if a driver has a mismatched get and put
368
- * of the command pool; the driver should be implicated in
369
- * the stack trace
370
- */
371
- BUG_ON (pool -> users == 0 );
372
-
373
- if (!-- pool -> users ) {
374
- kmem_cache_destroy (pool -> cmd_slab );
375
- if (hostt -> cmd_size ) {
376
- scsi_free_host_cmd_pool (pool );
377
- hostt -> cmd_pool = NULL ;
378
- }
379
- }
380
- mutex_unlock (& host_cmd_pool_mutex );
381
- }
382
-
383
- /**
384
- * scsi_setup_command_freelist - Setup the command freelist for a scsi host.
385
- * @shost: host to allocate the freelist for.
386
- *
387
- * Description: The command freelist protects against system-wide out of memory
388
- * deadlock by preallocating one SCSI command structure for each host, so the
389
- * system can always write to a swap file on a device associated with that host.
390
- *
391
- * Returns: Nothing.
392
- */
393
- int scsi_setup_command_freelist (struct Scsi_Host * shost )
394
- {
395
- struct scsi_cmnd * cmd ;
396
-
397
- spin_lock_init (& shost -> free_list_lock );
398
- INIT_LIST_HEAD (& shost -> free_list );
399
-
400
- shost -> cmd_pool = scsi_get_host_cmd_pool (shost );
401
- if (!shost -> cmd_pool )
402
- return - ENOMEM ;
403
-
404
- /*
405
- * Get one backup command for this host.
406
- */
407
- cmd = scsi_host_alloc_command (shost , GFP_KERNEL );
408
- if (!cmd ) {
409
- scsi_put_host_cmd_pool (shost );
410
- shost -> cmd_pool = NULL ;
411
- return - ENOMEM ;
412
- }
413
- list_add (& cmd -> list , & shost -> free_list );
414
- return 0 ;
415
- }
416
-
417
- /**
418
- * scsi_destroy_command_freelist - Release the command freelist for a scsi host.
419
- * @shost: host whose freelist is going to be destroyed
420
- */
421
- void scsi_destroy_command_freelist (struct Scsi_Host * shost )
422
- {
423
- /*
424
- * If cmd_pool is NULL the free list was not initialized, so
425
- * do not attempt to release resources.
426
- */
427
- if (!shost -> cmd_pool )
428
- return ;
429
-
430
- while (!list_empty (& shost -> free_list )) {
431
- struct scsi_cmnd * cmd ;
432
-
433
- cmd = list_entry (shost -> free_list .next , struct scsi_cmnd , list );
434
- list_del_init (& cmd -> list );
435
- scsi_host_free_command (shost , cmd );
436
- }
437
- shost -> cmd_pool = NULL ;
438
- scsi_put_host_cmd_pool (shost );
439
120
}
440
121
441
122
#ifdef CONFIG_SCSI_LOGGING
0 commit comments