2007-05-17 14:33:03

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH] ubi: kill homegrown endian macros

Kill ubis homegrown endianess handling crap and replace it with
the normal kernel endianess handling.


Signed-off-by: Christoph Hellwig <[email protected]>

Index: linux-2.6/drivers/mtd/ubi/debug.c
===================================================================
--- linux-2.6.orig/drivers/mtd/ubi/debug.c 2007-05-17 15:06:33.000000000 +0200
+++ linux-2.6/drivers/mtd/ubi/debug.c 2007-05-17 15:19:56.000000000 +0200
@@ -35,12 +35,12 @@
void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr)
{
dbg_msg("erase counter header dump:");
- dbg_msg("magic %#08x", ubi32_to_cpu(ec_hdr->magic));
+ dbg_msg("magic %#08x", be32_to_cpu(ec_hdr->magic));
dbg_msg("version %d", (int)ec_hdr->version);
- dbg_msg("ec %llu", (long long)ubi64_to_cpu(ec_hdr->ec));
- dbg_msg("vid_hdr_offset %d", ubi32_to_cpu(ec_hdr->vid_hdr_offset));
- dbg_msg("data_offset %d", ubi32_to_cpu(ec_hdr->data_offset));
- dbg_msg("hdr_crc %#08x", ubi32_to_cpu(ec_hdr->hdr_crc));
+ dbg_msg("ec %llu", (long long)be64_to_cpu(ec_hdr->ec));
+ dbg_msg("vid_hdr_offset %d", be32_to_cpu(ec_hdr->vid_hdr_offset));
+ dbg_msg("data_offset %d", be32_to_cpu(ec_hdr->data_offset));
+ dbg_msg("hdr_crc %#08x", be32_to_cpu(ec_hdr->hdr_crc));
dbg_msg("erase counter header hexdump:");
ubi_dbg_hexdump(ec_hdr, UBI_EC_HDR_SIZE);
}
@@ -52,20 +52,20 @@ void ubi_dbg_dump_ec_hdr(const struct ub
void ubi_dbg_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr)
{
dbg_msg("volume identifier header dump:");
- dbg_msg("magic %08x", ubi32_to_cpu(vid_hdr->magic));
+ dbg_msg("magic %08x", be32_to_cpu(vid_hdr->magic));
dbg_msg("version %d", (int)vid_hdr->version);
dbg_msg("vol_type %d", (int)vid_hdr->vol_type);
dbg_msg("copy_flag %d", (int)vid_hdr->copy_flag);
dbg_msg("compat %d", (int)vid_hdr->compat);
- dbg_msg("vol_id %d", ubi32_to_cpu(vid_hdr->vol_id));
- dbg_msg("lnum %d", ubi32_to_cpu(vid_hdr->lnum));
- dbg_msg("leb_ver %u", ubi32_to_cpu(vid_hdr->leb_ver));
- dbg_msg("data_size %d", ubi32_to_cpu(vid_hdr->data_size));
- dbg_msg("used_ebs %d", ubi32_to_cpu(vid_hdr->used_ebs));
- dbg_msg("data_pad %d", ubi32_to_cpu(vid_hdr->data_pad));
+ dbg_msg("vol_id %d", be32_to_cpu(vid_hdr->vol_id));
+ dbg_msg("lnum %d", be32_to_cpu(vid_hdr->lnum));
+ dbg_msg("leb_ver %u", be32_to_cpu(vid_hdr->leb_ver));
+ dbg_msg("data_size %d", be32_to_cpu(vid_hdr->data_size));
+ dbg_msg("used_ebs %d", be32_to_cpu(vid_hdr->used_ebs));
+ dbg_msg("data_pad %d", be32_to_cpu(vid_hdr->data_pad));
dbg_msg("sqnum %llu",
- (unsigned long long)ubi64_to_cpu(vid_hdr->sqnum));
- dbg_msg("hdr_crc %08x", ubi32_to_cpu(vid_hdr->hdr_crc));
+ (unsigned long long)be64_to_cpu(vid_hdr->sqnum));
+ dbg_msg("hdr_crc %08x", be32_to_cpu(vid_hdr->hdr_crc));
dbg_msg("volume identifier header hexdump:");
}

@@ -106,12 +106,12 @@ void ubi_dbg_dump_vol_info(const struct
*/
void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx)
{
- int name_len = ubi16_to_cpu(r->name_len);
+ int name_len = be16_to_cpu(r->name_len);

dbg_msg("volume table record %d dump:", idx);
- dbg_msg("reserved_pebs %d", ubi32_to_cpu(r->reserved_pebs));
- dbg_msg("alignment %d", ubi32_to_cpu(r->alignment));
- dbg_msg("data_pad %d", ubi32_to_cpu(r->data_pad));
+ dbg_msg("reserved_pebs %d", be32_to_cpu(r->reserved_pebs));
+ dbg_msg("alignment %d", be32_to_cpu(r->alignment));
+ dbg_msg("data_pad %d", be32_to_cpu(r->data_pad));
dbg_msg("vol_type %d", (int)r->vol_type);
dbg_msg("upd_marker %d", (int)r->upd_marker);
dbg_msg("name_len %d", name_len);
@@ -129,7 +129,7 @@ void ubi_dbg_dump_vtbl_record(const stru
r->name[0], r->name[1], r->name[2], r->name[3],
r->name[4]);
}
- dbg_msg("crc %#08x", ubi32_to_cpu(r->crc));
+ dbg_msg("crc %#08x", be32_to_cpu(r->crc));
}

/**
Index: linux-2.6/drivers/mtd/ubi/eba.c
===================================================================
--- linux-2.6.orig/drivers/mtd/ubi/eba.c 2007-05-17 15:06:33.000000000 +0200
+++ linux-2.6/drivers/mtd/ubi/eba.c 2007-05-17 15:19:18.000000000 +0200
@@ -425,10 +425,10 @@ retry:
} else if (err == UBI_IO_BITFLIPS)
scrub = 1;

- ubi_assert(lnum < ubi32_to_cpu(vid_hdr->used_ebs));
- ubi_assert(len == ubi32_to_cpu(vid_hdr->data_size));
+ ubi_assert(lnum < be32_to_cpu(vid_hdr->used_ebs));
+ ubi_assert(len == be32_to_cpu(vid_hdr->data_size));

- crc = ubi32_to_cpu(vid_hdr->data_crc);
+ crc = be32_to_cpu(vid_hdr->data_crc);
ubi_free_vid_hdr(ubi, vid_hdr);
}

@@ -518,7 +518,7 @@ retry:
goto out_put;
}

- vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi));
+ vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr);
if (err)
goto write_error;
@@ -634,11 +634,11 @@ int ubi_eba_write_leb(struct ubi_device
}

vid_hdr->vol_type = UBI_VID_DYNAMIC;
- vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi));
- vid_hdr->vol_id = cpu_to_ubi32(vol_id);
- vid_hdr->lnum = cpu_to_ubi32(lnum);
+ vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
+ vid_hdr->vol_id = cpu_to_be32(vol_id);
+ vid_hdr->lnum = cpu_to_be32(lnum);
vid_hdr->compat = ubi_get_compat(ubi, vol_id);
- vid_hdr->data_pad = cpu_to_ubi32(vol->data_pad);
+ vid_hdr->data_pad = cpu_to_be32(vol->data_pad);

retry:
pnum = ubi_wl_get_peb(ubi, dtype);
@@ -692,7 +692,7 @@ write_error:
return err;
}

- vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi));
+ vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
ubi_msg("try another PEB");
goto retry;
}
@@ -748,17 +748,17 @@ int ubi_eba_write_leb_st(struct ubi_devi
return err;
}

- vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi));
- vid_hdr->vol_id = cpu_to_ubi32(vol_id);
- vid_hdr->lnum = cpu_to_ubi32(lnum);
+ vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
+ vid_hdr->vol_id = cpu_to_be32(vol_id);
+ vid_hdr->lnum = cpu_to_be32(lnum);
vid_hdr->compat = ubi_get_compat(ubi, vol_id);
- vid_hdr->data_pad = cpu_to_ubi32(vol->data_pad);
+ vid_hdr->data_pad = cpu_to_be32(vol->data_pad);

crc = crc32(UBI_CRC32_INIT, buf, data_size);
vid_hdr->vol_type = UBI_VID_STATIC;
- vid_hdr->data_size = cpu_to_ubi32(data_size);
- vid_hdr->used_ebs = cpu_to_ubi32(used_ebs);
- vid_hdr->data_crc = cpu_to_ubi32(crc);
+ vid_hdr->data_size = cpu_to_be32(data_size);
+ vid_hdr->used_ebs = cpu_to_be32(used_ebs);
+ vid_hdr->data_crc = cpu_to_be32(crc);

retry:
pnum = ubi_wl_get_peb(ubi, dtype);
@@ -813,7 +813,7 @@ write_error:
return err;
}

- vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi));
+ vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
ubi_msg("try another PEB");
goto retry;
}
@@ -854,17 +854,17 @@ int ubi_eba_atomic_leb_change(struct ubi
return err;
}

- vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi));
- vid_hdr->vol_id = cpu_to_ubi32(vol_id);
- vid_hdr->lnum = cpu_to_ubi32(lnum);
+ vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
+ vid_hdr->vol_id = cpu_to_be32(vol_id);
+ vid_hdr->lnum = cpu_to_be32(lnum);
vid_hdr->compat = ubi_get_compat(ubi, vol_id);
- vid_hdr->data_pad = cpu_to_ubi32(vol->data_pad);
+ vid_hdr->data_pad = cpu_to_be32(vol->data_pad);

crc = crc32(UBI_CRC32_INIT, buf, len);
vid_hdr->vol_type = UBI_VID_STATIC;
- vid_hdr->data_size = cpu_to_ubi32(len);
+ vid_hdr->data_size = cpu_to_be32(len);
vid_hdr->copy_flag = 1;
- vid_hdr->data_crc = cpu_to_ubi32(crc);
+ vid_hdr->data_crc = cpu_to_be32(crc);

retry:
pnum = ubi_wl_get_peb(ubi, dtype);
@@ -924,7 +924,7 @@ write_error:
return err;
}

- vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi));
+ vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
ubi_msg("try another PEB");
goto retry;
}
@@ -965,17 +965,17 @@ int ubi_eba_copy_leb(struct ubi_device *
uint32_t crc;
void *buf, *buf1 = NULL;

- vol_id = ubi32_to_cpu(vid_hdr->vol_id);
- lnum = ubi32_to_cpu(vid_hdr->lnum);
+ vol_id = be32_to_cpu(vid_hdr->vol_id);
+ lnum = be32_to_cpu(vid_hdr->lnum);

dbg_eba("copy LEB %d:%d, PEB %d to PEB %d", vol_id, lnum, from, to);

if (vid_hdr->vol_type == UBI_VID_STATIC) {
- data_size = ubi32_to_cpu(vid_hdr->data_size);
+ data_size = be32_to_cpu(vid_hdr->data_size);
aldata_size = ALIGN(data_size, ubi->min_io_size);
} else
data_size = aldata_size =
- ubi->leb_size - ubi32_to_cpu(vid_hdr->data_pad);
+ ubi->leb_size - be32_to_cpu(vid_hdr->data_pad);

buf = kmalloc(aldata_size, GFP_KERNEL);
if (!buf)
@@ -1054,10 +1054,10 @@ int ubi_eba_copy_leb(struct ubi_device *
*/
if (data_size > 0) {
vid_hdr->copy_flag = 1;
- vid_hdr->data_size = cpu_to_ubi32(data_size);
- vid_hdr->data_crc = cpu_to_ubi32(crc);
+ vid_hdr->data_size = cpu_to_be32(data_size);
+ vid_hdr->data_crc = cpu_to_be32(crc);
}
- vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi));
+ vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));

