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 }; 71 72 static u_int bcache_total_nblks; /* set by bcache_init */ 73 static u_int bcache_blksize; /* set by bcache_init */ 74 static u_int bcache_numdev; /* set by bcache_add_dev */ 75 /* statistics */ 76 static u_int bcache_units; /* number of devices with cache */ 77 static u_int bcache_unit_nblks; /* nblocks per unit */ 78 static u_int bcache_hits; 79 static u_int bcache_misses; 80 static u_int bcache_ops; 81 static u_int bcache_bypasses; 82 static u_int bcache_bcount; 83 static u_int bcache_rablks; 84 85 #define BHASH(bc, blkno) ((blkno) & ((bc)->bcache_nblks - 1)) 86 #define BCACHE_LOOKUP(bc, blkno) \ 87 ((bc)->bcache_ctl[BHASH((bc), (blkno))].bc_blkno != (blkno)) 88 #define BCACHE_READAHEAD 256 89 #define BCACHE_MINREADAHEAD 32 90 91 static void bcache_invalidate(struct bcache *bc, daddr_t blkno); 92 static void bcache_insert(struct bcache *bc, daddr_t blkno); 93 static void bcache_free_instance(struct bcache *bc); 94 95 /* 96 * Initialise the cache for (nblks) of (bsize). 97 */ 98 void 99 bcache_init(size_t nblks, size_t bsize) 100 { 101 /* set up control data */ 102 bcache_total_nblks = nblks; 103 bcache_blksize = bsize; 104 } 105 106 /* 107 * add number of devices to bcache. we have to divide cache space 108 * between the devices, so bcache_add_dev() can be used to set up the 109 * number. The issue is, we need to get the number before actual allocations. 110 * bcache_add_dev() is supposed to be called from device init() call, so the 111 * assumption is, devsw dv_init is called for plain devices first, and 112 * for zfs, last. 113 */ 114 void 115 bcache_add_dev(int devices) 116 { 117 bcache_numdev += devices; 118 } 119 120 void * 121 bcache_allocate(void) 122 { 123 u_int i; 124 struct bcache *bc = malloc(sizeof (struct bcache)); 125 int disks = bcache_numdev; 126 127 if (disks == 0) 128 disks = 1; /* safe guard */ 129 130 if (bc == NULL) { 131 errno = ENOMEM; 132 return (bc); 133 } 134 135 /* 136 * the bcache block count must be power of 2 for hash function 137 */ 138 i = fls(disks) - 1; /* highbit - 1 */ 139 if (disks > (1 << i)) /* next power of 2 */ 140 i++; 141 142 bc->bcache_nblks = bcache_total_nblks >> i; 143 bcache_unit_nblks = bc->bcache_nblks; 144 bc->bcache_data = malloc(bc->bcache_nblks * bcache_blksize); 145 if (bc->bcache_data == NULL) { 146 /* dont error out yet. fall back to 32 blocks and try again */ 147 bc->bcache_nblks = 32; 148 bc->bcache_data = malloc(bc->bcache_nblks * bcache_blksize + 149 sizeof(uint32_t)); 150 } 151 152 bc->bcache_ctl = malloc(bc->bcache_nblks * sizeof(struct bcachectl)); 153 154 if ((bc->bcache_data == NULL) || (bc->bcache_ctl == NULL)) { 155 bcache_free_instance(bc); 156 errno = ENOMEM; 157 return (NULL); 158 } 159 160 /* Flush the cache */ 161 for (i = 0; i < bc->bcache_nblks; i++) { 162 bc->bcache_ctl[i].bc_count = -1; 163 bc->bcache_ctl[i].bc_blkno = -1; 164 } 165 bcache_units++; 166 bc->ra = BCACHE_READAHEAD; /* optimistic read ahead */ 167 bc->bcache_nextblkno = -1; 168 return (bc); 169 } 170 171 void 172 bcache_free(void *cache) 173 { 174 struct bcache *bc = cache; 175 176 if (bc == NULL) 177 return; 178 179 bcache_free_instance(bc); 180 bcache_units--; 181 } 182 183 /* 184 * Handle a write request; write directly to the disk, and populate the 185 * cache with the new values. 186 */ 187 static int 188 write_strategy(void *devdata, int rw, daddr_t blk, size_t size, 189 char *buf, size_t *rsize) 190 { 191 struct bcache_devdata *dd = (struct bcache_devdata *)devdata; 192 struct bcache *bc = dd->dv_cache; 193 daddr_t i, nblk; 194 195 nblk = size / bcache_blksize; 196 197 /* Invalidate the blocks being written */ 198 for (i = 0; i < nblk; i++) { 199 bcache_invalidate(bc, blk + i); 200 } 201 202 /* Write the blocks */ 203 return (dd->dv_strategy(dd->dv_devdata, rw, blk, size, buf, rsize)); 204 } 205 206 /* 207 * Handle a read request; fill in parts of the request that can 208 * be satisfied by the cache, use the supplied strategy routine to do 209 * device I/O and then use the I/O results to populate the cache. 210 */ 211 static int 212 read_strategy(void *devdata, int rw, daddr_t blk, size_t size, 213 char *buf, size_t *rsize) 214 { 215 struct bcache_devdata *dd = (struct bcache_devdata *)devdata; 216 struct bcache *bc = dd->dv_cache; 217 size_t i, nblk, p_size, r_size, complete, ra; 218 int result; 219 daddr_t p_blk; 220 caddr_t p_buf; 221 222 if (bc == NULL) { 223 errno = ENODEV; 224 return (-1); 225 } 226 227 if (rsize != NULL) 228 *rsize = 0; 229 230 nblk = size / bcache_blksize; 231 if (nblk == 0 && size != 0) 232 nblk++; 233 result = 0; 234 complete = 1; 235 236 /* Satisfy any cache hits up front, break on first miss */ 237 for (i = 0; i < nblk; i++) { 238 if (BCACHE_LOOKUP(bc, (daddr_t)(blk + i))) { 239 bcache_misses += (nblk - i); 240 complete = 0; 241 if (nblk - i > BCACHE_MINREADAHEAD && bc->ra > BCACHE_MINREADAHEAD) 242 bc->ra >>= 1; /* reduce read ahead */ 243 break; 244 } else { 245 bcache_hits++; 246 } 247 } 248 249 if (complete) { /* whole set was in cache, return it */ 250 if (bc->ra < BCACHE_READAHEAD) 251 bc->ra <<= 1; /* increase read ahead */ 252 bcopy(bc->bcache_data + (bcache_blksize * BHASH(bc, blk)), buf, size); 253 goto done; 254 } 255 256 /* 257 * Fill in any misses. From check we have i pointing to first missing 258 * block, read in all remaining blocks + readahead. 259 * We have space at least for nblk - i before bcache wraps. 260 */ 261 p_blk = blk + i; 262 p_buf = bc->bcache_data + (bcache_blksize * BHASH(bc, p_blk)); 263 r_size = bc->bcache_nblks - BHASH(bc, p_blk); /* remaining blocks */ 264 265 p_size = MIN(r_size, nblk - i); /* read at least those blocks */ 266 267 /* 268 * The read ahead size setup. 269 * While the read ahead can save us IO, it also can complicate things: 270 * 1. We do not want to read ahead by wrapping around the 271 * bcache end - this would complicate the cache management. 272 * 2. We are using bc->ra as dynamic hint for read ahead size, 273 * detected cache hits will increase the read-ahead block count, and 274 * misses will decrease, see the code above. 275 * 3. The bcache is sized by 512B blocks, however, the underlying device 276 * may have a larger sector size, and we should perform the IO by 277 * taking into account these larger sector sizes. We could solve this by 278 * passing the sector size to bcache_allocate(), or by using ioctl(), but 279 * in this version we are using the constant, 16 blocks, and are rounding 280 * read ahead block count down to multiple of 16. 281 * Using the constant has two reasons, we are not entirely sure if the 282 * BIOS disk interface is providing the correct value for sector size. 283 * And secondly, this way we get the most conservative setup for the ra. 284 * 285 * The selection of multiple of 16 blocks (8KB) is quite arbitrary, however, 286 * we want to cover CDs (2K) and 4K disks. 287 * bcache_allocate() will always fall back to a minimum of 32 blocks. 288 * Our choice of 16 read ahead blocks will always fit inside the bcache. 289 */ 290 291 if ((rw & F_NORA) == F_NORA) 292 ra = 0; 293 else 294 ra = bc->bcache_nblks - BHASH(bc, p_blk + p_size); 295 296 /* 297 * Only trigger read-ahead if we detect two blocks being read 298 * sequentially. 299 */ 300 if ((bc->bcache_nextblkno != blk) && ra != 0) { 301 ra = 0; 302 } 303 304 if (ra != 0 && ra != bc->bcache_nblks) { /* do we have RA space? */ 305 ra = MIN(bc->ra, ra - 1); 306 ra = rounddown(ra, 16); /* multiple of 16 blocks */ 307 p_size += ra; 308 } 309 310 /* invalidate bcache */ 311 for (i = 0; i < p_size; i++) { 312 bcache_invalidate(bc, p_blk + i); 313 } 314 315 r_size = 0; 316 /* 317 * with read-ahead, it may happen we are attempting to read past 318 * disk end, as bcache has no information about disk size. 319 * in such case we should get partial read if some blocks can be 320 * read or error, if no blocks can be read. 321 * in either case we should return the data in bcache and only 322 * return error if there is no data. 323 */ 324 rw &= F_MASK; 325 result = dd->dv_strategy(dd->dv_devdata, rw, p_blk, 326 p_size * bcache_blksize, p_buf, &r_size); 327 328 r_size /= bcache_blksize; 329 for (i = 0; i < r_size; i++) 330 bcache_insert(bc, p_blk + i); 331 332 /* update ra statistics */ 333 if (r_size != 0) { 334 if (r_size < p_size) 335 bcache_rablks += (p_size - r_size); 336 else 337 bcache_rablks += ra; 338 } 339 340 /* check how much data can we copy */ 341 for (i = 0; i < nblk; i++) { 342 if (BCACHE_LOOKUP(bc, (daddr_t)(blk + i))) 343 break; 344 } 345 346 if (size > i * bcache_blksize) 347 size = i * bcache_blksize; 348 349 if (size != 0) { 350 bcopy(bc->bcache_data + (bcache_blksize * BHASH(bc, blk)), buf, size); 351 result = 0; 352 } 353 354 done: 355 if (result == 0) { 356 if (rsize != NULL) 357 *rsize = size; 358 bc->bcache_nextblkno = blk + (size / DEV_BSIZE); 359 } 360 return(result); 361 } 362 363 /* 364 * Requests larger than 1/2 cache size will be bypassed and go 365 * directly to the disk. XXX tune this. 366 */ 367 int 368 bcache_strategy(void *devdata, int rw, daddr_t blk, size_t size, 369 char *buf, size_t *rsize) 370 { 371 struct bcache_devdata *dd = (struct bcache_devdata *)devdata; 372 struct bcache *bc = dd->dv_cache; 373 u_int bcache_nblks = 0; 374 int nblk, cblk, ret; 375 size_t csize, isize, total; 376 377 bcache_ops++; 378 379 if (bc != NULL) 380 bcache_nblks = bc->bcache_nblks; 381 382 /* bypass large requests, or when the cache is inactive */ 383 if (bc == NULL || 384 ((size * 2 / bcache_blksize) > bcache_nblks)) { 385 DPRINTF("bypass %zu from %qu", size / bcache_blksize, blk); 386 bcache_bypasses++; 387 rw &= F_MASK; 388 return (dd->dv_strategy(dd->dv_devdata, rw, blk, size, buf, rsize)); 389 } 390 391 switch (rw & F_MASK) { 392 case F_READ: 393 nblk = size / bcache_blksize; 394 if (size != 0 && nblk == 0) 395 nblk++; /* read at least one block */ 396 397 ret = 0; 398 total = 0; 399 while(size) { 400 cblk = bcache_nblks - BHASH(bc, blk); /* # of blocks left */ 401 cblk = MIN(cblk, nblk); 402 403 if (size <= bcache_blksize) 404 csize = size; 405 else 406 csize = cblk * bcache_blksize; 407 408 ret = read_strategy(devdata, rw, blk, csize, buf+total, &isize); 409 410 /* 411 * we may have error from read ahead, if we have read some data 412 * return partial read. 413 */ 414 if (ret != 0 || isize == 0) { 415 if (total != 0) 416 ret = 0; 417 break; 418 } 419 blk += isize / bcache_blksize; 420 total += isize; 421 size -= isize; 422 nblk = size / bcache_blksize; 423 } 424 425 if (rsize) 426 *rsize = total; 427 428 return (ret); 429 case F_WRITE: 430 return write_strategy(devdata, F_WRITE, blk, size, buf, rsize); 431 } 432 return -1; 433 } 434 435 /* 436 * Free allocated bcache instance 437 */ 438 static void 439 bcache_free_instance(struct bcache *bc) 440 { 441 if (bc != NULL) { 442 free(bc->bcache_ctl); 443 free(bc->bcache_data); 444 free(bc); 445 } 446 } 447 448 /* 449 * Insert a block into the cache. 450 */ 451 static void 452 bcache_insert(struct bcache *bc, daddr_t blkno) 453 { 454 u_int cand; 455 456 cand = BHASH(bc, blkno); 457 458 DPRINTF("insert blk %llu -> %u # %d", blkno, cand, bcache_bcount); 459 bc->bcache_ctl[cand].bc_blkno = blkno; 460 bc->bcache_ctl[cand].bc_count = bcache_bcount++; 461 } 462 463 /* 464 * Invalidate a block from the cache. 465 */ 466 static void 467 bcache_invalidate(struct bcache *bc, daddr_t blkno) 468 { 469 u_int i; 470 471 i = BHASH(bc, blkno); 472 if (bc->bcache_ctl[i].bc_blkno == blkno) { 473 bc->bcache_ctl[i].bc_count = -1; 474 bc->bcache_ctl[i].bc_blkno = -1; 475 DPRINTF("invalidate blk %llu", blkno); 476 } 477 } 478 479 #ifndef BOOT2 480 COMMAND_SET(bcachestat, "bcachestat", "get disk block cache stats", command_bcache); 481 482 static int 483 command_bcache(int argc, char *argv[] __unused) 484 { 485 if (argc != 1) { 486 command_errmsg = "wrong number of arguments"; 487 return(CMD_ERROR); 488 } 489 490 printf("\ncache blocks: %u\n", bcache_total_nblks); 491 printf("cache blocksz: %u\n", bcache_blksize); 492 printf("cache readahead: %u\n", bcache_rablks); 493 printf("unit cache blocks: %u\n", bcache_unit_nblks); 494 printf("cached units: %u\n", bcache_units); 495 printf("%u ops %d bypasses %u hits %u misses\n", bcache_ops, 496 bcache_bypasses, bcache_hits, bcache_misses); 497 return(CMD_OK); 498 } 499 #endif 500