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} |