summaryrefslogtreecommitdiff
path: root/smalloc.c
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2009-07-07 17:43:11 +0200
committerJens Axboe <jens.axboe@oracle.com>2009-07-07 17:43:11 +0200
commitcf98708da292cb9e77bb6aff4eda7652103f4f77 (patch)
tree245af2210175f1c050c0833e0f66023d4654dc53 /smalloc.c
parente40823b10920f679d84f3f2222e319c168b1e7da (diff)
downloadfio-cf98708da292cb9e77bb6aff4eda7652103f4f77.tar.gz
Make smalloc redzone pointer properly aligned
It would SIGBUS on archs that require proper alignment, and work suboptimally on others. Real fix is pending, making sure that we always return naturally aligned pointers. But this at least makes it work on sparc64. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'smalloc.c')
-rw-r--r--smalloc.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/smalloc.c b/smalloc.c
index e82ef1da..e0bc4981 100644
--- a/smalloc.c
+++ b/smalloc.c
@@ -268,9 +268,20 @@ void scleanup(void)
}
#ifdef SMALLOC_REDZONE
+static void *postred_ptr(struct block_hdr *hdr)
+{
+ const int int_mask = sizeof(unsigned int) - 1;
+ unsigned long ptr;
+
+ ptr = (unsigned long) hdr + hdr->size - sizeof(unsigned int);
+ ptr = (ptr + int_mask) & ~int_mask;
+
+ return (void *) ptr;
+}
+
static void fill_redzone(struct block_hdr *hdr)
{
- unsigned int *postred = (void *) hdr + hdr->size - sizeof(unsigned int);
+ unsigned int *postred = postred_ptr(hdr);
hdr->prered = SMALLOC_PRE_RED;
*postred = SMALLOC_POST_RED;
@@ -278,7 +289,7 @@ static void fill_redzone(struct block_hdr *hdr)
static void sfree_check_redzone(struct block_hdr *hdr)
{
- unsigned int *postred = (void *) hdr + hdr->size - sizeof(unsigned int);
+ unsigned int *postred = postred_ptr(hdr);
if (hdr->prered != SMALLOC_PRE_RED) {
fprintf(stderr, "smalloc pre redzone destroyed!\n");
@@ -414,8 +425,12 @@ static void *smalloc_pool(struct pool *pool, unsigned int size)
unsigned int alloc_size = size + sizeof(struct block_hdr);
void *ptr;
+ /*
+ * Use twice the size for good luck, we may need to adjust
+ * alignment.
+ */
#ifdef SMALLOC_REDZONE
- alloc_size += sizeof(unsigned int);
+ alloc_size += 2 * sizeof(unsigned int);
#endif
ptr = __smalloc_pool(pool, alloc_size);