On Wed, Nov 25, 2015 at 11:01:40AM -0700, Bob Beck wrote: > At first go, you need a bit more #ifdef WAPBL in there.. the idea > being we want to be able to build kernels selectively with > and without WAPBL compiled in at all.... and initially we may not (by > default) put it in GENERIC. > > I'll mail you a diff shortly.
Thanks Bob, I'm waiting for your diff to send my new attempt of a clear and acceptable diff. mpi@ talked with me too. And give me some tips. > > On Wed, Nov 25, 2015 at 10:55 AM, Bob Beck <b...@openbsd.org> wrote: > > Nice walter.. I was just going to start separating this out myself and > > theo distracted me :) > > > > I'll take a look at this right away. > > > > > > On Wed, Nov 25, 2015 at 8:27 AM, Walter Neto <wsouz...@gmail.com> wrote: > >> Changes needed in buffercache(9) for WAPBL > >> > >> - All changes needed in vfs_bio.c > >> - Adding WAPBL headers > >> - Introducing buf_adjcnt to inform wapbl when a buffer has changed its > >> size (get > >> it from Bitrig) > >> > >> Hi guys, with this diff I'm trying to introduce WAPBL to OpenBSD a > >> little more splitted than before. > >> > >> If someone want to see all the implementation, you can get it on > >> https://github.com/radixo/openbsd-src/tree/wapbl > >> > >> I hope to get the feature as soon as possible in OpenBSD. > >> Thanks in advance guys. :) > >> > >> Index: sys/kern/vfs_bio.c > >> =================================================================== > >> RCS file: /Volumes/CSP/cvs/src/sys/kern/vfs_bio.c,v > >> retrieving revision 1.170 > >> diff -u -r1.170 vfs_bio.c > >> --- sys/kern/vfs_bio.c 19 Jul 2015 16:21:11 -0000 1.170 > >> +++ sys/kern/vfs_bio.c 25 Nov 2015 14:37:01 -0000 > >> @@ -56,7 +56,7 @@ > >> #include <sys/resourcevar.h> > >> #include <sys/conf.h> > >> #include <sys/kernel.h> > >> -#include <sys/specdev.h> > >> +#include <sys/wapbl.h> > >> #include <uvm/uvm_extern.h> > >> > >> int nobuffers; > >> @@ -556,6 +556,16 @@ > >> mp = NULL; > >> > >> /* > >> + * If using WAPBL, convert it to a delayed write > >> + */ > >> + if (mp && mp->mnt_wapbl) { > >> + if (bp->b_iodone != mp->mnt_wapbl_op->wo_wapbl_biodone) { > >> + bdwrite(bp); > >> + return 0; > >> + } > >> + } > >> + > >> + /* > >> * Remember buffer type, to switch on it later. If the write was > >> * synchronous, but the file system was mounted with MNT_ASYNC, > >> * convert it to a delayed write. > >> @@ -628,7 +638,6 @@ > >> return (rv); > >> } > >> > >> - > >> /* > >> * Delayed write. > >> * > >> @@ -647,6 +656,20 @@ > >> { > >> int s; > >> > >> + /* If this is a tape block, write the block now. */ > >> + if (major(bp->b_dev) < nblkdev && > >> + bdevsw[major(bp->b_dev)].d_type == D_TAPE) { > >> + bawrite(bp); > >> + return; > >> + } > >> + > >> + if (wapbl_vphaswapbl(bp->b_vp)) { > >> + struct mount *mp = wapbl_vptomp(bp->b_vp); > >> + > >> + if (bp->b_iodone != mp->mnt_wapbl_op->wo_wapbl_biodone) > >> + WAPBL_ADD_BUF(mp, bp); > >> + } > >> + > >> /* > >> * If the block hasn't been seen before: > >> * (1) Mark it as having been seen, > >> @@ -663,13 +686,6 @@ > >> curproc->p_ru.ru_oublock++; /* XXX */ > >> } > >> > >> - /* If this is a tape block, write the block now. */ > >> - if (major(bp->b_dev) < nblkdev && > >> - bdevsw[major(bp->b_dev)].d_type == D_TAPE) { > >> - bawrite(bp); > >> - return; > >> - } > >> - > >> /* Otherwise, the "write" is done, so mark and release the buffer. > >> */ > >> CLR(bp->b_flags, B_NEEDCOMMIT); > >> SET(bp->b_flags, B_DONE); > >> @@ -743,12 +759,28 @@ > >> * Determine which queue the buffer should be on, then put it > >> there. > >> */ > >> > >> + /* If it's locked, don't report an error; try again later */ > >> + if (ISSET(bp->b_flags, (B_LOCKED|B_ERROR)) == (B_LOCKED|B_ERROR)) > >> + CLR(bp->b_flags, B_ERROR); > >> + > >> /* If it's not cacheable, or an error, mark it invalid. */ > >> if (ISSET(bp->b_flags, (B_NOCACHE|B_ERROR))) > >> SET(bp->b_flags, B_INVAL); > >> > >> if (ISSET(bp->b_flags, B_INVAL)) { > >> /* > >> + * If using WAPBL > >> + */ > >> + if (ISSET(bp->b_flags, B_LOCKED)) { > >> + if (wapbl_vphaswapbl(bp->b_vp)) { > >> + struct mount *mp = wapbl_vptomp(bp->b_vp); > >> + KASSERT(bp->b_iodone > >> + != mp->mnt_wapbl_op->wo_wapbl_biodone); > >> + WAPBL_REMOVE_BUF(mp, bp); > >> + } > >> + } > >> + > >> + /* > >> * If the buffer is invalid, free it now rather than > >> leaving > >> * it in a queue and wasting memory. > >> */ > >> @@ -1079,6 +1111,19 @@ > >> if (!ISSET(bp->b_flags, B_DELWRI)) > >> panic("Clean buffer on dirty queue"); > >> #endif > >> + > >> + > >> +#ifdef WAPBL > >> + if (ISSET(bp->b_flags, B_LOCKED) && > >> + wapbl_vphaswapbl(bp->b_vp)) { > >> + brelse(bp); > >> + struct mount *mp = wapbl_vptomp(bp->b_vp); > >> + wapbl_flush(mp->mnt_wapbl, 1); > >> + s = splbio(); > >> + continue; > >> + } > >> +#endif /* WAPBL */ > >> + > >> if (LIST_FIRST(&bp->b_dep) != NULL && > >> !ISSET(bp->b_flags, B_DEFERRED) && > >> buf_countdeps(bp, 0, 0)) { > >> @@ -1206,6 +1251,17 @@ > >> } > >> #endif > >> > >> +void > >> +buf_adjcnt(struct buf *bp, long ncount) > >> +{ > >> + KASSERT(ncount <= bp->b_bufsize); > >> + long ocount = bp->b_bcount; > >> + bp->b_bcount = ncount; > >> + if (wapbl_vphaswapbl(bp->b_vp)) > >> + WAPBL_RESIZE_BUF(wapbl_vptomp(bp->b_vp), bp, bp->b_bufsize, > >> + ocount); > >> +} > >> + > >> /* bufcache freelist code below */ > >> /* > >> * Copyright (c) 2014 Ted Unangst <t...@openbsd.org> > >> Index: sys/sys/buf.h > >> =================================================================== > >> RCS file: /Volumes/CSP/cvs/src/sys/sys/buf.h,v > >> retrieving revision 1.99 > >> diff -u -r1.99 buf.h > >> --- sys/sys/buf.h 19 Jul 2015 16:21:11 -0000 1.99 > >> +++ sys/sys/buf.h 25 Nov 2015 14:51:02 -0000 > >> @@ -221,12 +221,14 @@ > >> #define B_COLD 0x01000000 /* buffer is on the cold > >> queue */ > >> #define B_BC 0x02000000 /* buffer is managed by > >> the cache */ > >> #define B_DMA 0x04000000 /* buffer is DMA reachable > >> */ > >> +#define B_LOCKED 0x08000000 /* Locked in core (not > >> reusable). */ > >> > >> #define B_BITS "\20\001AGE\002NEEDCOMMIT\003ASYNC\004BAD\005BUSY" > >> \ > >> "\006CACHE\007CALL\010DELWRI\011DONE\012EINTR\013ERROR" \ > >> "\014INVAL\015NOCACHE\016PHYS\017RAW\020READ" \ > >> "\021WANTED\022WRITEINPROG\023XXX(FORMAT)\024DEFERRED" \ > >> - "\025SCANNED\026DAEMON\027RELEASED\030WARM\031COLD\032BC\033DMA" > >> + "\025SCANNED\026DAEMON\027RELEASED\030WARM\031COLD\032BC\033DMA" \ > >> + "\034LOCKED" > >> > >> /* > >> * This structure describes a clustered I/O. It is stored in the > >> b_saveaddr > >> @@ -292,6 +294,7 @@ > >> void bufinit(void); > >> void buf_dirty(struct buf *); > >> void buf_undirty(struct buf *); > >> +void buf_adjcnt(struct buf *, long); > >> int bwrite(struct buf *); > >> struct buf *getblk(struct vnode *, daddr_t, int, int, int); > >> struct buf *geteblk(int); > >> Index: sys/sys/mount.h > >> =================================================================== > >> RCS file: /Volumes/CSP/cvs/src/sys/sys/mount.h,v > >> retrieving revision 1.121 > >> diff -u -r1.121 mount.h > >> --- sys/sys/mount.h 8 Sep 2014 01:47:06 -0000 1.121 > >> +++ sys/sys/mount.h 25 Nov 2015 14:46:45 -0000 > >> @@ -358,6 +358,11 @@ > >> int mnt_maxsymlinklen; /* max size of short > >> symlink */ > >> struct statfs mnt_stat; /* cache of filesystem > >> stats */ > >> void *mnt_data; /* private data */ > >> + struct wapbl_ops > >> + *mnt_wapbl_op; /* logging ops */ > >> + struct wapbl *mnt_wapbl; /* log info */ > >> + struct wapbl_replay > >> + *mnt_wapbl_replay; /* replay support XXX: > >> what? */ > >> }; > >> > >> /* > >> @@ -501,6 +506,51 @@ > >> extern int bufbackoff(struct uvm_constraint_range*, long); > >> > >> /* > >> + * This operations vector is so wapbl can be wrapped into a filesystem > >> lkm. > >> + * XXX Eventually, we want to move this functionality > >> + * down into the filesystems themselves so that this isn't needed. > >> + */ > >> +struct wapbl_ops { > >> + void (*wo_wapbl_discard)(struct wapbl *); > >> + int (*wo_wapbl_replay_isopen)(struct wapbl_replay *); > >> + int (*wo_wapbl_replay_can_read)(struct wapbl_replay *, daddr_t, > >> long); > >> + int (*wo_wapbl_replay_read)(struct wapbl_replay *, void *, daddr_t, > >> + long); > >> + void (*wo_wapbl_add_buf)(struct wapbl *, struct buf *); > >> + void (*wo_wapbl_remove_buf)(struct wapbl *, struct buf *); > >> + void (*wo_wapbl_resize_buf)(struct wapbl *, struct buf *, long, > >> long); > >> + int (*wo_wapbl_begin)(struct wapbl *, const char *, int); > >> + void (*wo_wapbl_end)(struct wapbl *); > >> + void (*wo_wapbl_junlock_assert)(struct wapbl *); > >> + void (*wo_wapbl_biodone)(struct buf *); > >> +}; > >> +#define WAPBL_DISCARD(MP) \ > >> + (*(MP)->mnt_wapbl_op->wo_wapbl_discard)((MP)->mnt_wapbl) > >> +#define WAPBL_REPLAY_ISOPEN(MP) > >> \ > >> + (*(MP)->mnt_wapbl_op->wo_wapbl_replay_isopen)((MP)->mnt_wapbl_replay) > >> +#define WAPBL_REPLAY_CAN_READ(MP, BLK, LEN) \ > >> + > >> (*(MP)->mnt_wapbl_op->wo_wapbl_replay_can_read)((MP)->mnt_wapbl_replay, \ > >> + (BLK), (LEN)) > >> +#define WAPBL_REPLAY_READ(MP, DATA, BLK, LEN) \ > >> + (*(MP)->mnt_wapbl_op->wo_wapbl_replay_read)((MP)->mnt_wapbl_replay, > >> \ > >> + (DATA), (BLK), (LEN)) > >> +#define WAPBL_ADD_BUF(MP, BP) \ > >> + (*(MP)->mnt_wapbl_op->wo_wapbl_add_buf)((MP)->mnt_wapbl, (BP)) > >> +#define WAPBL_REMOVE_BUF(MP, BP) \ > >> + (*(MP)->mnt_wapbl_op->wo_wapbl_remove_buf)((MP)->mnt_wapbl, (BP)) > >> +#define WAPBL_RESIZE_BUF(MP, BP, OLDSZ, OLDCNT) > >> \ > >> + (*(MP)->mnt_wapbl_op->wo_wapbl_resize_buf)((MP)->mnt_wapbl, (BP), \ > >> + (OLDSZ), (OLDCNT)) > >> +#define WAPBL_BEGIN(MP) > >> \ > >> + (*(MP)->mnt_wapbl_op->wo_wapbl_begin)((MP)->mnt_wapbl, \ > >> + __FILE__, __LINE__) > >> +#define WAPBL_END(MP) \ > >> + (*(MP)->mnt_wapbl_op->wo_wapbl_end)((MP)->mnt_wapbl) > >> +#define WAPBL_JUNLOCK_ASSERT(MP) \ > >> + (*(MP)->mnt_wapbl_op->wo_wapbl_junlock_assert)((MP)->mnt_wapbl) > >> + > >> + > >> +/* > >> * Operations supported on mounted file system. > >> */ > >> struct nameidata; > >>