Deleted Added
full compact
ctl_backend_block.c (261538) ctl_backend_block.c (264020)
1/*-
2 * Copyright (c) 2003 Silicon Graphics International Corp.
3 * Copyright (c) 2009-2011 Spectra Logic Corporation
4 * Copyright (c) 2012 The FreeBSD Foundation
5 * All rights reserved.
6 *
7 * Portions of this software were developed by Edward Tomasz Napierala
8 * under sponsorship from the FreeBSD Foundation.

--- 26 unchanged lines hidden (view full) ---

35 * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_backend_block.c#5 $
36 */
37/*
38 * CAM Target Layer driver backend for block devices.
39 *
40 * Author: Ken Merry <ken@FreeBSD.org>
41 */
42#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2003 Silicon Graphics International Corp.
3 * Copyright (c) 2009-2011 Spectra Logic Corporation
4 * Copyright (c) 2012 The FreeBSD Foundation
5 * All rights reserved.
6 *
7 * Portions of this software were developed by Edward Tomasz Napierala
8 * under sponsorship from the FreeBSD Foundation.

--- 26 unchanged lines hidden (view full) ---

35 * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_backend_block.c#5 $
36 */
37/*
38 * CAM Target Layer driver backend for block devices.
39 *
40 * Author: Ken Merry <ken@FreeBSD.org>
41 */
42#include <sys/cdefs.h>
43__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_backend_block.c 261538 2014-02-06 03:54:58Z mav $");
43__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_backend_block.c 264020 2014-04-01 21:13:05Z trasz $");
44
45#include <sys/param.h>
46#include <sys/systm.h>
47#include <sys/kernel.h>
48#include <sys/types.h>
49#include <sys/kthread.h>
50#include <sys/bio.h>
51#include <sys/fcntl.h>

--- 116 unchanged lines hidden (view full) ---

168 STAILQ_HEAD(, ctl_io_hdr) config_write_queue;
169 STAILQ_HEAD(, ctl_io_hdr) datamove_queue;
170};
171
172/*
173 * Overall softc structure for the block backend module.
174 */
175struct ctl_be_block_softc {
44
45#include <sys/param.h>
46#include <sys/systm.h>
47#include <sys/kernel.h>
48#include <sys/types.h>
49#include <sys/kthread.h>
50#include <sys/bio.h>
51#include <sys/fcntl.h>

--- 116 unchanged lines hidden (view full) ---

168 STAILQ_HEAD(, ctl_io_hdr) config_write_queue;
169 STAILQ_HEAD(, ctl_io_hdr) datamove_queue;
170};
171
172/*
173 * Overall softc structure for the block backend module.
174 */
175struct ctl_be_block_softc {
176 STAILQ_HEAD(, ctl_be_block_io) beio_free_queue;
177 struct mtx lock;
176 struct mtx lock;
178 int prealloc_beio;
179 int num_disks;
180 STAILQ_HEAD(, ctl_block_disk) disk_list;
181 int num_luns;
182 STAILQ_HEAD(, ctl_be_block_lun) lun_list;
183};
184
185static struct ctl_be_block_softc backend_block_softc;
186

--- 13 unchanged lines hidden (view full) ---

200 int num_errors;
201 struct bintime ds_t0;
202 devstat_tag_type ds_tag_type;
203 devstat_trans_flags ds_trans_type;
204 uint64_t io_len;
205 uint64_t io_offset;
206 struct ctl_be_block_softc *softc;
207 struct ctl_be_block_lun *lun;
177 int num_disks;
178 STAILQ_HEAD(, ctl_block_disk) disk_list;
179 int num_luns;
180 STAILQ_HEAD(, ctl_be_block_lun) lun_list;
181};
182
183static struct ctl_be_block_softc backend_block_softc;
184

--- 13 unchanged lines hidden (view full) ---

