Commit 8f848fba authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Set the alignment of things in the persistent silo on a more

systematic footing.
parent e8b3d50e
...@@ -66,9 +66,6 @@ SVNID("$Id$") ...@@ -66,9 +66,6 @@ SVNID("$Id$")
#define ASSERT_SILO_THREAD(sc) \ #define ASSERT_SILO_THREAD(sc) \
do {assert(pthread_self() == (sc)->thread);} while (0) do {assert(pthread_self() == (sc)->thread);} while (0)
#define RDN2(x, y) ((x)&(~((y)-1))) /* if y is powers of two */
#define RUP2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
#define OC_F_NEEDFIXUP OC_F_PRIV #define OC_F_NEEDFIXUP OC_F_PRIV
/* /*
...@@ -130,7 +127,8 @@ struct smp_sc { ...@@ -130,7 +127,8 @@ struct smp_sc {
int fd; int fd;
const char *filename; const char *filename;
off_t mediasize; off_t mediasize;
unsigned granularity; uint64_t align; /* 64b to avoid casts */
uint32_t granularity;
uint32_t unique; uint32_t unique;
uint8_t *base; uint8_t *base;
...@@ -173,11 +171,23 @@ struct smp_sc { ...@@ -173,11 +171,23 @@ struct smp_sc {
uint64_t free_reserve; uint64_t free_reserve;
}; };
#define CACHE_LINE_ALIGN 16 /*--------------------------------------------------------------------*/
/* Generic power-2 rounding */
#define PWR2(x) ((((x)-1)&(x))==0) /* Is a power of two */
#define RDN2(x, y) ((x)&(~((y)-1))) /* if y is powers of two */
#define RUP2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
/* Pointer round up/down & assert */
#define PRNDN(sc, x) ((void*)RDN2((uintptr_t)x, sc->align))
#define PRNUP(sc, x) ((void*)RUP2((uintptr_t)x, sc->align))
#define ASSERTALIGN(sc, x) assert(PRDN(sc, x) == x)
#define C_ALIGN(x) RUP2(x, CACHE_LINE_ALIGN) /* Integer round up/down & assert */
#define IRNDN(sc, x) RDN2(x, sc->align)
#define IRNUP(sc, x) RUP2(x, sc->align)
#define SEG_SPACE RUP2(SMP_SIGN_SPACE, CACHE_LINE_ALIGN) /*--------------------------------------------------------------------*/
/* /*
* silos is unlocked, it only changes during startup when we are * silos is unlocked, it only changes during startup when we are
...@@ -356,11 +366,15 @@ smp_newsilo(struct smp_sc *sc) ...@@ -356,11 +366,15 @@ smp_newsilo(struct smp_sc *sc)
strcpy(si->ident, SMP_IDENT_STRING); strcpy(si->ident, SMP_IDENT_STRING);
si->byte_order = 0x12345678; si->byte_order = 0x12345678;
si->size = sizeof *si; si->size = sizeof *si;
si->major_version = 1; si->major_version = 2;
si->minor_version = 2;
si->unique = sc->unique; si->unique = sc->unique;
si->mediasize = sc->mediasize; si->mediasize = sc->mediasize;
si->granularity = sc->granularity; si->granularity = sc->granularity;
/*
* Aim for cache-line-width
*/
si->align = sizeof(void*) * 2;
sc->align = si->align;
si->stuff[SMP_BAN1_STUFF] = sc->granularity; si->stuff[SMP_BAN1_STUFF] = sc->granularity;
si->stuff[SMP_BAN2_STUFF] = si->stuff[SMP_BAN1_STUFF] + 1024*1024; si->stuff[SMP_BAN2_STUFF] = si->stuff[SMP_BAN1_STUFF] + 1024*1024;
...@@ -401,14 +415,17 @@ smp_valid_silo(struct smp_sc *sc) ...@@ -401,14 +415,17 @@ smp_valid_silo(struct smp_sc *sc)
return (3); return (3);
if (si->size != sizeof *si) if (si->size != sizeof *si)
return (4); return (4);
if (si->major_version != 1) if (si->major_version != 2)
return (5); return (5);
if (si->minor_version != 2)
return (6);
if (si->mediasize != sc->mediasize) if (si->mediasize != sc->mediasize)
return (7); return (7);
if (si->granularity != sc->granularity) if (si->granularity != sc->granularity)
return (8); return (8);
if (si->align < sizeof(void*))
return (9);
if (!PWR2(si->align))
return (10);
sc->align = si->align;
sc->unique = si->unique; sc->unique = si->unique;
/* XXX: Sanity check stuff[6] */ /* XXX: Sanity check stuff[6] */
...@@ -544,6 +561,7 @@ smp_init(struct stevedore *parent, int ac, char * const *av) ...@@ -544,6 +561,7 @@ smp_init(struct stevedore *parent, int ac, char * const *av)
#undef SIZOF #undef SIZOF
/* See comments in persistent.h */ /* See comments in persistent.h */
printf("%jd %d\n", sizeof(struct smp_ident), SMP_IDENT_SIZE);
assert(sizeof(struct smp_ident) == SMP_IDENT_SIZE); assert(sizeof(struct smp_ident) == SMP_IDENT_SIZE);
/* Allocate softc */ /* Allocate softc */
...@@ -561,6 +579,7 @@ smp_init(struct stevedore *parent, int ac, char * const *av) ...@@ -561,6 +579,7 @@ smp_init(struct stevedore *parent, int ac, char * const *av)
if (i == 2) if (i == 2)
ARGV_ERR("(-spersistent) need filename (not directory)\n"); ARGV_ERR("(-spersistent) need filename (not directory)\n");
sc->align = sizeof(void*) * 2;
sc->granularity = getpagesize(); sc->granularity = getpagesize();
sc->mediasize = STV_FileSize(sc->fd, av[1], &sc->granularity, sc->mediasize = STV_FileSize(sc->fd, av[1], &sc->granularity,
"-spersistent"); "-spersistent");
...@@ -1174,7 +1193,7 @@ smp_close_seg(struct smp_sc *sc, struct smp_seg *sg) ...@@ -1174,7 +1193,7 @@ smp_close_seg(struct smp_sc *sc, struct smp_seg *sg)
} }
assert(sg->nalloc1 * sizeof(struct smp_object) == sc->objreserv); assert(sg->nalloc1 * sizeof(struct smp_object) == sc->objreserv);
assert(C_ALIGN(sc->objreserv) + 2 * SEG_SPACE <= smp_spaceleft(sg)); // assert(C_ALIGN(sc->objreserv) + 2 * SEG_SPACE <= smp_spaceleft(sg));
/* Write the OBJIDX */ /* Write the OBJIDX */
sg->next_addr |= 7; sg->next_addr |= 7;
...@@ -1182,14 +1201,14 @@ smp_close_seg(struct smp_sc *sc, struct smp_seg *sg) ...@@ -1182,14 +1201,14 @@ smp_close_seg(struct smp_sc *sc, struct smp_seg *sg)
smp_def_sign(sc, sg->ctx, sg->next_addr, "OBJIDX"); smp_def_sign(sc, sg->ctx, sg->next_addr, "OBJIDX");
smp_reset_sign(sg->ctx); smp_reset_sign(sg->ctx);
smp_sync_sign(sg->ctx); smp_sync_sign(sg->ctx);
sg->next_addr += SEG_SPACE; sg->next_addr += IRNUP(sc, SMP_SIGN_SPACE);
/* Update the segment header */ /* Update the segment header */
sg->p.objlist = sg->next_addr; sg->p.objlist = sg->next_addr;
sg->p.nalloc = sg->nalloc1; sg->p.nalloc = sg->nalloc1;
p = (void*)(sc->base + sg->next_addr); p = (void*)(sc->base + sg->next_addr);
sg->next_addr += C_ALIGN(sc->objreserv); sg->next_addr += IRNUP(sc, sc->objreserv);
memcpy(p, sg->objs, sc->objreserv); memcpy(p, sg->objs, sc->objreserv);
sc->objbuf = sg->objs; sc->objbuf = sg->objs;
...@@ -1200,7 +1219,7 @@ smp_close_seg(struct smp_sc *sc, struct smp_seg *sg) ...@@ -1200,7 +1219,7 @@ smp_close_seg(struct smp_sc *sc, struct smp_seg *sg)
smp_def_sign(sc, sg->ctx, sg->next_addr, "SEGTAIL"); smp_def_sign(sc, sg->ctx, sg->next_addr, "SEGTAIL");
smp_reset_sign(sg->ctx); smp_reset_sign(sg->ctx);
smp_sync_sign(sg->ctx); smp_sync_sign(sg->ctx);
sg->next_addr += SEG_SPACE; sg->next_addr += IRNUP(sc, SMP_SIGN_SPACE);
sg->p.length = sg->next_addr - sg->p.offset; sg->p.length = sg->next_addr - sg->p.offset;
...@@ -1327,19 +1346,19 @@ smp_allocx(struct stevedore *st, size_t size, struct smp_seg **sgp) ...@@ -1327,19 +1346,19 @@ smp_allocx(struct stevedore *st, size_t size, struct smp_seg **sgp)
CAST_OBJ_NOTNULL(sc, st->priv, SMP_SC_MAGIC); CAST_OBJ_NOTNULL(sc, st->priv, SMP_SC_MAGIC);
Lck_Lock(&sc->mtx); Lck_Lock(&sc->mtx);
size = C_ALIGN(size); size = IRNUP(sc, size);
for (tries = 0; tries < 3; tries++) { for (tries = 0; tries < 3; tries++) {
sg = sc->cur_seg; sg = sc->cur_seg;
CHECK_OBJ_NOTNULL(sg, SMP_SEG_MAGIC); CHECK_OBJ_NOTNULL(sg, SMP_SEG_MAGIC);
overhead = C_ALIGN(sizeof *ss); overhead = IRNUP(sc, sizeof *ss);
overhead += SEG_SPACE * 2; overhead += 2 * IRNUP(sc, SMP_SIGN_SPACE);
if (sgp == NULL) { if (sgp == NULL) {
overhead += C_ALIGN(sc->objreserv); overhead += IRNUP(sc, sc->objreserv);
} else { } else {
overhead += overhead += IRNUP(sc,
C_ALIGN(sizeof(struct smp_object) + sc->objreserv); sizeof(struct smp_object) + sc->objreserv);
} }
needed = overhead + size; needed = overhead + size;
left = smp_spaceleft(sg); left = smp_spaceleft(sg);
...@@ -1368,7 +1387,7 @@ smp_allocx(struct stevedore *st, size_t size, struct smp_seg **sgp) ...@@ -1368,7 +1387,7 @@ smp_allocx(struct stevedore *st, size_t size, struct smp_seg **sgp)
smp_new_seg(sc); smp_new_seg(sc);
} }
assert(size == C_ALIGN(size)); assert(size == IRNUP(sc, size));
if (needed > smp_spaceleft(sg)) { if (needed > smp_spaceleft(sg)) {
Lck_Unlock(&sc->mtx); Lck_Unlock(&sc->mtx);
...@@ -1379,12 +1398,14 @@ smp_allocx(struct stevedore *st, size_t size, struct smp_seg **sgp) ...@@ -1379,12 +1398,14 @@ smp_allocx(struct stevedore *st, size_t size, struct smp_seg **sgp)
/* Grab for storage struct */ /* Grab for storage struct */
ss = (void *)(sc->base + sg->next_addr); ss = (void *)(sc->base + sg->next_addr);
sg->next_addr += C_ALIGN(sizeof *ss); sg->next_addr += IRNUP(sc, sizeof *ss);
/* Grab for allocated space */ /* Grab for allocated space */
allocation = sc->base + sg->next_addr; allocation = sc->base + sg->next_addr;
sg->next_addr += size; sg->next_addr += size;
assert((char*)allocation > (char*)ss);
/* Paint our marker */ /* Paint our marker */
memcpy(sc->base + sg->next_addr, "HERE", 4); memcpy(sc->base + sg->next_addr, "HERE", 4);
......
...@@ -79,10 +79,10 @@ struct smp_ident { ...@@ -79,10 +79,10 @@ struct smp_ident {
uint32_t major_version; uint32_t major_version;
uint32_t minor_version;
uint32_t unique; uint32_t unique;
uint32_t align; /* alignment in silo */
uint32_t granularity; /* smallest ... in bytes */ uint32_t granularity; /* smallest ... in bytes */
uint64_t mediasize; /* ... in bytes */ uint64_t mediasize; /* ... in bytes */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment