[PATCH] dm verity: deferred hash checking for restart/logging mode

2017-04-24 Thread Bongkyu Kim
This patch introduces deferred hash checking for dm-verity.
In case of restart and logging mode, I/O return first and hash checking is
deferred. It can improve dm-verity's performance greatly.

This is my testing on qualcomm snapdragon 821 platform with UFS 2.0.
dd if=/dev/block/dm-0 of=/dev/null bs=1024 count=100
- vanilla: 238.14 MB/s
- patched: 331.52 MB/s (+39.2%)

fio --rw=randread --size=64M --bs=4k --filename=/dev/block/dm-0 --name=job1
--name=job2 --name=job3 --name=job4
- vanilla: 325.21 MB/s
- patched: 356.42 MB/s (+9.6%)

One major concoren is security risk.
If data is tampered, this data will not return -EIO, and can be transferred
to user process. But, device will be rebooted after hash verification.
After rebooting, device will work with EIO mode.
In my opinion, this is enough for gurantee integrity by each power cycles.

Signed-off-by: Bongkyu Kim 
---
 drivers/md/dm-verity-target.c | 58 ---
 drivers/md/dm.c   | 17 +++--
 drivers/md/dm.h   |  4 +++
 3 files changed, 73 insertions(+), 6 deletions(-)

diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
index 7335d8a..37c4d9c 100644
--- a/drivers/md/dm-verity-target.c
+++ b/drivers/md/dm-verity-target.c
@@ -16,6 +16,7 @@
 
 #include "dm-verity.h"
 #include "dm-verity-fec.h"
+#include "dm.h"
 
 #include 
 #include 
@@ -62,6 +63,9 @@ struct buffer_aux {
int hash_verified;
 };
 
+static void verity_submit_prefetch(struct dm_verity *v,
+   struct dm_verity_io *io);
+
 /*
  * Initialize struct buffer_aux for a freshly created buffer.
  */
@@ -462,12 +466,35 @@ static void verity_finish_io(struct dm_verity_io *io, int 
error)
struct dm_verity *v = io->v;
struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
 
-   bio->bi_end_io = io->orig_bi_end_io;
-   bio->bi_error = error;
+   if (v->mode == DM_VERITY_MODE_EIO) {
+   bio->bi_end_io = io->orig_bi_end_io;
+   bio->bi_error = error;
+   }
 
verity_fec_finish_io(io);
 
-   bio_endio(bio);
+   if (v->mode == DM_VERITY_MODE_EIO) {
+   bio_endio(bio);
+   } else {
+   struct dm_target_io *tio = container_of(bio,
+   struct dm_target_io, clone);
+   struct dm_io *dmio = tio->io;
+   struct bio *ori_bio = dm_io_get_bio(dmio);
+   struct bio_vec *bv;
+   int i;
+
+   bio_put(bio);
+   free_io(dm_io_get_md(dmio), dmio);
+
+   bio_for_each_segment_all(bv, ori_bio, i) {
+   struct page *page = bv->bv_page;
+
+   put_page(page);
+   }
+
+   bio_put(ori_bio);
+
+   }
 }
 
 static void verity_work(struct work_struct *w)
@@ -486,6 +513,28 @@ static void verity_end_io(struct bio *bio)
return;
}
 
+   if (io->v->mode != DM_VERITY_MODE_EIO) {
+   struct dm_target_io *tio = container_of(bio,
+   struct dm_target_io, clone);
+   struct bio *ori_bio = dm_io_get_bio(tio->io);
+   struct bio_vec *bv;
+   int i;
+
+   bio_for_each_segment_all(bv, ori_bio, i) {
+   struct page *page = bv->bv_page;
+
+   get_page(page);
+   }
+
+   bio_get(ori_bio);
+   bio_get(bio);
+
+   bio->bi_end_io = io->orig_bi_end_io;
+   bio_endio(bio);
+
+   verity_submit_prefetch(io->v, io);
+   }
+
INIT_WORK(&io->work, verity_work);
queue_work(io->v->verify_wq, &io->work);
 }
@@ -586,7 +635,8 @@ static int verity_map(struct dm_target *ti, struct bio *bio)
 
verity_fec_init_io(io);
 
-   verity_submit_prefetch(v, io);
+   if (v->mode == DM_VERITY_MODE_EIO)
+   verity_submit_prefetch(v, io);
 
generic_make_request(bio);
 
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 8bf3977..9eca0a0 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -164,6 +164,18 @@ static unsigned dm_get_numa_node(void)
 DM_NUMA_NODE, num_online_nodes() - 1);
 }
 
+struct bio *dm_io_get_bio(struct dm_io *io)
+{
+   return io->bio;
+}
+EXPORT_SYMBOL(dm_io_get_bio);
+
+struct mapped_device *dm_io_get_md(struct dm_io *io)
+{
+   return io->md;
+}
+EXPORT_SYMBOL(dm_io_get_md);
+
 static int __init local_init(void)
 {
int r = -ENOMEM;
@@ -489,7 +501,7 @@ static struct dm_io *alloc_io(struct mapped_device *md)
return mempool_alloc(md->io_pool, GFP_NOIO);
 }
 
