1 /*- 2 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 3 * Copyright 2015 Toomas Soome <tsoome@me.com> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 #include <sys/param.h> 30 __FBSDID("$FreeBSD$"); 31 32 /* 33 * Simple hashed block cache 34 */ 35 36 #include <sys/stdint.h> 37 38 #include <stand.h> 39 #include <string.h> 40 #include <strings.h> 41 42 #include "bootstrap.h" 43 44 /* #define BCACHE_DEBUG */ 45 46 #ifdef BCACHE_DEBUG 47 # define DPRINTF(fmt, args...) printf("%s: " fmt "\n" , __func__ , ## args) 48 #else 49 # define DPRINTF(fmt, args...) ((void)0) 50 #endif 51 52 struct bcachectl 53 { 54 daddr_t bc_blkno; 55 int bc_count; 56 }; 57 58 /* 59 * bcache per device node. cache is allocated on device first open and freed 60 * on last close, to save memory. The issue there is the size; biosdisk 61 * supports up to 31 (0x1f) devices. Classic setup would use single disk 62 * to boot from, but this has changed with zfs. 63 */ 64 struct bcache { 65 struct bcachectl *bcache_ctl; 66 caddr_t bcache_data; 67 size_t bcache_nblks; 68 size_t ra; 69 daddr_t bcache_nextblkno; 70 size_t ralen; 71 }; 72 73 static u_int bcache_total_nblks; /* set by bcache_init */ 74 static u_int bcache_blksize; /* set by bcache_init */ 75 static u_int bcache_numdev; /* set by bcache_add_dev */ 76 /* statistics */ 77 static u_int bcache_units; /* number of devices with cache */ 78 static u_int bcache_unit_nblks; /* nblocks per unit */ 79 static u_int bcache_hits; 80 static u_int bcache_misses; 81 static u_int bcache_ops; 82 static u_int bcache_bypasses; 83 static u_int bcache_bcount; 84 static u_int bcache_rablks; 85 86 #define BHASH(bc, blkno) ((blkno) & ((bc)->bcache_nblks - 1)) 87 #define BCACHE_LOOKUP(bc, blkno) \ 88 ((bc)->bcache_ctl[BHASH((bc), (blkno))].bc_blkno != (blkno)) 89 #define BCACHE_READAHEAD 512 90 #define BCACHE_MINREADAHEAD 32 91 #define BCACHE_MAXIOWRA 512 92 93 static void bcache_invalidate(struct bcache *bc, daddr_t blkno); 94 static void bcache_insert(struct bcache *bc, daddr_t blkno); 95 static void bcache_free_instance(struct bcache *bc); 96 97 /* 98 * Initialise the cache for (nblks) of (bsize). 99 */ 100 void 101 bcache_init(size_t nblks, size_t bsize) 102 { 103 /* set up control data */ 104 bcache_total_nblks = nblks; 105 bcache_blksize = bsize; 106 } 107 108 /* 109 * add number of devices to bcache. we have to divide cache space 110 * between the devices, so bcache_add_dev() can be used to set up the 111 * number. The issue is, we need to get the number before actual allocations. 112 * bcache_add_dev() is supposed to be called from device init() call, so the 113 * assumption is, devsw dv_init is called for plain devices first, and 114 * for zfs, last. 115 */ 116 void 117 bcache_add_dev(int devices) 118 { 119 bcache_numdev += devices; 120 } 121 122 void * 123 bcache_allocate(void) 124 { 125 u_int i; 126 struct bcache *bc = malloc(sizeof (struct bcache)); 127 int disks = bcache_numdev; 128 129 if (disks == 0) 130 disks = 1; /* safe guard */ 131 132 if (bc == NULL) { 133 errno = ENOMEM; 134 return (bc); 135 } 136 137 /* 138 * the bcache block count must be power of 2 for hash function 139 */ 140 i = fls(disks) - 1; /* highbit - 1 */ 141 if (disks > (1 << i)) /* next power of 2 */ 142 i++; 143 144 bc->bcache_nblks = bcache_total_nblks >> i; 145 bcache_unit_nblks = bc->bcache_nblks; 146 bc->bcache_data = malloc(bc->bcache_nblks * bcache_blksize); 147 if (bc->bcache_data == NULL) { 148 /* dont error out yet. fall back to 32 blocks and try again */ 149 bc->bcache_nblks = 32; 150 bc->bcache_data = malloc(bc->bcache_nblks * bcache_blksize + 151 sizeof(uint32_t)); 152 } 153 154 bc->bcache_ctl = malloc(bc->bcache_nblks * sizeof(struct bcachectl)); 155 156 if ((bc->bcache_data == NULL) || (bc->bcache_ctl == NULL)) { 157 bcache_free_instance(bc); 158 errno = ENOMEM; 159 return (NULL); 160 } 161 162 /* Flush the cache */ 163 for (i = 0; i < bc->bcache_nblks; i++) { 164 bc->bcache_ctl[i].bc_count = -1; 165 bc->bcache_ctl[i].bc_blkno = -1; 166 } 167 bcache_units++; 168 bc->ra = BCACHE_READAHEAD; /* optimistic read ahead */ 169 bc->bcache_nextblkno = -1; 170 return (bc); 171 } 172 173 void 174 bcache_free(void *cache) 175 { 176 struct bcache *bc = cache; 177 178 if (bc == NULL) 179 return; 180 181 bcache_free_instance(bc); 182 bcache_units--; 183 } 184 185 /* 186 * Handle a write request; write directly to the disk, and populate the 187 * cache with the new values. 188 */ 189 static int 190 write_strategy(void *devdata, int rw, daddr_t blk, size_t size, 191 char *buf, size_t *rsize) 192 { 193 struct bcache_devdata *dd = (struct bcache_devdata *)devdata; 194 struct bcache *bc = dd->dv_cache; 195 daddr_t i, nblk; 196 197 nblk = size / bcache_blksize; 198 199 /* Invalidate the blocks being written */ 200 for (i = 0; i < nblk; i++) { 201 bcache_invalidate(bc, blk + i); 202 } 203 204 /* Write the blocks */ 205 return (dd->dv_strategy(dd->dv_devdata, rw, blk, size, buf, rsize)); 206 } 207 208 /* 209 * Handle a read request; fill in parts of the request that can 210 * be satisfied by the cache, use the supplied strategy routine to do 211 * device I/O and then use the I/O results to populate the cache. 212 */ 213 static int 214 read_strategy(void *devdata, int rw, daddr_t blk, size_t size, 215 char *buf, size_t *rsize) 216 { 217 struct bcache_devdata *dd = (struct bcache_devdata *)devdata; 218 struct bcache *bc = dd->dv_cache; 219 size_t i, nblk, p_size, r_size, complete, ra; 220 int result; 221 daddr_t p_blk; 222 caddr_t p_buf; 223 224 if (bc == NULL) { 225 errno = ENODEV; 226 return (-1); 227 } 228 229 if (rsize != NULL) 230 *rsize = 0; 231 232 nblk = size / bcache_blksize; 233 if (nblk == 0 && size != 0) 234 nblk++; 235 result = 0; 236 complete = 1; 237 238 /* Satisfy any cache hits up front, break on first miss */ 239 for (i = 0; i < nblk; i++) { 240 if (BCACHE_LOOKUP(bc, (daddr_t)(blk + i))) { 241 bcache_misses += (nblk - i); 242 complete = 0; 243 break; 244 } else { 245 bcache_hits++; 246 } 247 } 248 249 /* 250 * Adjust read-ahead size if appropriate. Subject to the requirement 251 * that bc->ra must stay in between MINREADAHEAD and READAHEAD, we 252 * increase it when we notice that readahead was useful and decrease 253 * it when we notice that readahead was not useful. 254 */ 255 if (complete || (i == bc->ralen && bc->ralen > 0)) { 256 if (bc->ra < BCACHE_READAHEAD) 257 bc->ra <<= 1; /* increase read ahead */ 258 } else { 259 if (nblk - i > BCACHE_MINREADAHEAD && bc->ralen > 0 && 260 bc->ra > BCACHE_MINREADAHEAD) 261 bc->ra >>= 1; /* reduce read ahead */ 262 } 263 264 /* Adjust our "unconsumed readahead" value. */ 265 if (blk == bc->bcache_nextblkno) { 266 if (nblk > bc->ralen) 267 bc->ralen = 0; 268 else 269 bc->ralen -= nblk; 270 } 271 272 if (complete) { /* whole set was in cache, return it */ 273 bcopy(bc->bcache_data + (bcache_blksize * BHASH(bc, blk)), buf, size); 274 goto done; 275 } 276 277 /* 278 * Fill in any misses. From check we have i pointing to first missing 279 * block, read in all remaining blocks + readahead. 280 * We have space at least for nblk - i before bcache wraps. 281 */ 282 p_blk = blk + i; 283 p_buf = bc->bcache_data + (bcache_blksize * BHASH(bc, p_blk)); 284 r_size = bc->bcache_nblks - BHASH(bc, p_blk); /* remaining blocks */ 285 286 p_size = MIN(r_size, nblk - i); /* read at least those blocks */ 287 288 /* 289 * The read ahead size setup. 290 * While the read ahead can save us IO, it also can complicate things: 291 * 1. We do not want to read ahead by wrapping around the 292 * bcache end - this would complicate the cache management. 293 * 2. We are using bc->ra as dynamic hint for read ahead size, 294 * detected cache hits will increase the read-ahead block count, and 295 * misses will decrease, see the code above. 296 * 3. The bcache is sized by 512B blocks, however, the underlying device 297 * may have a larger sector size, and we should perform the IO by 298 * taking into account these larger sector sizes. We could solve this by 299 * passing the sector size to bcache_allocate(), or by using ioctl(), but 300 * in this version we are using the constant, 16 blocks, and are rounding 301 * read ahead block count down to multiple of 16. 302 * Using the constant has two reasons, we are not entirely sure if the 303 * BIOS disk interface is providing the correct value for sector size. 304 * And secondly, this way we get the most conservative setup for the ra. 305 * 306 * The selection of multiple of 16 blocks (8KB) is quite arbitrary, however, 307 * we want to cover CDs (2K) and 4K disks. 308 * bcache_allocate() will always fall back to a minimum of 32 blocks. 309 * Our choice of 16 read ahead blocks will always fit inside the bcache. 310 */ 311 312 if ((rw & F_NORA) == F_NORA) 313 ra = 0; 314 else 315 ra = bc->bcache_nblks - BHASH(bc, p_blk + p_size); 316 317 /* 318 * Only trigger read-ahead if we detect two blocks being read 319 * sequentially. 320 */ 321 if ((bc->bcache_nextblkno != blk) && ra != 0) { 322 ra = 0; 323 } 324 325 if (ra != 0 && ra != bc->bcache_nblks) { /* do we have RA space? */ 326 ra = MIN(bc->ra, ra - 1); 327 ra = rounddown(ra, 16); /* multiple of 16 blocks */ 328 if (ra + p_size > BCACHE_MAXIOWRA) 329 ra = BCACHE_MAXIOWRA - p_size; 330 bc->ralen = ra; 331 p_size += ra; 332 } else { 333 bc->ralen = 0; 334 } 335 336 /* invalidate bcache */ 337 for (i = 0; i < p_size; i++) { 338 bcache_invalidate(bc, p_blk + i); 339 } 340 341 r_size = 0; 342 /* 343 * with read-ahead, it may happen we are attempting to read past 344 * disk end, as bcache has no information about disk size. 345 * in such case we should get partial read if some blocks can be 346 * read or error, if no blocks can be read. 347 * in either case we should return the data in bcache and only 348 * return error if there is no data. 349 */ 350 rw &= F_MASK; 351 result = dd->dv_strategy(dd->dv_devdata, rw, p_blk, 352 p_size * bcache_blksize, p_buf, &r_size); 353 354 r_size /= bcache_blksize; 355 for (i = 0; i < r_size; i++) 356 bcache_insert(bc, p_blk + i); 357 358 /* update ra statistics */ 359 if (r_size != 0) { 360 if (r_size < p_size) 361 bcache_rablks += (p_size - r_size); 362 else 363 bcache_rablks += ra; 364 } 365 366 /* check how much data can we copy */ 367 for (i = 0; i < nblk; i++) { 368 if (BCACHE_LOOKUP(bc, (daddr_t)(blk + i))) 369 break; 370 } 371 372 if (size > i * bcache_blksize) 373 size = i * bcache_blksize; 374 375 if (size != 0) { 376 bcopy(bc->bcache_data + (bcache_blksize * BHASH(bc, blk)), buf, size); 377 result = 0; 378 } 379 380 done: 381 if (result == 0) { 382 if (rsize != NULL) 383 *rsize = size; 384 bc->bcache_nextblkno = blk + (size / DEV_BSIZE); 385 } 386 return(result); 387 } 388 389 /* 390 * Requests larger than 1/2 cache size will be bypassed and go 391 * directly to the disk. XXX tune this. 392 */ 393 int 394 bcache_strategy(void *devdata, int rw, daddr_t blk, size_t size, 395 char *buf, size_t *rsize) 396 { 397 struct bcache_devdata *dd = (struct bcache_devdata *)devdata; 398 struct bcache *bc = dd->dv_cache; 399 u_int bcache_nblks = 0; 400 int nblk, cblk, ret; 401 size_t csize, isize, total; 402 403 bcache_ops++; 404 405 if (bc != NULL) 406 bcache_nblks = bc->bcache_nblks; 407 408 /* bypass large requests, or when the cache is inactive */ 409 if (bc == NULL || 410 ((size * 2 / bcache_blksize) > bcache_nblks)) { 411 DPRINTF("bypass %zu from %jd", size / bcache_blksize, blk); 412 bcache_bypasses++; 413 rw &= F_MASK; 414 return (dd->dv_strategy(dd->dv_devdata, rw, blk, size, buf, rsize)); 415 } 416 417 switch (rw & F_MASK) { 418 case F_READ: 419 nblk = size / bcache_blksize; 420 if (size != 0 && nblk == 0) 421 nblk++; /* read at least one block */ 422 423 ret = 0; 424 total = 0; 425 while(size) { 426 cblk = bcache_nblks - BHASH(bc, blk); /* # of blocks left */ 427 cblk = MIN(cblk, nblk); 428 429 if (size <= bcache_blksize) 430 csize = size; 431 else 432 csize = cblk * bcache_blksize; 433 434 ret = read_strategy(devdata, rw, blk, csize, buf+total, &isize); 435 436 /* 437 * we may have error from read ahead, if we have read some data 438 * return partial read. 439 */ 440 if (ret != 0 || isize == 0) { 441 if (total != 0) 442 ret = 0; 443 break; 444 } 445 blk += isize / bcache_blksize; 446 total += isize; 447 size -= isize; 448 nblk = size / bcache_blksize; 449 } 450 451 if (rsize) 452 *rsize = total; 453 454 return (ret); 455 case F_WRITE: 456 return write_strategy(devdata, F_WRITE, blk, size, buf, rsize); 457 } 458 return -1; 459 } 460 461 /* 462 * Free allocated bcache instance 463 */ 464 static void 465 bcache_free_instance(struct bcache *bc) 466 { 467 if (bc != NULL) { 468 free(bc->bcache_ctl); 469 free(bc->bcache_data); 470 free(bc); 471 } 472 } 473 474 /* 475 * Insert a block into the cache. 476 */ 477 static void 478 bcache_insert(struct bcache *bc, daddr_t blkno) 479 { 480 u_int cand; 481 482 cand = BHASH(bc, blkno); 483 484 DPRINTF("insert blk %jd -> %u # %d", blkno, cand, bcache_bcount); 485 bc->bcache_ctl[cand].bc_blkno = blkno; 486 bc->bcache_ctl[cand].bc_count = bcache_bcount++; 487 } 488 489 /* 490 * Invalidate a block from the cache. 491 */ 492 static void 493 bcache_invalidate(struct bcache *bc, daddr_t blkno) 494 { 495 u_int i; 496 497 i = BHASH(bc, blkno); 498 if (bc->bcache_ctl[i].bc_blkno == blkno) { 499 bc->bcache_ctl[i].bc_count = -1; 500 bc->bcache_ctl[i].bc_blkno = -1; 501 DPRINTF("invalidate blk %ju", blkno); 502 } 503 } 504 505 #ifndef BOOT2 506 COMMAND_SET(bcachestat, "bcachestat", "get disk block cache stats", command_bcache); 507 508 static int 509 command_bcache(int argc, char *argv[] __unused) 510 { 511 if (argc != 1) { 512 command_errmsg = "wrong number of arguments"; 513 return(CMD_ERROR); 514 } 515 516 printf("\ncache blocks: %u\n", bcache_total_nblks); 517 printf("cache blocksz: %u\n", bcache_blksize); 518 printf("cache readahead: %u\n", bcache_rablks); 519 printf("unit cache blocks: %u\n", bcache_unit_nblks); 520 printf("cached units: %u\n", bcache_units); 521 printf("%u ops %d bypasses %u hits %u misses\n", bcache_ops, 522 bcache_bypasses, bcache_hits, bcache_misses); 523 return(CMD_OK); 524 } 525 #endif 526