198 int num_errors;
199 struct bintime ds_t0;
200 devstat_tag_type ds_tag_type;
201 devstat_trans_flags ds_trans_type;
202 uint64_t io_len;
203 uint64_t io_offset;
204 struct ctl_be_block_softc *softc;
205 struct ctl_be_block_lun *lun;
208 STAILQ_ENTRY(ctl_be_block_io) links;
209};
210
211static int cbb_num_threads = 14;
212TUNABLE_INT("kern.cam.ctl.block.num_threads", &cbb_num_threads);
213SYSCTL_NODE(_kern_cam_ctl, OID_AUTO, block, CTLFLAG_RD, 0,
214 "CAM Target Layer Block Backend");
215SYSCTL_INT(_kern_cam_ctl_block, OID_AUTO, num_threads, CTLFLAG_RW,
216 &cbb_num_threads, 0, "Number of threads per backing file");
217
218static struct ctl_be_block_io *ctl_alloc_beio(struct ctl_be_block_softc *softc);
219static void ctl_free_beio(struct ctl_be_block_io *beio);
206};
207
208static int cbb_num_threads = 14;
209TUNABLE_INT("kern.cam.ctl.block.num_threads", &cbb_num_threads);
210SYSCTL_NODE(_kern_cam_ctl, OID_AUTO, block, CTLFLAG_RD, 0,
211 "CAM Target Layer Block Backend");
212SYSCTL_INT(_kern_cam_ctl_block, OID_AUTO, num_threads, CTLFLAG_RW,
213 &cbb_num_threads, 0, "Number of threads per backing file");
214
215static struct ctl_be_block_io *ctl_alloc_beio(struct ctl_be_block_softc *softc);
216static void ctl_free_beio(struct ctl_be_block_io *beio);
220static int ctl_grow_beio(struct ctl_be_block_softc *softc, int count);
221#if 0
222static void ctl_shrink_beio(struct ctl_be_block_softc *softc);
223#endif
224static void ctl_complete_beio(struct ctl_be_block_io *beio);
225static int ctl_be_block_move_done(union ctl_io *io);
226static void ctl_be_block_biodone(struct bio *bio);
227static void ctl_be_block_flush_file(struct ctl_be_block_lun *be_lun,
228 struct ctl_be_block_io *beio);
229static void ctl_be_block_dispatch_file(struct ctl_be_block_lun *be_lun,
230 struct ctl_be_block_io *beio);
231static void ctl_be_block_flush_dev(struct ctl_be_block_lun *be_lun,

--- 45 unchanged lines hidden (view full) ---

277 .config_write = ctl_be_block_config_write,
278 .ioctl = ctl_be_block_ioctl,
279 .lun_info = ctl_be_block_lun_info
280};
281
282MALLOC_DEFINE(M_CTLBLK, "ctlblk", "Memory used for CTL block backend");
283CTL_BACKEND_DECLARE(cbb, ctl_be_block_driver);
284
217static void ctl_complete_beio(struct ctl_be_block_io *beio);
218static int ctl_be_block_move_done(union ctl_io *io);
219static void ctl_be_block_biodone(struct bio *bio);
220static void ctl_be_block_flush_file(struct ctl_be_block_lun *be_lun,
221 struct ctl_be_block_io *beio);
222static void ctl_be_block_dispatch_file(struct ctl_be_block_lun *be_lun,
223 struct ctl_be_block_io *beio);
224static void ctl_be_block_flush_dev(struct ctl_be_block_lun *be_lun,

--- 45 unchanged lines hidden (view full) ---

270 .config_write = ctl_be_block_config_write,
271 .ioctl = ctl_be_block_ioctl,
272 .lun_info = ctl_be_block_lun_info
273};
274
275MALLOC_DEFINE(M_CTLBLK, "ctlblk", "Memory used for CTL block backend");
276CTL_BACKEND_DECLARE(cbb, ctl_be_block_driver);
277
278static uma_zone_t beio_zone;
279
285static struct ctl_be_block_io *
286ctl_alloc_beio(struct ctl_be_block_softc *softc)
287{
288 struct ctl_be_block_io *beio;
280static struct ctl_be_block_io *
281ctl_alloc_beio(struct ctl_be_block_softc *softc)
282{
283 struct ctl_be_block_io *beio;
289 int count;
290
284
291 mtx_lock(&softc->lock);
292
293 beio = STAILQ_FIRST(&softc->beio_free_queue);
294 if (beio != NULL) {
295 STAILQ_REMOVE(&softc->beio_free_queue, beio,
296 ctl_be_block_io, links);
297 }
298 mtx_unlock(&softc->lock);
299
300 if (beio != NULL) {
301 bzero(beio, sizeof(*beio));
302 beio->softc = softc;
303 return (beio);
304 }
305
306 for (;;) {
307
308 count = ctl_grow_beio(softc, /*count*/ 10);
309
310 /*
311 * This shouldn't be possible, since ctl_grow_beio() uses a
312 * blocking malloc.
313 */
314 if (count == 0)
315 return (NULL);
316
317 /*
318 * Since we have to drop the lock when we're allocating beio
319 * structures, it's possible someone else can come along and
320 * allocate the beio's we've just allocated.
321 */
322 mtx_lock(&softc->lock);
323 beio = STAILQ_FIRST(&softc->beio_free_queue);
324 if (beio != NULL) {
325 STAILQ_REMOVE(&softc->beio_free_queue, beio,
326 ctl_be_block_io, links);
327 }
328 mtx_unlock(&softc->lock);
329
330 if (beio != NULL) {
331 bzero(beio, sizeof(*beio));
332 beio->softc = softc;
333 break;
334 }
335 }
285 beio = uma_zalloc(beio_zone, M_WAITOK | M_ZERO);
286 beio->softc = softc;
336 return (beio);
337}
338
339static void
340ctl_free_beio(struct ctl_be_block_io *beio)
341{
287 return (beio);
288}
289
290static void
291ctl_free_beio(struct ctl_be_block_io *beio)
292{
342 struct ctl_be_block_softc *softc;
343 int duplicate_free;
344 int i;
345
293 int duplicate_free;
294 int i;
295
346 softc = beio->softc;
347 duplicate_free = 0;
348
349 for (i = 0; i < beio->num_segs; i++) {
350 if (beio->sg_segs[i].addr == NULL)
351 duplicate_free++;
352
353 uma_zfree(beio->lun->lun_zone, beio->sg_segs[i].addr);
354 beio->sg_segs[i].addr = NULL;
355 }
356
357 if (duplicate_free > 0) {
358 printf("%s: %d duplicate frees out of %d segments\n", __func__,
359 duplicate_free, beio->num_segs);
360 }
296 duplicate_free = 0;
297
298 for (i = 0; i < beio->num_segs; i++) {
299 if (beio->sg_segs[i].addr == NULL)
300 duplicate_free++;
301
302 uma_zfree(beio->lun->lun_zone, beio->sg_segs[i].addr);
303 beio->sg_segs[i].addr = NULL;
304 }
305
306 if (duplicate_free > 0) {
307 printf("%s: %d duplicate frees out of %d segments\n", __func__,
308 duplicate_free, beio->num_segs);
309 }
361 mtx_lock(&softc->lock);
362 STAILQ_INSERT_TAIL(&softc->beio_free_queue, beio, links);
363 mtx_unlock(&softc->lock);
364}
365
310
366static int
367ctl_grow_beio(struct ctl_be_block_softc *softc, int count)
368{
369 int i;
370
371 for (i = 0; i < count; i++) {
372 struct ctl_be_block_io *beio;
373
374 beio = (struct ctl_be_block_io *)malloc(sizeof(*beio),
375 M_CTLBLK,
376 M_WAITOK | M_ZERO);
377 beio->softc = softc;
378 mtx_lock(&softc->lock);
379 STAILQ_INSERT_TAIL(&softc->beio_free_queue, beio, links);
380 mtx_unlock(&softc->lock);
381 }
382
383 return (i);
311 uma_zfree(beio_zone, beio);
384}
385
312}
313
386#if 0
387static void
314static void
388ctl_shrink_beio(struct ctl_be_block_softc *softc)
389{
390 struct ctl_be_block_io *beio, *beio_tmp;
391
392 mtx_lock(&softc->lock);
393 STAILQ_FOREACH_SAFE(beio, &softc->beio_free_queue, links, beio_tmp) {
394 STAILQ_REMOVE(&softc->beio_free_queue, beio,
395 ctl_be_block_io, links);
396 free(beio, M_CTLBLK);
397 }
398 mtx_unlock(&softc->lock);
399}
400#endif
401
402static void
403ctl_complete_beio(struct ctl_be_block_io *beio)
404{
405 union ctl_io *io;
406 int io_len;
407
408 io = beio->io;
409
410 if ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS)