err = ubi_io_write_vid_hdr(ubi, to, vid_hdr);
if (err)
Index: linux-2.6/drivers/mtd/ubi/io.c
===================================================================
--- linux-2.6.orig/drivers/mtd/ubi/io.c 2007-05-17 15:06:33.000000000 +0200
+++ linux-2.6/drivers/mtd/ubi/io.c 2007-05-17 15:15:22.000000000 +0200
@@ -557,9 +557,9 @@ static int validate_ec_hdr(const struct
long long ec;
int vid_hdr_offset, leb_start;

- ec = ubi64_to_cpu(ec_hdr->ec);
- vid_hdr_offset = ubi32_to_cpu(ec_hdr->vid_hdr_offset);
- leb_start = ubi32_to_cpu(ec_hdr->data_offset);
+ ec = be64_to_cpu(ec_hdr->ec);
+ vid_hdr_offset = be32_to_cpu(ec_hdr->vid_hdr_offset);
+ leb_start = be32_to_cpu(ec_hdr->data_offset);

if (ec_hdr->version != UBI_VERSION) {
ubi_err("node with incompatible UBI version found: "
@@ -640,7 +640,7 @@ int ubi_io_read_ec_hdr(const struct ubi_
read_err = err;
}

- magic = ubi32_to_cpu(ec_hdr->magic);
+ magic = be32_to_cpu(ec_hdr->magic);
if (magic != UBI_EC_HDR_MAGIC) {
/*
* The magic field is wrong. Let's check if we have read all
@@ -684,7 +684,7 @@ int ubi_io_read_ec_hdr(const struct ubi_
}

crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC);
- hdr_crc = ubi32_to_cpu(ec_hdr->hdr_crc);
+ hdr_crc = be32_to_cpu(ec_hdr->hdr_crc);

if (hdr_crc != crc) {
if (verbose) {
@@ -729,12 +729,12 @@ int ubi_io_write_ec_hdr(const struct ubi
dbg_io("write EC header to PEB %d", pnum);
ubi_assert(pnum >= 0 && pnum < ubi->peb_count);

- ec_hdr->magic = cpu_to_ubi32(UBI_EC_HDR_MAGIC);
+ ec_hdr->magic = cpu_to_be32(UBI_EC_HDR_MAGIC);
ec_hdr->version = UBI_VERSION;
- ec_hdr->vid_hdr_offset = cpu_to_ubi32(ubi->vid_hdr_offset);
- ec_hdr->data_offset = cpu_to_ubi32(ubi->leb_start);
+ ec_hdr->vid_hdr_offset = cpu_to_be32(ubi->vid_hdr_offset);
+ ec_hdr->data_offset = cpu_to_be32(ubi->leb_start);
crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC);
- ec_hdr->hdr_crc = cpu_to_ubi32(crc);
+ ec_hdr->hdr_crc = cpu_to_be32(crc);

err = paranoid_check_ec_hdr(ubi, pnum, ec_hdr);
if (err)
@@ -757,13 +757,13 @@ static int validate_vid_hdr(const struct
{
int vol_type = vid_hdr->vol_type;
int copy_flag = vid_hdr->copy_flag;
- int vol_id = ubi32_to_cpu(vid_hdr->vol_id);
- int lnum = ubi32_to_cpu(vid_hdr->lnum);
+ int vol_id = be32_to_cpu(vid_hdr->vol_id);
+ int lnum = be32_to_cpu(vid_hdr->lnum);
int compat = vid_hdr->compat;
- int data_size = ubi32_to_cpu(vid_hdr->data_size);
- int used_ebs = ubi32_to_cpu(vid_hdr->used_ebs);
- int data_pad = ubi32_to_cpu(vid_hdr->data_pad);
- int data_crc = ubi32_to_cpu(vid_hdr->data_crc);
+ int data_size = be32_to_cpu(vid_hdr->data_size);
+ int used_ebs = be32_to_cpu(vid_hdr->used_ebs);
+ int data_pad = be32_to_cpu(vid_hdr->data_pad);
+ int data_crc = be32_to_cpu(vid_hdr->data_crc);
int usable_leb_size = ubi->leb_size - data_pad;

if (copy_flag != 0 && copy_flag != 1) {
@@ -914,7 +914,7 @@ int ubi_io_read_vid_hdr(const struct ubi
read_err = err;
}

- magic = ubi32_to_cpu(vid_hdr->magic);
+ magic = be32_to_cpu(vid_hdr->magic);
if (magic != UBI_VID_HDR_MAGIC) {
/*
* If we have read all 0xFF bytes, the VID header probably does
@@ -957,7 +957,7 @@ int ubi_io_read_vid_hdr(const struct ubi
}

crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC);
- hdr_crc = ubi32_to_cpu(vid_hdr->hdr_crc);
+ hdr_crc = be32_to_cpu(vid_hdr->hdr_crc);

if (hdr_crc != crc) {
if (verbose) {
@@ -1007,10 +1007,10 @@ int ubi_io_write_vid_hdr(const struct ub
if (err)
return err > 0 ? -EINVAL: err;

- vid_hdr->magic = cpu_to_ubi32(UBI_VID_HDR_MAGIC);
+ vid_hdr->magic = cpu_to_be32(UBI_VID_HDR_MAGIC);
vid_hdr->version = UBI_VERSION;
crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC);
- vid_hdr->hdr_crc = cpu_to_ubi32(crc);
+ vid_hdr->hdr_crc = cpu_to_be32(crc);

err = paranoid_check_vid_hdr(ubi, pnum, vid_hdr);
if (err)
@@ -1060,7 +1060,7 @@ static int paranoid_check_ec_hdr(const s
int err;
uint32_t magic;

- magic = ubi32_to_cpu(ec_hdr->magic);
+ magic = be32_to_cpu(ec_hdr->magic);
if (magic != UBI_EC_HDR_MAGIC) {
ubi_err("bad magic %#08x, must be %#08x",
magic, UBI_EC_HDR_MAGIC);
@@ -1105,7 +1105,7 @@ static int paranoid_check_peb_ec_hdr(con
goto exit;

crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC);
- hdr_crc = ubi32_to_cpu(ec_hdr->hdr_crc);
+ hdr_crc = be32_to_cpu(ec_hdr->hdr_crc);
if (hdr_crc != crc) {
ubi_err("bad CRC, calculated %#08x, read %#08x", crc, hdr_crc);
ubi_err("paranoid check failed for PEB %d", pnum);
@@ -1137,7 +1137,7 @@ static int paranoid_check_vid_hdr(const
int err;
uint32_t magic;

- magic = ubi32_to_cpu(vid_hdr->magic);
+ magic = be32_to_cpu(vid_hdr->magic);
if (magic != UBI_VID_HDR_MAGIC) {
ubi_err("bad VID header magic %#08x at PEB %d, must be %#08x",
magic, pnum, UBI_VID_HDR_MAGIC);
@@ -1187,7 +1187,7 @@ static int paranoid_check_peb_vid_hdr(co
goto exit;

crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_EC_HDR_SIZE_CRC);
- hdr_crc = ubi32_to_cpu(vid_hdr->hdr_crc);
+ hdr_crc = be32_to_cpu(vid_hdr->hdr_crc);
if (hdr_crc != crc) {
ubi_err("bad VID header CRC at PEB %d, calculated %#08x, "
"read %#08x", pnum, crc, hdr_crc);
Index: linux-2.6/drivers/mtd/ubi/scan.c
===================================================================
--- linux-2.6.orig/drivers/mtd/ubi/scan.c 2007-05-17 15:06:33.000000000 +0200
+++ linux-2.6/drivers/mtd/ubi/scan.c 2007-05-17 15:16:07.000000000 +0200
@@ -121,9 +121,9 @@ static int validate_vid_hdr(const struct
const struct ubi_scan_volume *sv, int pnum)
{
int vol_type = vid_hdr->vol_type;
- int vol_id = ubi32_to_cpu(vid_hdr->vol_id);
- int used_ebs = ubi32_to_cpu(vid_hdr->used_ebs);
- int data_pad = ubi32_to_cpu(vid_hdr->data_pad);
+ int vol_id = be32_to_cpu(vid_hdr->vol_id);
+ int used_ebs = be32_to_cpu(vid_hdr->used_ebs);
+ int data_pad = be32_to_cpu(vid_hdr->data_pad);

if (sv->leb_count != 0) {
int sv_vol_type;
@@ -189,7 +189,7 @@ static struct ubi_scan_volume *add_volum
struct ubi_scan_volume *sv;
struct rb_node **p = &si->volumes.rb_node, *parent = NULL;

- ubi_assert(vol_id == ubi32_to_cpu(vid_hdr->vol_id));
+ ubi_assert(vol_id == be32_to_cpu(vid_hdr->vol_id));

/* Walk the volume RB-tree to look if this volume is already present */
while (*p) {
@@ -214,8 +214,8 @@ static struct ubi_scan_volume *add_volum
si->max_sqnum = 0;
sv->vol_id = vol_id;
sv->root = RB_ROOT;
- sv->used_ebs = ubi32_to_cpu(vid_hdr->used_ebs);
- sv->data_pad = ubi32_to_cpu(vid_hdr->data_pad);
+ sv->used_ebs = be32_to_cpu(vid_hdr->used_ebs);
+ sv->data_pad = be32_to_cpu(vid_hdr->data_pad);
sv->compat = vid_hdr->compat;
sv->vol_type = vid_hdr->vol_type == UBI_VID_DYNAMIC ? UBI_DYNAMIC_VOLUME
: UBI_STATIC_VOLUME;
@@ -257,10 +257,10 @@ static int compare_lebs(const struct ubi
int len, err, second_is_newer, bitflips = 0, corrupted = 0;
uint32_t data_crc, crc;
struct ubi_vid_hdr *vidh = NULL;
- unsigned long long sqnum2 = ubi64_to_cpu(vid_hdr->sqnum);
+ unsigned long long sqnum2 = be64_to_cpu(vid_hdr->sqnum);

if (seb->sqnum == 0 && sqnum2 == 0) {
- long long abs, v1 = seb->leb_ver, v2 = ubi32_to_cpu(vid_hdr->leb_ver);
+ long long abs, v1 = seb->leb_ver, v2 = be32_to_cpu(vid_hdr->leb_ver);

/*
* UBI constantly increases the logical eraseblock version
@@ -344,7 +344,7 @@ static int compare_lebs(const struct ubi

/* Read the data of the copy and check the CRC */

- len = ubi32_to_cpu(vid_hdr->data_size);
+ len = be32_to_cpu(vid_hdr->data_size);
buf = kmalloc(len, GFP_KERNEL);
if (!buf) {
err = -ENOMEM;
@@ -355,7 +355,7 @@ static int compare_lebs(const struct ubi
if (err && err != UBI_IO_BITFLIPS)
goto out_free_buf;

- data_crc = ubi32_to_cpu(vid_hdr->data_crc);
+ data_crc = be32_to_cpu(vid_hdr->data_crc);
crc = crc32(UBI_CRC32_INIT, buf, len);
if (crc != data_crc) {
dbg_bld("PEB %d CRC error: calculated %#08x, must be %#08x",
@@ -410,10 +410,10 @@ int ubi_scan_add_used(const struct ubi_d
struct ubi_scan_leb *seb;
struct rb_node **p, *parent = NULL;

- vol_id = ubi32_to_cpu(vid_hdr->vol_id);
- lnum = ubi32_to_cpu(vid_hdr->lnum);
- sqnum = ubi64_to_cpu(vid_hdr->sqnum);
- leb_ver = ubi32_to_cpu(vid_hdr->leb_ver);
+ vol_id = be32_to_cpu(vid_hdr->vol_id);
+ lnum = be32_to_cpu(vid_hdr->lnum);
+ sqnum = be64_to_cpu(vid_hdr->sqnum);
+ leb_ver = be32_to_cpu(vid_hdr->leb_ver);

dbg_bld("PEB %d, LEB %d:%d, EC %d, sqnum %llu, ver %u, bitflips %d",
pnum, vol_id, lnum, ec, sqnum, leb_ver, bitflips);
@@ -508,7 +508,7 @@ int ubi_scan_add_used(const struct ubi_d

if (sv->highest_lnum == lnum)
sv->last_data_size =
- ubi32_to_cpu(vid_hdr->data_size);
+ be32_to_cpu(vid_hdr->data_size);

return 0;
} else {
@@ -547,7 +547,7 @@ int ubi_scan_add_used(const struct ubi_d

if (sv->highest_lnum <= lnum) {
sv->highest_lnum = lnum;
- sv->last_data_size = ubi32_to_cpu(vid_hdr->data_size);
+ sv->last_data_size = be32_to_cpu(vid_hdr->data_size);
}

if (si->max_sqnum < sqnum)
@@ -674,7 +674,7 @@ int ubi_scan_erase_peb(const struct ubi_
return -EINVAL;
}

- ec_hdr->ec = cpu_to_ubi64(ec);
+ ec_hdr->ec = cpu_to_be64(ec);

err = ubi_io_sync_erase(ubi, pnum, 0);
if (err < 0)
@@ -806,7 +806,7 @@ static int process_eb(struct ubi_device
return -EINVAL;
}

- ec = ubi64_to_cpu(ech->ec);
+ ec = be64_to_cpu(ech->ec);
if (ec > UBI_MAX_ERASECOUNTER) {
/*
* Erase counter overflow. The EC headers have 64 bits
@@ -844,9 +844,9 @@ static int process_eb(struct ubi_device
goto adjust_mean_ec;
}

- vol_id = ubi32_to_cpu(vidh->vol_id);
+ vol_id = be32_to_cpu(vidh->vol_id);
if (vol_id > UBI_MAX_VOLUMES && vol_id != UBI_LAYOUT_VOL_ID) {
- int lnum = ubi32_to_cpu(vidh->lnum);
+ int lnum = be32_to_cpu(vidh->lnum);

/* Unsupported internal volume */
switch (vidh->compat) {
@@ -1249,12 +1249,12 @@ static int paranoid_check_si(const struc
goto bad_vid_hdr;
}

- if (seb->sqnum != ubi64_to_cpu(vidh->sqnum)) {
+ if (seb->sqnum != be64_to_cpu(vidh->sqnum)) {
ubi_err("bad sqnum %llu", seb->sqnum);
goto bad_vid_hdr;
}

- if (sv->vol_id != ubi32_to_cpu(vidh->vol_id)) {
+ if (sv->vol_id != be32_to_cpu(vidh->vol_id)) {
ubi_err("bad vol_id %d", sv->vol_id);
goto bad_vid_hdr;
}
@@ -1264,22 +1264,22 @@ static int paranoid_check_si(const struc
goto bad_vid_hdr;
}

- if (seb->lnum != ubi32_to_cpu(vidh->lnum)) {
+ if (seb->lnum != be32_to_cpu(vidh->lnum)) {
ubi_err("bad lnum %d", seb->lnum);
goto bad_vid_hdr;
}

- if (sv->used_ebs != ubi32_to_cpu(vidh->used_ebs)) {
+ if (sv->used_ebs != be32_to_cpu(vidh->used_ebs)) {
ubi_err("bad used_ebs %d", sv->used_ebs);
goto bad_vid_hdr;
}

- if (sv->data_pad != ubi32_to_cpu(vidh->data_pad)) {
+ if (sv->data_pad != be32_to_cpu(vidh->data_pad)) {
ubi_err("bad data_pad %d", sv->data_pad);
goto bad_vid_hdr;
}

- if (seb->leb_ver != ubi32_to_cpu(vidh->leb_ver)) {
+ if (seb->leb_ver != be32_to_cpu(vidh->leb_ver)) {
ubi_err("bad leb_ver %u", seb->leb_ver);
goto bad_vid_hdr;
}
@@ -1288,12 +1288,12 @@ static int paranoid_check_si(const struc
if (!last_seb)
continue;

- if (sv->highest_lnum != ubi32_to_cpu(vidh->lnum)) {
+ if (sv->highest_lnum != be32_to_cpu(vidh->lnum)) {
ubi_err("bad highest_lnum %d", sv->highest_lnum);
goto bad_vid_hdr;
}

- if (sv->last_data_size != ubi32_to_cpu(vidh->data_size)) {
+ if (sv->last_data_size != be32_to_cpu(vidh->data_size)) {
ubi_err("bad last_data_size %d", sv->last_data_size);
goto bad_vid_hdr;
}
Index: linux-2.6/drivers/mtd/ubi/vmt.c
===================================================================
--- linux-2.6.orig/drivers/mtd/ubi/vmt.c 2007-05-17 15:06:33.000000000 +0200
+++ linux-2.6/drivers/mtd/ubi/vmt.c 2007-05-17 15:18:23.000000000 +0200
@@ -320,10 +320,10 @@ int ubi_create_volume(struct ubi_device

/* Fill volume table record */
memset(&vtbl_rec, 0, sizeof(struct ubi_vtbl_record));
- vtbl_rec.reserved_pebs = cpu_to_ubi32(vol->reserved_pebs);
- vtbl_rec.alignment = cpu_to_ubi32(vol->alignment);
- vtbl_rec.data_pad = cpu_to_ubi32(vol->data_pad);
- vtbl_rec.name_len = cpu_to_ubi16(vol->name_len);
+ vtbl_rec.reserved_pebs = cpu_to_be32(vol->reserved_pebs);
+ vtbl_rec.alignment = cpu_to_be32(vol->alignment);
+ vtbl_rec.data_pad = cpu_to_be32(vol->data_pad);
+ vtbl_rec.name_len = cpu_to_be16(vol->name_len);
if (vol->vol_type == UBI_DYNAMIC_VOLUME)
vtbl_rec.vol_type = UBI_VID_DYNAMIC;
else
@@ -503,7 +503,7 @@ int ubi_resize_volume(struct ubi_volume_

/* Change volume table record */
memcpy(&vtbl_rec, &ubi->vtbl[vol_id], sizeof(struct ubi_vtbl_record));
- vtbl_rec.reserved_pebs = cpu_to_ubi32(reserved_pebs);
+ vtbl_rec.reserved_pebs = cpu_to_be32(reserved_pebs);
err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
if (err)
goto out_acc;
@@ -651,7 +651,7 @@ static void paranoid_check_volume(const
long long n;
const char *name;

- reserved_pebs = ubi32_to_cpu(ubi->vtbl[vol_id].reserved_pebs);
+ reserved_pebs = be32_to_cpu(ubi->vtbl[vol_id].reserved_pebs);

if (!vol) {
if (reserved_pebs) {
@@ -765,9 +765,9 @@ static void paranoid_check_volume(const
}
}

- alignment = ubi32_to_cpu(ubi->vtbl[vol_id].alignment);
- data_pad = ubi32_to_cpu(ubi->vtbl[vol_id].data_pad);
- name_len = ubi16_to_cpu(ubi->vtbl[vol_id].name_len);
+ alignment = be32_to_cpu(ubi->vtbl[vol_id].alignment);
+ data_pad = be32_to_cpu(ubi->vtbl[vol_id].data_pad);
+ name_len = be16_to_cpu(ubi->vtbl[vol_id].name_len);
upd_marker = ubi->vtbl[vol_id].upd_marker;
name = &ubi->vtbl[vol_id].name[0];
if (ubi->vtbl[vol_id].vol_type == UBI_VID_DYNAMIC)
Index: linux-2.6/drivers/mtd/ubi/vtbl.c
===================================================================
--- linux-2.6.orig/drivers/mtd/ubi/vtbl.c 2007-05-17 15:06:33.000000000 +0200
+++ linux-2.6/drivers/mtd/ubi/vtbl.c 2007-05-17 15:14:11.000000000 +0200
@@ -93,7 +93,7 @@ int ubi_change_vtbl_record(struct ubi_de
vtbl_rec = &empty_vtbl_record;
else {
crc = crc32(UBI_CRC32_INIT, vtbl_rec, UBI_VTBL_RECORD_SIZE_CRC);
- vtbl_rec->crc = cpu_to_ubi32(crc);
+ vtbl_rec->crc = cpu_to_be32(crc);
}

dbg_msg("change record %d", idx);
@@ -141,18 +141,18 @@ static int vtbl_check(const struct ubi_d
for (i = 0; i < ubi->vtbl_slots; i++) {
cond_resched();

- reserved_pebs = ubi32_to_cpu(vtbl[i].reserved_pebs);
- alignment = ubi32_to_cpu(vtbl[i].alignment);
- data_pad = ubi32_to_cpu(vtbl[i].data_pad);
+ reserved_pebs = be32_to_cpu(vtbl[i].reserved_pebs);
+ alignment = be32_to_cpu(vtbl[i].alignment);
+ data_pad = be32_to_cpu(vtbl[i].data_pad);
upd_marker = vtbl[i].upd_marker;
vol_type = vtbl[i].vol_type;
- name_len = ubi16_to_cpu(vtbl[i].name_len);
+ name_len = be16_to_cpu(vtbl[i].name_len);
name = &vtbl[i].name[0];

crc = crc32(UBI_CRC32_INIT, &vtbl[i], UBI_VTBL_RECORD_SIZE_CRC);
- if (ubi32_to_cpu(vtbl[i].crc) != crc) {
+ if (be32_to_cpu(vtbl[i].crc) != crc) {
ubi_err("bad CRC at record %u: %#08x, not %#08x",
- i, crc, ubi32_to_cpu(vtbl[i].crc));
+ i, crc, be32_to_cpu(vtbl[i].crc));
ubi_dbg_dump_vtbl_record(&vtbl[i], i);
return 1;
}
@@ -225,8 +225,8 @@ static int vtbl_check(const struct ubi_d
/* Checks that all names are unique */
for (i = 0; i < ubi->vtbl_slots - 1; i++) {
for (n = i + 1; n < ubi->vtbl_slots; n++) {
- int len1 = ubi16_to_cpu(vtbl[i].name_len);
- int len2 = ubi16_to_cpu(vtbl[n].name_len);
+ int len1 = be16_to_cpu(vtbl[i].name_len);
+ int len2 = be16_to_cpu(vtbl[n].name_len);

if (len1 > 0 && len1 == len2 &&
!strncmp(vtbl[i].name, vtbl[n].name, len1)) {
@@ -288,13 +288,13 @@ retry:
}

vid_hdr->vol_type = UBI_VID_DYNAMIC;
- vid_hdr->vol_id = cpu_to_ubi32(UBI_LAYOUT_VOL_ID);
+ vid_hdr->vol_id = cpu_to_be32(UBI_LAYOUT_VOL_ID);
vid_hdr->compat = UBI_LAYOUT_VOLUME_COMPAT;
vid_hdr->data_size = vid_hdr->used_ebs =
- vid_hdr->data_pad = cpu_to_ubi32(0);
- vid_hdr->lnum = cpu_to_ubi32(copy);
- vid_hdr->sqnum = cpu_to_ubi64(++si->max_sqnum);
- vid_hdr->leb_ver = cpu_to_ubi32(old_seb ? old_seb->leb_ver + 1: 0);
+ vid_hdr->data_pad = cpu_to_be32(0);
+ vid_hdr->lnum = cpu_to_be32(copy);
+ vid_hdr->sqnum = cpu_to_be64(++si->max_sqnum);
+ vid_hdr->leb_ver = cpu_to_be32(old_seb ? old_seb->leb_ver + 1: 0);

/* The EC header is already there, write the VID header */
err = ubi_io_write_vid_hdr(ubi, new_seb->pnum, vid_hdr);
@@ -500,19 +500,19 @@ static int init_volumes(struct ubi_devic
for (i = 0; i < ubi->vtbl_slots; i++) {
cond_resched();

- if (ubi32_to_cpu(vtbl[i].reserved_pebs) == 0)
+ if (be32_to_cpu(vtbl[i].reserved_pebs) == 0)
continue; /* Empty record */

vol = kzalloc(sizeof(struct ubi_volume), GFP_KERNEL);
if (!vol)
return -ENOMEM;

- vol->reserved_pebs = ubi32_to_cpu(vtbl[i].reserved_pebs);
- vol->alignment = ubi32_to_cpu(vtbl[i].alignment);
- vol->data_pad = ubi32_to_cpu(vtbl[i].data_pad);
+ vol->reserved_pebs = be32_to_cpu(vtbl[i].reserved_pebs);
+ vol->alignment = be32_to_cpu(vtbl[i].alignment);
+ vol->data_pad = be32_to_cpu(vtbl[i].data_pad);
vol->vol_type = vtbl[i].vol_type == UBI_VID_DYNAMIC ?
UBI_DYNAMIC_VOLUME : UBI_STATIC_VOLUME;
- vol->name_len = ubi16_to_cpu(vtbl[i].name_len);
+ vol->name_len = be16_to_cpu(vtbl[i].name_len);
vol->usable_leb_size = ubi->leb_size - vol->data_pad;
memcpy(vol->name, vtbl[i].name, vol->name_len);
vol->name[vol->name_len] = '\0';
@@ -718,7 +718,7 @@ int ubi_read_volume_table(struct ubi_dev
int i, err;
struct ubi_scan_volume *sv;

- empty_vtbl_record.crc = cpu_to_ubi32(0xf116c36b);
+ empty_vtbl_record.crc = cpu_to_be32(0xf116c36b);

/*
* The number of supported volumes is limited by the eraseblock size
Index: linux-2.6/include/mtd/ubi-header.h
===================================================================
--- linux-2.6.orig/include/mtd/ubi-header.h 2007-05-17 15:09:40.000000000 +0200
+++ linux-2.6/include/mtd/ubi-header.h 2007-05-17 15:12:20.000000000 +0200
@@ -74,42 +74,13 @@ enum {
UBI_COMPAT_REJECT = 5
};

-/*
- * ubi16_t/ubi32_t/ubi64_t - 16, 32, and 64-bit integers used in UBI on-flash
- * data structures.
- */
-typedef struct {
- uint16_t int16;
-} __attribute__ ((packed)) ubi16_t;
-
-typedef struct {
- uint32_t int32;
-} __attribute__ ((packed)) ubi32_t;
-
-typedef struct {
- uint64_t int64;
-} __attribute__ ((packed)) ubi64_t;
-
-/*
- * In this implementation of UBI uses the big-endian format for on-flash
- * integers. The below are the corresponding conversion macros.
- */
-#define cpu_to_ubi16(x) ((ubi16_t){__cpu_to_be16(x)})
-#define ubi16_to_cpu(x) ((uint16_t)__be16_to_cpu((x).int16))
-
-#define cpu_to_ubi32(x) ((ubi32_t){__cpu_to_be32(x)})
-#define ubi32_to_cpu(x) ((uint32_t)__be32_to_cpu((x).int32))
-
-#define cpu_to_ubi64(x) ((ubi64_t){__cpu_to_be64(x)})
-#define ubi64_to_cpu(x) ((uint64_t)__be64_to_cpu((x).int64))
-
/* Sizes of UBI headers */
#define UBI_EC_HDR_SIZE sizeof(struct ubi_ec_hdr)
#define UBI_VID_HDR_SIZE sizeof(struct ubi_vid_hdr)

/* Sizes of UBI headers without the ending CRC */
-#define UBI_EC_HDR_SIZE_CRC (UBI_EC_HDR_SIZE - sizeof(ubi32_t))
-#define UBI_VID_HDR_SIZE_CRC (UBI_VID_HDR_SIZE - sizeof(ubi32_t))
+#define UBI_EC_HDR_SIZE_CRC (UBI_EC_HDR_SIZE - sizeof(__be32))
+#define UBI_VID_HDR_SIZE_CRC (UBI_VID_HDR_SIZE - sizeof(__be32))

/**
* struct ubi_ec_hdr - UBI erase counter header.
@@ -137,14 +108,14 @@ typedef struct {
* eraseblocks.
*/
struct ubi_ec_hdr {
- ubi32_t magic;
- uint8_t version;
- uint8_t padding1[3];
- ubi64_t ec; /* Warning: the current limit is 31-bit anyway! */
- ubi32_t vid_hdr_offset;
- ubi32_t data_offset;
- uint8_t padding2[36];
- ubi32_t hdr_crc;
+ __be32 magic;
+ __u8 version;
+ __u8 padding1[3];
+ __be64 ec; /* Warning: the current limit is 31-bit anyway! */
+ __be32 vid_hdr_offset;
+ __be32 data_offset;
+ __u8 padding2[36];
+ __be32 hdr_crc;
} __attribute__ ((packed));

/**
@@ -262,22 +233,22 @@ struct ubi_ec_hdr {
* software (say, cramfs) on top of the UBI volume.
*/
struct ubi_vid_hdr {
- ubi32_t magic;
- uint8_t version;
- uint8_t vol_type;
- uint8_t copy_flag;
- uint8_t compat;
- ubi32_t vol_id;
- ubi32_t lnum;
- ubi32_t leb_ver; /* obsolete, to be removed, don't use */
- ubi32_t data_size;
- ubi32_t used_ebs;
- ubi32_t data_pad;
- ubi32_t data_crc;
- uint8_t padding1[4];
- ubi64_t sqnum;
- uint8_t padding2[12];
- ubi32_t hdr_crc;
+ __be32 magic;
+ __u8 version;
+ __u8 vol_type;
+ __u8 copy_flag;
+ __u8 compat;
+ __be32 vol_id;
+ __be32 lnum;
+ __be32 leb_ver; /* obsolete, to be removed, don't use */
+ __be32 data_size;
+ __be32 used_ebs;
+ __be32 data_pad;
+ __be32 data_crc;
+ __u8 padding1[4];
+ __be64 sqnum;
+ __u8 padding2[12];
+ __be32 hdr_crc;
} __attribute__ ((packed));

/* Internal UBI volumes count */
@@ -306,7 +277,7 @@ struct ubi_vid_hdr {
#define UBI_VTBL_RECORD_SIZE sizeof(struct ubi_vtbl_record)

/* Size of the volume table record without the ending CRC */
-#define UBI_VTBL_RECORD_SIZE_CRC (UBI_VTBL_RECORD_SIZE - sizeof(ubi32_t))
+#define UBI_VTBL_RECORD_SIZE_CRC (UBI_VTBL_RECORD_SIZE - sizeof(__be32))

/**
* struct ubi_vtbl_record - a record in the volume table.
@@ -346,15 +317,15 @@ struct ubi_vid_hdr {
* Empty records contain all zeroes and the CRC checksum of those zeroes.
*/
struct ubi_vtbl_record {
- ubi32_t reserved_pebs;
- ubi32_t alignment;
- ubi32_t data_pad;
- uint8_t vol_type;
- uint8_t upd_marker;
- ubi16_t name_len;
- uint8_t name[UBI_VOL_NAME_MAX+1];
- uint8_t padding2[24];
- ubi32_t crc;
+ __be32 reserved_pebs;
+ __be32 alignment;
+ __be32 data_pad;
+ __u8 vol_type;
+ __u8 upd_marker;
+ __be16 name_len;
+ __u8 name[UBI_VOL_NAME_MAX+1];
+ __u8 padding2[24];
+ __be32 crc;
} __attribute__ ((packed));

#endif /* !__UBI_HEADER_H__ */
Index: linux-2.6/drivers/mtd/ubi/wl.c
===================================================================
--- linux-2.6.orig/drivers/mtd/ubi/wl.c 2007-05-17 15:15:27.000000000 +0200
+++ linux-2.6/drivers/mtd/ubi/wl.c 2007-05-17 15:15:42.000000000 +0200
@@ -667,7 +667,7 @@ static int sync_erase(struct ubi_device

dbg_wl("erased PEB %d, new EC %llu", e->pnum, ec);

- ec_hdr->ec = cpu_to_ubi64(ec);
+ ec_hdr->ec = cpu_to_be64(ec);

err = ubi_io_write_ec_hdr(ubi, e->pnum, ec_hdr);
if (err)
@@ -1633,7 +1633,7 @@ static int paranoid_check_ec(const struc
goto out_free;
}

- read_ec = ubi64_to_cpu(ec_hdr->ec);
+ read_ec = be64_to_cpu(ec_hdr->ec);
if (ec != read_ec) {
ubi_err("paranoid check failed for PEB %d", pnum);
ubi_err("read EC is %lld, should be %d", read_ec, ec);


2007-05-17 14:51:47

by Artem Bityutskiy

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

Christoph,

On Thu, 2007-05-17 at 16:32 +0200, Christoph Hellwig wrote:
> Kill ubis homegrown endianess handling crap and replace it with
> the normal kernel endianess handling.

Err,__be32 and the company are just sparse things, while I have compiler
checks with my struct ubi32_t and friends. JFFS2 also uses the same
technique. Why do you force me to rely on sparse instead instead of
compiler?

Well, I see the good side of your change - no home-brewed media<->cpu
things. Fair enough and nice. But why don't you make __be32 a struct
(just like I do) so that compiler could complain then?

--
Best regards,
Artem Bityutskiy (Битюцкий Артём)

2007-05-17 14:57:44

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Thu, May 17, 2007 at 05:50:43PM +0300, Artem Bityutskiy wrote:
> Christoph,
>
> On Thu, 2007-05-17 at 16:32 +0200, Christoph Hellwig wrote:
> > Kill ubis homegrown endianess handling crap and replace it with
> > the normal kernel endianess handling.
>
> Err,__be32 and the company are just sparse things, while I have compiler
> checks with my struct ubi32_t and friends. JFFS2 also uses the same
> technique. Why do you force me to rely on sparse instead instead of
> compiler?

Yes. Like all other code in the kernel aswell.

2007-05-17 15:10:44

by Artem Bityutskiy

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Thu, 2007-05-17 at 16:56 +0200, Christoph Hellwig wrote:
> On Thu, May 17, 2007 at 05:50:43PM +0300, Artem Bityutskiy wrote:
> > Christoph,
> >
> > On Thu, 2007-05-17 at 16:32 +0200, Christoph Hellwig wrote:
> > > Kill ubis homegrown endianess handling crap and replace it with
> > > the normal kernel endianess handling.
> >
> > Err,__be32 and the company are just sparse things, while I have compiler
> > checks with my struct ubi32_t and friends. JFFS2 also uses the same
> > technique. Why do you force me to rely on sparse instead instead of
> > compiler?
>
> Yes. Like all other code in the kernel aswell.

Andrew, may I please have your ack that I absolutely have to use __be32
instead of my own types since Christoph tends to provide no explanation
to his requests.

--
Best regards,
Artem Bityutskiy (Битюцкий Артём)

2007-05-17 15:51:16

by David Woodhouse

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Thu, 2007-05-17 at 16:32 +0200, Christoph Hellwig wrote:
> Kill ubis homegrown endianess handling crap and replace it with
> the normal kernel endianess handling.

NAK. The 'normal' kernel stuff doesn't work in GCC; only in sparse.

If you want to go removing the ones which _do_ work in GCC, then fix the
'normal' one first. _Then_ go about converting others over to it.

--
dwmw2

2007-05-17 17:34:20

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Thu, 17 May 2007 18:09:50 +0300 Artem Bityutskiy <[email protected]> wrote:

> On Thu, 2007-05-17 at 16:56 +0200, Christoph Hellwig wrote:
> > On Thu, May 17, 2007 at 05:50:43PM +0300, Artem Bityutskiy wrote:
> > > Christoph,
> > >
> > > On Thu, 2007-05-17 at 16:32 +0200, Christoph Hellwig wrote:
> > > > Kill ubis homegrown endianess handling crap and replace it with
> > > > the normal kernel endianess handling.
> > >
> > > Err,__be32 and the company are just sparse things, while I have compiler
> > > checks with my struct ubi32_t and friends. JFFS2 also uses the same
> > > technique. Why do you force me to rely on sparse instead instead of
> > > compiler?
> >
> > Yes. Like all other code in the kernel aswell.
>
> Andrew, may I please have your ack that I absolutely have to use __be32
> instead of my own types since Christoph tends to provide no explanation
> to his requests.

umm.. I'd say what you've done in there is an improvement to the exiting
stuff: getting gcc to check it is better than having to use sparse.

I'd have expected gcc to generate poorer code with your approach but I'm
showing zero text size changes from Christoph's patch (gcc-4.1 and
gcc-3.4.5).

So I wouldn't be averse to creating a new, generic, kernel-wide alternative
to the existing __be32/__le32/etc code. It is an improvement.

But I don't think we want driver-private implementations.



We could conceivably simply switch the existing stuff to use structs, but
quite a lot of code assumes that cpu_to_foo32(0) == 0 and just does
open-coded assigments of zero. They'd need fixups.

2007-05-17 17:54:05

by Artem Bityutskiy

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Thu, 2007-05-17 at 10:29 -0700, Andrew Morton wrote:
> umm.. I'd say what you've done in there is an improvement to the exiting
> stuff: getting gcc to check it is better than having to use sparse.
>
> I'd have expected gcc to generate poorer code with your approach but I'm
> showing zero text size changes from Christoph's patch (gcc-4.1 and
> gcc-3.4.5).
>
> So I wouldn't be averse to creating a new, generic, kernel-wide alternative
> to the existing __be32/__le32/etc code. It is an improvement.
>
> We could conceivably simply switch the existing stuff to use structs, but
> quite a lot of code assumes that cpu_to_foo32(0) == 0 and just does
> open-coded assigments of zero. They'd need fixups.

Andrew,

thanks for answer. I personally do not think this should be applied
before we have better __be32 and friends. Thus, if I can do so, I will
just sit and wait for your decision - whether you include this patch to
-mm or not :-) .

--
Best regards,
Artem Bityutskiy (Битюцкий Артём)

2007-05-17 18:13:20

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Thu, May 17, 2007 at 11:50:54PM +0800, David Woodhouse wrote:
> On Thu, 2007-05-17 at 16:32 +0200, Christoph Hellwig wrote:
> > Kill ubis homegrown endianess handling crap and replace it with
> > the normal kernel endianess handling.
>
> NAK. The 'normal' kernel stuff doesn't work in GCC; only in sparse.
>
> If you want to go removing the ones which _do_ work in GCC, then fix the
> 'normal' one first. _Then_ go about converting others over to it.

Nope. gcc checking is crap and we need to run sparse anyway. It's what
everyone in the kernel use so it's perfect for some random code almost
no one uses aswell.

2007-05-17 18:20:50

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Thu, 17 May 2007 20:46:46 +0300
Artem Bityutskiy <[email protected]> wrote:

> On Thu, 2007-05-17 at 10:29 -0700, Andrew Morton wrote:
> > umm.. I'd say what you've done in there is an improvement to the exiting
> > stuff: getting gcc to check it is better than having to use sparse.
> >
> > I'd have expected gcc to generate poorer code with your approach but I'm
> > showing zero text size changes from Christoph's patch (gcc-4.1 and
> > gcc-3.4.5).
> >
> > So I wouldn't be averse to creating a new, generic, kernel-wide alternative
> > to the existing __be32/__le32/etc code. It is an improvement.
> >
> > We could conceivably simply switch the existing stuff to use structs, but
> > quite a lot of code assumes that cpu_to_foo32(0) == 0 and just does
> > open-coded assigments of zero. They'd need fixups.
>
> Andrew,
>
> thanks for answer. I personally do not think this should be applied
> before we have better __be32 and friends. Thus, if I can do so, I will
> just sit and wait for your decision - whether you include this patch to
> -mm or not :-) .
>

Drat, and here was I hoping I'd lured you into implementing the generic
code.

2007-05-17 18:22:25

by Sam Ravnborg

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Thu, May 17, 2007 at 08:12:23PM +0200, Christoph Hellwig wrote:
> On Thu, May 17, 2007 at 11:50:54PM +0800, David Woodhouse wrote:
> > On Thu, 2007-05-17 at 16:32 +0200, Christoph Hellwig wrote:
> > > Kill ubis homegrown endianess handling crap and replace it with
> > > the normal kernel endianess handling.
> >
> > NAK. The 'normal' kernel stuff doesn't work in GCC; only in sparse.
> >
> > If you want to go removing the ones which _do_ work in GCC, then fix the
> > 'normal' one first. _Then_ go about converting others over to it.
>
> Nope. gcc checking is crap and we need to run sparse anyway. It's what
> everyone in the kernel use so it's perfect for some random code almost
> no one uses aswell.

Care to explain what is wrong with the gcc checks as used by UBI?
Would be nice to know before someone start to migrate current
stuff so gcc can check for correct endian.

Sam

2007-05-17 18:36:37

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Thu, May 17, 2007 at 08:23:14PM +0200, Sam Ravnborg wrote:
> On Thu, May 17, 2007 at 08:12:23PM +0200, Christoph Hellwig wrote:
> > On Thu, May 17, 2007 at 11:50:54PM +0800, David Woodhouse wrote:
> > > On Thu, 2007-05-17 at 16:32 +0200, Christoph Hellwig wrote:
> > > > Kill ubis homegrown endianess handling crap and replace it with
> > > > the normal kernel endianess handling.
> > >
> > > NAK. The 'normal' kernel stuff doesn't work in GCC; only in sparse.
> > >
> > > If you want to go removing the ones which _do_ work in GCC, then fix the
> > > 'normal' one first. _Then_ go about converting others over to it.
> >
> > Nope. gcc checking is crap and we need to run sparse anyway. It's what
> > everyone in the kernel use so it's perfect for some random code almost
> > no one uses aswell.
>
> Care to explain what is wrong with the gcc checks as used by UBI?
> Would be nice to know before someone start to migrate current
> stuff so gcc can check for correct endian.

The major wrong thing is that it makes a little subsysttem artifically
different from the rest of the kernel.

At a technical level it overdoing things. The attribute syntax is perfecltly
find to address endianess issues without introducing wrapper structs the
lead to horrible code generation in some situations (e.g. trying to return
such a value)

2007-05-17 20:19:03

by Jeremy Fitzhardinge

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

Christoph Hellwig wrote:
> The attribute syntax is perfecltly
> find to address endianess issues without introducing wrapper structs the
> lead to horrible code generation in some situations (e.g. trying to return
> such a value)

Small structs are returned in register; it is indistinguishable from
returning a scalar.

J

2007-05-17 20:27:45

by matthieu castet

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Thu, 17 May 2007 16:32:01 +0200, Christoph Hellwig wrote:

> Kill ubis homegrown endianess handling crap and replace it with the
> normal kernel endianess handling.
>
Hum, you should check about alignment stuff.
Jffs2 use a similar mechanism and the packed struct also take care of
some unaligned data (present in summary node for example).

Matthieu

2007-05-17 20:32:36

by Artem Bityutskiy

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Thu, 17 May 2007, Andrew Morton wrote:
> Drat, and here was I hoping I'd lured you into implementing the generic
> code.

Well, I am really happy to contribute, but I am not a generic janitor like
Cristoph, who (amaizingly) knows many differet kernel subsystems. I am
a specific developer and I would rather concentrate on the Flash file
system I am writing, and this will be my later contribution.

Artem.

2007-05-17 20:35:25

by matthieu castet

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Thu, 17 May 2007 10:29:31 -0700, Andrew Morton wrote:

> On Thu, 17 May 2007 18:09:50 +0300 Artem Bityutskiy
> <[email protected]> wrote:
>
> umm.. I'd say what you've done in there is an improvement to the
> exiting stuff: getting gcc to check it is better than having to use
> sparse.
>
> I'd have expected gcc to generate poorer code with your approach but I'm
> showing zero text size changes from Christoph's patch (gcc-4.1 and
> gcc-3.4.5).
>
>
On which arch did you try ?
X86 where unaligned access are ok ?

On arch that don't support aligned access, packed struct access will be
done byte per byte (but it could be the expected behavior if there
unaligned access).

Matthieu

2007-05-17 20:42:51

by Al Viro

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Thu, May 17, 2007 at 10:29:31AM -0700, Andrew Morton wrote:
> On Thu, 17 May 2007 18:09:50 +0300 Artem Bityutskiy <[email protected]> wrote:
>
> > On Thu, 2007-05-17 at 16:56 +0200, Christoph Hellwig wrote:
> > > On Thu, May 17, 2007 at 05:50:43PM +0300, Artem Bityutskiy wrote:
> > > > Christoph,
> > > >
> > > > On Thu, 2007-05-17 at 16:32 +0200, Christoph Hellwig wrote:
> > > > > Kill ubis homegrown endianess handling crap and replace it with
> > > > > the normal kernel endianess handling.
> > > >
> > > > Err,__be32 and the company are just sparse things, while I have compiler
> > > > checks with my struct ubi32_t and friends. JFFS2 also uses the same
> > > > technique. Why do you force me to rely on sparse instead instead of
> > > > compiler?
> > >
> > > Yes. Like all other code in the kernel aswell.
> >
> > Andrew, may I please have your ack that I absolutely have to use __be32
> > instead of my own types since Christoph tends to provide no explanation
> > to his requests.
>
> umm.. I'd say what you've done in there is an improvement to the exiting
> stuff: getting gcc to check it is better than having to use sparse.

Ahem... So what does
x |= y;
turns into with that approach?

2007-05-17 20:53:51

by Al Viro

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

> Ahem... So what does
> x |= y;
> turns into with that approach?

BTW, you can simply typedef __be16 ubi16_t; etc. and define conversion
functions as cpu_to_ubi16(x) being (__force ubi16_t)cpu_to_be16(x), etc.

sparse will do all checks just fine, you still have bitwise operations
(might or might be not relevant in your case) and for gcc it simply
becomes __be16, etc - i.e. an integer type.

2007-05-17 20:56:31

by David Miller

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

From: Artem Bityutskiy <[email protected]>
Date: Thu, 17 May 2007 17:50:43 +0300

> Well, I see the good side of your change - no home-brewed media<->cpu
> things. Fair enough and nice. But why don't you make __be32 a struct
> (just like I do) so that compiler could complain then?

structs get passed on the stack instead of via registers, regardless
of size, when passed as arguments on some architectures, so there is a
terrible performance cost of doing things that way

2007-05-17 21:03:31

by Al Viro

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Thu, May 17, 2007 at 01:56:24PM -0700, David Miller wrote:
> From: Artem Bityutskiy <[email protected]>
> Date: Thu, 17 May 2007 17:50:43 +0300
>
> > Well, I see the good side of your change - no home-brewed media<->cpu
> > things. Fair enough and nice. But why don't you make __be32 a struct
> > (just like I do) so that compiler could complain then?
>
> structs get passed on the stack instead of via registers, regardless
> of size, when passed as arguments on some architectures, so there is a
> terrible performance cost of doing things that way

BTW, the lack of home-grown coversions is not a benefit - it's _nice_ to
have protections against mixing be32 and ubi32, etc. Avoiding the mess
with struct, OTOH, *is* a benefit.

So I'd rather go with independent bitwise types and conversions done by
use of be... ones + force-cast. The rest of ubi code remain unchanged.

2007-05-17 21:14:37

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On 5/17/07, Al Viro <[email protected]> wrote:
>
> Ahem... So what does
> x |= y;
> turns into with that approach?

Do we want to do such kind of operations on endian-annotated data? I'd
imagine you want to convert ot host-endianess first anyway.

--
Dmitry

2007-05-17 21:26:56

by Al Viro

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Thu, May 17, 2007 at 09:42:34PM +0100, Al Viro wrote:
> Ahem... So what does
> x |= y;
> turns into with that approach?

Another case is

#define FLAG1 cpu_to_be32(2)
#define FLAG2 cpu_to_be32(0x400)

if (packet_header->field & (FLAG1 | FLAG2))
....

which is a bloody common idiom in net/* and it happens on some pretty hot
paths. Approaches that would require converting it to something like
if (be32_to_cpu(packet_header->field) & (FLAG1 | FLAG2))
would be not just obnoxious, they would actually generate worse code.

2007-05-17 21:29:28

by Al Viro

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Thu, May 17, 2007 at 05:14:26PM -0400, Dmitry Torokhov wrote:
> On 5/17/07, Al Viro <[email protected]> wrote:
> >
> >Ahem... So what does
> > x |= y;
> >turns into with that approach?
>
> Do we want to do such kind of operations on endian-annotated data? I'd
> imagine you want to convert ot host-endianess first anyway.

Why? When both x and y are of the same type, it's a perfectly sane and
safe operation. And yes, sparse checks handle that.

2007-05-17 21:33:40

by David Miller

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

From: "Dmitry Torokhov" <[email protected]>
Date: Thu, 17 May 2007 17:14:26 -0400

> On 5/17/07, Al Viro <[email protected]> wrote:
> >
> > Ahem... So what does
> > x |= y;
> > turns into with that approach?
>
> Do we want to do such kind of operations on endian-annotated data? I'd
> imagine you want to convert ot host-endianess first anyway.

Generally you don't, if 'x' and 'y' are both in the needed
endinaness already, there is no reason to convert anything.

2007-05-17 21:47:33

by Al Viro

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Thu, May 17, 2007 at 02:33:34PM -0700, David Miller wrote:
> From: "Dmitry Torokhov" <[email protected]>
> Date: Thu, 17 May 2007 17:14:26 -0400
>
> > On 5/17/07, Al Viro <[email protected]> wrote:
> > >
> > > Ahem... So what does
> > > x |= y;
> > > turns into with that approach?
> >
> > Do we want to do such kind of operations on endian-annotated data? I'd
> > imagine you want to convert ot host-endianess first anyway.
>
> Generally you don't, if 'x' and 'y' are both in the needed
> endinaness already, there is no reason to convert anything.

BTW, if you have two independently defined bitwise types, sparse
will complain about mixing them, so you still have protection against
mixing unrelated types that happen to have the same endianness.

Folks, just doing annotations of net/* had been large enough and it
mostly had been about annotating declarations. If we have to rewrite
every sodding place where we happen to do bitwise operations on those...
Forget about it. BTW, another fun kind of places is comparing for
equality - also adds a fsckload of lines to rewrite^Wobscure.

2007-05-18 02:39:31

by David Woodhouse

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Thu, 2007-05-17 at 20:30 +0000, Matthieu CASTET wrote:
> On Thu, 17 May 2007 10:29:31 -0700, Andrew Morton wrote:
>
> > On Thu, 17 May 2007 18:09:50 +0300 Artem Bityutskiy
> > <[email protected]> wrote:
> >
> > umm.. I'd say what you've done in there is an improvement to the
> > exiting stuff: getting gcc to check it is better than having to use
> > sparse.
> >
> > I'd have expected gcc to generate poorer code with your approach but I'm
> > showing zero text size changes from Christoph's patch (gcc-4.1 and
> > gcc-3.4.5).
> >
> >
> On which arch did you try ?
> X86 where unaligned access are ok ?
>
> On arch that don't support aligned access, packed struct access will be
> done byte per byte (but it could be the expected behavior if there
> unaligned access).

When I tested this on ARM, the output for je32_to_cpu et al was fine.
For _other_ structures where I'd used __attribute__((packed)) to be
safe, gcc would emit code to handle unaligned loads. But not in the
simple case where the struct has only one member.

Are you suggesting that this has changed since I did my testing?

--
dwmw2

2007-05-18 02:58:10

by John Anthony Kazos Jr.

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Fri, 18 May 2007, David Woodhouse wrote:
> On Thu, 2007-05-17 at 20:30 +0000, Matthieu CASTET wrote:
> > On Thu, 17 May 2007 10:29:31 -0700, Andrew Morton wrote:
> >
> > > On Thu, 17 May 2007 18:09:50 +0300 Artem Bityutskiy
> > > <[email protected]> wrote:
> > >
> > > umm.. I'd say what you've done in there is an improvement to the
> > > exiting stuff: getting gcc to check it is better than having to use
> > > sparse.
> > >
> > > I'd have expected gcc to generate poorer code with your approach but I'm
> > > showing zero text size changes from Christoph's patch (gcc-4.1 and
> > > gcc-3.4.5).
> > >
> > >
> > On which arch did you try ?
> > X86 where unaligned access are ok ?
> >
> > On arch that don't support aligned access, packed struct access will be
> > done byte per byte (but it could be the expected behavior if there
> > unaligned access).
>
> When I tested this on ARM, the output for je32_to_cpu et al was fine.
> For _other_ structures where I'd used __attribute__((packed)) to be
> safe, gcc would emit code to handle unaligned loads. But not in the
> simple case where the struct has only one member.
>
> Are you suggesting that this has changed since I did my testing?

Wouldn't the appropriate test be to demonstrate that the same program text
opcodes are generated in both cases for all architectures? If that's not
the case, even if the generation isn't -worse-, it shows that the compiler
is doing different things with each, which means different versions of the
compiler could do different things with it, and all of a sudden another
nice programming construct which helps compile-time issues ends up
increasing the number of cases where compiler differences generate faster
or slower kernels with the same code, whereas in the test cases it was "no
better, no worse" so deemed fine.

2007-05-18 03:18:16

by David Woodhouse

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Thu, 2007-05-17 at 22:57 -0400, John Anthony Kazos Jr. wrote:
> Wouldn't the appropriate test be to demonstrate that the same program text
> opcodes are generated in both cases for all architectures?

No, empirical testing with the compiler is never the _correct_ thing to
do. It's just expedient.

> If that's not the case, even if the generation isn't -worse-, it shows
> that the compiler is doing different things with each, which means
> different versions of the compiler could do different things with it,

Well yes, but even it _is_ generating precisely the same output today,
there's no reason why the compiler shouldn't behave differently under a
different phase of the moon.

The _correct_ thing to do is act upon my mutterings at the time I
removed the '__attribute__((packed))' from various JFFS2 structures to
improve the generated code on ARM -- actually implement an attribute for
GCC which has the same "don't insert any padding" meaning, but without
the unwanted "assume arbitrary alignment" implications.

It'd actually be nice if GCC knew about endianness too. I don't want to
have to do:

*x = le32_to_cpu(cpu_to_le32(*x) + 5);

I just want

uint32_t __attribute__((littleendian)) *x;

*x += 5;

I know we can hack around it for masks, with '*x |= cpu_to_le32(X_BAR);'
and such like, and we can load it into local native-endian variables and
then copy it back again later -- but it's better just to let the
compiler know what's going on and do its own optimisation. Especially on
architectures which have 'load-and-swap' or 'store-and-swap'
instructions.

--
dwmw2

2007-05-18 07:00:06

by Artem Bityutskiy

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

Al Viro wrote:
> BTW, you can simply typedef __be16 ubi16_t; etc. and define conversion
> functions as cpu_to_ubi16(x) being (__force ubi16_t)cpu_to_be16(x), etc.
>
> sparse will do all checks just fine, you still have bitwise operations
> (might or might be not relevant in your case) and for gcc it simply
> becomes __be16, etc - i.e. an integer type.

Err, what is the benefit of it? If we relied on sparce, why not would we be
just using __be16 directly?

--
Best Regards,
Artem Bityutskiy (Артём Битюцкий)

2007-05-18 08:39:26

by Al Viro

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Fri, May 18, 2007 at 09:58:25AM +0300, Artem Bityutskiy wrote:
> Al Viro wrote:
> >BTW, you can simply typedef __be16 ubi16_t; etc. and define conversion
> >functions as cpu_to_ubi16(x) being (__force ubi16_t)cpu_to_be16(x), etc.
> >
> >sparse will do all checks just fine, you still have bitwise operations
> >(might or might be not relevant in your case) and for gcc it simply
> >becomes __be16, etc - i.e. an integer type.
>
> Err, what is the benefit of it? If we relied on sparce, why not would we be
> just using __be16 directly?

Because you might legitimately want your type to be *not* mixed with whatever
other big-endian 16bit types you have out there?

2007-05-18 11:53:16

by John Anthony Kazos Jr.

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Fri, 18 May 2007, David Woodhouse wrote:
> On Thu, 2007-05-17 at 22:57 -0400, John Anthony Kazos Jr. wrote:
> > Wouldn't the appropriate test be to demonstrate that the same program text
> > opcodes are generated in both cases for all architectures?
>
> No, empirical testing with the compiler is never the _correct_ thing to
> do. It's just expedient.
>
> > If that's not the case, even if the generation isn't -worse-, it shows
> > that the compiler is doing different things with each, which means
> > different versions of the compiler could do different things with it,
>
> Well yes, but even it _is_ generating precisely the same output today,
> there's no reason why the compiler shouldn't behave differently under a
> different phase of the moon.
>
> The _correct_ thing to do is act upon my mutterings at the time I
> removed the '__attribute__((packed))' from various JFFS2 structures to
> improve the generated code on ARM -- actually implement an attribute for
> GCC which has the same "don't insert any padding" meaning, but without
> the unwanted "assume arbitrary alignment" implications.

Out of curiosity, why would a compiler ever insert padding in a structure
that has all its elements properly-aligned?

> It'd actually be nice if GCC knew about endianness too. I don't want to
> have to do:
>
> *x = le32_to_cpu(cpu_to_le32(*x) + 5);
>
> I just want
>
> uint32_t __attribute__((littleendian)) *x;
>
> *x += 5;
>
> I know we can hack around it for masks, with '*x |= cpu_to_le32(X_BAR);'
> and such like, and we can load it into local native-endian variables and
> then copy it back again later -- but it's better just to let the
> compiler know what's going on and do its own optimisation. Especially on
> architectures which have 'load-and-swap' or 'store-and-swap'
> instructions.

2007-05-18 14:52:49

by David Woodhouse

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Fri, 2007-05-18 at 07:52 -0400, John Anthony Kazos Jr. wrote:
> Out of curiosity, why would a compiler ever insert padding in a structure
> that has all its elements properly-aligned?

Well, it might decide it would be nicer if some elements were aligned to
64 bits. Or to a cache line. Or something. I don't care about _why_ --
the point is that it's _allowed_ to. Hence the original use of
__attribute__((packed)).

In practice, there's no real reason why it would do such a thing, which
is why I removed the packed attribute and replaced it with a runtime
check on the size of the structures in question.

--
dwmw2

2007-05-18 19:55:21

by matthieu castet

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

David Woodhouse wrote:
> On Thu, 2007-05-17 at 20:30 +0000, Matthieu CASTET wrote:
>> On Thu, 17 May 2007 10:29:31 -0700, Andrew Morton wrote:
>>
>>> On Thu, 17 May 2007 18:09:50 +0300 Artem Bityutskiy
> When I tested this on ARM, the output for je32_to_cpu et al was fine.
> For _other_ structures where I'd used __attribute__((packed)) to be
> safe, gcc would emit code to handle unaligned loads. But not in the
> simple case where the struct has only one member.
I don't think it is true.

When porting some summary stuff to bootloader, I hit some unaligned
access problem :
in summary.c:405 there is a
switch (je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype)) {
and
struct jffs2_sum_unknown_flash
{
jint16_t nodetype; /* node type */
};

note that sp isn't aligned to a 32 bits boundary (it can be anything and
depend for example of the size of the dirent name).

if gcc doesn't emit code to handle unaligned loads in this case, there
is unaligned access.

When compiling my code for arm, I use a gcc-4.1.1 with a bug and it
break. With another compiler (last gcc from codesourcery) it worked
(because gcc emit load it bit per bit).


>
> Are you suggesting that this has changed since I did my testing?
>
Which version of gcc did you try ?

Matthieu

2007-05-18 20:30:33

by matthieu castet

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

Hi,

David Woodhouse wrote:
> On Thu, 2007-05-17 at 20:30 +0000, Matthieu CASTET wrote:
>> On arch that don't support aligned access, packed struct access will be
>> done byte per byte (but it could be the expected behavior if there
>> unaligned access).
>
> When I tested this on ARM, the output for je32_to_cpu et al was fine.
> For _other_ structures where I'd used __attribute__((packed)) to be
> safe, gcc would emit code to handle unaligned loads. But not in the
> simple case where the struct has only one member.
>
> Are you suggesting that this has changed since I did my testing?
>
here a small example I made and try with a sourcery 2006q3-27


/tmp/arm-2006q3/bin/arm-none-linux-gnueabi-gcc -S test.c -O3 -o
test.s.packed
/tmp/arm-2006q3/bin/arm-none-linux-gnueabi-gcc -S test.c -DNOP -O3 -o test.s

$diff test.s test.s.packed 19,23c19,34
< @ link register save eliminated.
< ldrh r2, [r1, #0]
< ldrh r1, [r0, #2]
< ldr r0, [r0, #4]
< @ lr needed for prologue
---
> stmfd sp!, {r4, r5, r6, lr}
> ldrb r2, [r0, #5] @ zero_extendqisi2
> ldrb r3, [r0, #4] @ zero_extendqisi2
> mov lr, r1
> ldrb r4, [r0, #6] @ zero_extendqisi2
> ldrb r5, [r0, #3] @ zero_extendqisi2
> ldrb r6, [r1, #1] @ zero_extendqisi2
> orr r3, r3, r2, asl #8
> ldrb r1, [r0, #2] @ zero_extendqisi2
> ldrb ip, [r0, #7] @ zero_extendqisi2
> ldrb r2, [lr, #0] @ zero_extendqisi2
> orr r3, r3, r4, asl #16
> orr r0, r3, ip, asl #24
> orr r1, r1, r5, asl #8
> orr r2, r2, r6, asl #8
> ldmfd sp!, {r4, r5, r6, lr}


Matthieu


Attachments:
test.c (820.00 B)

2007-05-18 22:01:10

by Segher Boessenkool

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

>> Out of curiosity, why would a compiler ever insert padding in a
>> structure
>> that has all its elements properly-aligned?
>
> Well, it might decide it would be nicer if some elements were aligned
> to
> 64 bits. Or to a cache line. Or something. I don't care about _why_ --
> the point is that it's _allowed_ to. Hence the original use of
> __attribute__((packed)).

It's not the compiler who decides -- struct layout is
dictated by the ABI you're compiling for.


Segher

2007-05-19 01:59:27

by David Woodhouse

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Fri, 2007-05-18 at 21:55 +0200, matthieu castet wrote:
> > Are you suggesting that this has changed since I did my testing?
> >
> Which version of gcc did you try ?

It was a while ago -- probably 3.2 or something like that. I think it
might even predate the summary support.

When I get home I'll take another look.

--
dwmw2

2007-05-19 02:07:56

by David Woodhouse

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Sat, 2007-05-19 at 00:00 +0200, Segher Boessenkool wrote:
> It's not the compiler who decides -- struct layout is
> dictated by the ABI you're compiling for.

This is true in the case of externally-visible stuff. I think the
compiler is permitted to violate the ABI for purely unit-internal things
if it makes sense though, isn't it?

Besides, in the case of the Linux kernel the ABI in question could be
one of many. It could even be a new one which was added a couple of
weeks ago, and which I had no _chance_ of considering.

The rule stands -- empirical testing of what the compiler will do isn't
usually the right answer.

--
dwmw2

2007-05-19 12:24:47

by Segher Boessenkool

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

>> It's not the compiler who decides -- struct layout is
>> dictated by the ABI you're compiling for.
>
> This is true in the case of externally-visible stuff. I think the
> compiler is permitted to violate the ABI for purely unit-internal
> things
> if it makes sense though, isn't it?

Sure. It isn't "violating the ABI" in that case though,
to be perfectly clear.

> Besides, in the case of the Linux kernel the ABI in question could be
> one of many. It could even be a new one which was added a couple of
> weeks ago, and which I had no _chance_ of considering.

Of course.

> The rule stands -- empirical testing of what the compiler will do isn't
> usually the right answer.

It is *never* the right answer. You should always write
your code so that it will do the right thing no matter
what the compiler decides to do to it.


Segher

2007-05-20 11:29:48

by David Woodhouse

[permalink] [raw]
Subject: Re: [PATCH] ubi: kill homegrown endian macros

On Sat, 2007-05-19 at 14:24 +0200, Segher Boessenkool wrote:
> >> It's not the compiler who decides -- struct layout is
> >> dictated by the ABI you're compiling for.
> >
> > This is true in the case of externally-visible stuff. I think the
> > compiler is permitted to violate the ABI for purely unit-internal
> > things
> > if it makes sense though, isn't it?
>
> Sure. It isn't "violating the ABI" in that case though,
> to be perfectly clear.

Of course. It's not conforming to the ABI because there's no need to.

> > The rule stands -- empirical testing of what the compiler will do isn't
> > usually the right answer.
>
> It is *never* the right answer. You should always write
> your code so that it will do the right thing no matter
> what the compiler decides to do to it.

Well, there's sometimes some benefit in _also_ checking that the output
of the compiler matches your expectations. :)

--
dwmw2