-static void free_io(struct mapped_device *md, struct dm_io *io)
+void free_io(struct mapped_device *md, struct 

[PATCH] lz4: fix wrong compress buffer size for 64-bits

2015-11-18 Thread Bongkyu Kim
The current lz4 compress buffer is 16kb on 32-bits, 32kb on 64-bits system.
But, lz4 needs only 16kb on both. On 64-bits, this causes wasted cpu cycles
for additional memset during every compression.

In case of lz4hc,
the current buffer size is (256kb + 8) on 32-bits, (512kb + 16) on 64-bits.
But, lz4hc needs only (256kb + 2 * pointer) on both.

This patch fixes these wrong compress buffer sizes for 64-bits.

Cc: Chanho Min 
Cc: Yann Collet 
Cc: Kyungsik Lee 
Signed-off-by: Bongkyu Kim 
---
 include/linux/lz4.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/lz4.h b/include/linux/lz4.h
index 4356686..6b784c5 100644
--- a/include/linux/lz4.h
+++ b/include/linux/lz4.h
@@ -9,8 +9,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#define LZ4_MEM_COMPRESS   (4096 * sizeof(unsigned char *))
-#define LZ4HC_MEM_COMPRESS (65538 * sizeof(unsigned char *))
+#define LZ4_MEM_COMPRESS   (16384)
+#define LZ4HC_MEM_COMPRESS (262144 + (2 * sizeof(unsigned char *)))
 
 /*
  * lz4_compressbound()
-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] of/i2c: support more interrupt specifiers

2012-11-25 Thread Bongkyu Kim
On 11/21/2012 10:41 PM, Rob Herring wrote:
> On 11/21/2012 02:58 AM, Bongkyu Kim wrote:
>> This patch supports more interrupt specifiers for i2c client.
> 
> Why?
> 

If we are registering a device has 2 interrupts like the below,
i2c@f9968000 {
lsm330_acc@1D {
compatible = "ST,lsm330_acc",
/* #interrupt-cells = <2> */
interrupts = <73 0x2 65 0x2>,
};
};

we can't use second irq(65) in a driver because of mapping first
interrupt only.
If second irq(65) is mapped, we can use by gpio_to_irq() function at a
driver.
So, I think that all interrupt specifiers should be parsed and mapped
if DT's interrupts property is allowed several interrupt specifiers.

>> Signed-off-by: Bongkyu Kim 
>> ---
>>  drivers/of/of_i2c.c | 5 -
>>  1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
>> index 3550f3b..c6d9b7e 100644
>> --- a/drivers/of/of_i2c.c
>> +++ b/drivers/of/of_i2c.c
>> @@ -34,6 +34,7 @@ void of_i2c_register_devices(struct i2c_adapter *adap)
>>  struct dev_archdata dev_ad = {};
>>  const __be32 *addr;
>>  int len;
>> +int nr = 0;
>>  
>>  dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name);
>>  
>> @@ -57,7 +58,9 @@ void of_i2c_register_devices(struct i2c_adapter *adap)
>>  continue;
>>  }
>>  
>> -info.irq = irq_of_parse_and_map(node, 0);
>> +info.irq = irq_of_parse_and_map(node, nr++);
>> +while (irq_of_parse_and_map(node, nr))
>> +nr++;
> 
> What's the point if you are just discarding the interrupt number? If
> this is needed, then shouldn't you fix i2c_board_info first?
> 
> Rob
> 

It is better that i2c_board_info will be fixed.
But, if it will be fixed, all i2c client drivers should be changed.
I think there're so many i2c drivers currently.
In my opinion, do not assign to i2c_board_info and just map for all
interrupts is the better.

Thanks,
Bongkyu.

>>  info.of_node = of_node_get(node);
>>  info.archdata = &dev_ad;
>>  
>>
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] of/i2c: support more interrupt specifiers

2012-11-21 Thread Bongkyu Kim
This patch supports more interrupt specifiers for i2c client.

Signed-off-by: Bongkyu Kim 
---
 drivers/of/of_i2c.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
index 3550f3b..c6d9b7e 100644
--- a/drivers/of/of_i2c.c
+++ b/drivers/of/of_i2c.c
@@ -34,6 +34,7 @@ void of_i2c_register_devices(struct i2c_adapter *adap)
struct dev_archdata dev_ad = {};
const __be32 *addr;
int len;
+   int nr = 0;
 
dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name);
 
@@ -57,7 +58,9 @@ void of_i2c_register_devices(struct i2c_adapter *adap)
continue;
}
 
-   info.irq = irq_of_parse_and_map(node, 0);
+   info.irq = irq_of_parse_and_map(node, nr++);
+   while (irq_of_parse_and_map(node, nr))
+   nr++;
info.of_node = of_node_get(node);
info.archdata = &dev_ad;
 
-- 
1.8.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] of/i2c: check status property for i2c client

2012-11-21 Thread Bongkyu Kim
Because of_i2c_register_devices() do not check status property,
all i2c clients are registered.

This patch add checking status property for i2c client.
After this patch, if status property is absent or "okay" or "ok",
i2c client will be registered.

Signed-off-by: Bongkyu Kim 
---
 drivers/of/of_i2c.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
index 3550f3b..2552fc5 100644
--- a/drivers/of/of_i2c.c
+++ b/drivers/of/of_i2c.c
@@ -37,6 +37,9 @@ void of_i2c_register_devices(struct i2c_adapter *adap)
 
dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name);
 
+   if (!of_device_is_available(node))
+   continue;
+
if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
dev_err(&adap->dev, "of_i2c: modalias failure on %s\n",
node->full_name);
-- 
1.8.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/