--- 517 unchanged lines hidden (view full) ---

928{
929 struct ctl_be_block_io *beio;
930 struct ctl_be_block_softc *softc;
931
932 DPRINTF("entered\n");
933
934 softc = be_lun->softc;
935 beio = ctl_alloc_beio(softc);
315ctl_complete_beio(struct ctl_be_block_io *beio)
316{
317 union ctl_io *io;
318 int io_len;
319
320 io = beio->io;
321
322 if ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS)

--- 517 unchanged lines hidden (view full) ---

840{
841 struct ctl_be_block_io *beio;
842 struct ctl_be_block_softc *softc;
843
844 DPRINTF("entered\n");
845
846 softc = be_lun->softc;
847 beio = ctl_alloc_beio(softc);
936 if (beio == NULL) {
937 /*
938 * This should not happen. ctl_alloc_beio() will call
939 * ctl_grow_beio() with a blocking malloc as needed.
940 * A malloc with M_WAITOK should not fail.
941 */
942 ctl_set_busy(&io->scsiio);
943 ctl_done(io);
944 return;
945 }
848 KASSERT(beio != NULL, ("ctl_alloc_beio() failed"));
946
947 beio->io = io;
948 beio->softc = softc;
949 beio->lun = be_lun;
950 io->io_hdr.ctl_private[CTL_PRIV_BACKEND].ptr = beio;
951
952 switch (io->scsiio.cdb[0]) {
953 case SYNCHRONIZE_CACHE:

--- 54 unchanged lines hidden (view full) ---

1008 /*field*/ 0,
1009 /*bit_valid*/ 0,
1010 /*bit*/ 0);
1011 ctl_done(io);
1012 return;
1013 }
1014
1015 beio = ctl_alloc_beio(softc);
849
850 beio->io = io;
851 beio->softc = softc;
852 beio->lun = be_lun;
853 io->io_hdr.ctl_private[CTL_PRIV_BACKEND].ptr = beio;
854
855 switch (io->scsiio.cdb[0]) {
856 case SYNCHRONIZE_CACHE:

--- 54 unchanged lines hidden (view full) ---

911 /*field*/ 0,
912 /*bit_valid*/ 0,
913 /*bit*/ 0);
914 ctl_done(io);
915 return;
916 }
917
918 beio = ctl_alloc_beio(softc);
1016 if (beio == NULL) {
1017 /*
1018 * This should not happen. ctl_alloc_beio() will call
1019 * ctl_grow_beio() with a blocking malloc as needed.
1020 * A malloc with M_WAITOK should not fail.
1021 */
1022 ctl_set_busy(&io->scsiio);
1023 ctl_done(io);
1024 return;
1025 }
919 KASSERT(beio != NULL, ("ctl_alloc_beio() failed"));
1026
1027 beio->io = io;
1028 beio->softc = softc;
1029 beio->lun = be_lun;
1030 io->io_hdr.ctl_private[CTL_PRIV_BACKEND].ptr = beio;
1031
1032 /*
1033 * If the I/O came down with an ordered or head of queue tag, set

--- 1303 unchanged lines hidden (view full) ---

2337{
2338 struct ctl_be_block_softc *softc;
2339 int retval;
2340
2341 softc = &backend_block_softc;
2342 retval = 0;
2343
2344 mtx_init(&softc->lock, "ctlblk", NULL, MTX_DEF);
920
921 beio->io = io;
922 beio->softc = softc;
923 beio->lun = be_lun;
924 io->io_hdr.ctl_private[CTL_PRIV_BACKEND].ptr = beio;
925
926 /*
927 * If the I/O came down with an ordered or head of queue tag, set

--- 1303 unchanged lines hidden (view full) ---

2231{
2232 struct ctl_be_block_softc *softc;
2233 int retval;
2234
2235 softc = &backend_block_softc;
2236 retval = 0;
2237
2238 mtx_init(&softc->lock, "ctlblk", NULL, MTX_DEF);
2345 STAILQ_INIT(&softc->beio_free_queue);
2239 beio_zone = uma_zcreate("beio", sizeof(struct ctl_be_block_io),
2240 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
2346 STAILQ_INIT(&softc->disk_list);
2347 STAILQ_INIT(&softc->lun_list);
2241 STAILQ_INIT(&softc->disk_list);
2242 STAILQ_INIT(&softc->lun_list);
2348 ctl_grow_beio(softc, 200);
2349
2350 return (retval);
2351}
2243
2244 return (retval);
2245}