[PATCH] Fixes bitmap allocation accounting logic in rtems-rfs-bitmaps.c
Chris Johns
chrisj at rtems.org
Thu Oct 12 16:48:54 UTC 2017
Hi,
Many thanks for post the patches. The other patches look fine. I am wondering is this is equivalent to what you have?
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-bitmaps.c b/cpukit/libfs/src/rfs/rtems-rfs-bitmaps.c
index 15a9050133..d14082691a 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-bitmaps.c
+++ b/cpukit/libfs/src/rfs/rtems-rfs-bitmaps.c
@@ -196,9 +196,9 @@ rtems_rfs_bitmap_map_set (rtems_rfs_bitmap_control* control,
search_map = control->search_bits;
index = rtems_rfs_bitmap_map_index (bit);
offset = rtems_rfs_bitmap_map_offset (bit);
- map[index] = rtems_rfs_bitmap_set (map[index], 1 << offset);
- if (rtems_rfs_bitmap_match(map[index], RTEMS_RFS_BITMAP_ELEMENT_SET))
+ if (!rtems_rfs_bitmap_match(map[index], RTEMS_RFS_BITMAP_ELEMENT_SET))
{
+ map[index] = rtems_rfs_bitmap_set (map[index], 1 << offset);
bit = index;
index = rtems_rfs_bitmap_map_index (bit);
offset = rtems_rfs_bitmap_map_offset (bit);
@@ -226,6 +226,8 @@ rtems_rfs_bitmap_map_clear (rtems_rfs_bitmap_control* control,
search_map = control->search_bits;
index = rtems_rfs_bitmap_map_index (bit);
offset = rtems_rfs_bitmap_map_offset (bit);
+ if (rtems_rfs_bitmap_match(map[index], RTEMS_RFS_BITMAP_ELEMENT_SET))
+ {
map[index] = rtems_rfs_bitmap_clear (map[index], 1 << offset);
bit = index;
index = rtems_rfs_bitmap_map_index (bit);
@@ -233,6 +235,7 @@ rtems_rfs_bitmap_map_clear (rtems_rfs_bitmap_control* control,
search_map[index] = rtems_rfs_bitmap_clear (search_map[index], 1 << offset);
rtems_rfs_buffer_mark_dirty (control->buffer);
control->free++;
+ }
return 0;
}
Chris
On 10/10/17 4:28 pm, Fan Deng wrote:
> The bitmap allocation accounting logic in rtems-rfs-bitmaps.c is flawed
> around control->free. Specifically:
>
> In rtems_rfs_bitmap_map_set():
> control->free is only decremented when its corresponding search bit is
> toggled. This is wrong and will miss on average 31/32 set updates.
>
> In rtems_rfs_bitmap_map_clear():
> control->free is incremented unconditionally.
>
> The correct behavior is:
> When updating the map, check if the bit is already set/clear. Only update
> control->free when the bit is toggled.
>
> This change enforced the correct behavior.
>
> Tested by inspecting the internal data structure.
> ---
> cpukit/libfs/src/rfs/rtems-rfs-bitmaps.c | 40 +++++++++++++++++++++-----------
> 1 file changed, 26 insertions(+), 14 deletions(-)
>
> diff --git a/cpukit/libfs/src/rfs/rtems-rfs-bitmaps.c b/cpukit/libfs/src/rfs/rtems-rfs-bitmaps.c
> index 15a9050133..c0c6921db1 100644
> --- a/cpukit/libfs/src/rfs/rtems-rfs-bitmaps.c
> +++ b/cpukit/libfs/src/rfs/rtems-rfs-bitmaps.c
> @@ -183,11 +183,12 @@ int
> rtems_rfs_bitmap_map_set (rtems_rfs_bitmap_control* control,
> rtems_rfs_bitmap_bit bit)
> {
> - rtems_rfs_bitmap_map map;
> - rtems_rfs_bitmap_map search_map;
> - int index;
> - int offset;
> - int rc;
> + rtems_rfs_bitmap_map map;
> + rtems_rfs_bitmap_map search_map;
> + int index;
> + int offset;
> + int rc;
> + rtems_rfs_bitmap_element element;
> rc = rtems_rfs_bitmap_load_map (control, &map);
> if (rc > 0)
> return rc;
> @@ -196,15 +197,20 @@ rtems_rfs_bitmap_map_set (rtems_rfs_bitmap_control* control,
> search_map = control->search_bits;
> index = rtems_rfs_bitmap_map_index (bit);
> offset = rtems_rfs_bitmap_map_offset (bit);
> - map[index] = rtems_rfs_bitmap_set (map[index], 1 << offset);
> + element = map[index];
> + map[index] = rtems_rfs_bitmap_set (element, 1 << offset);
> + // If the element does not change, the bit was already set. There will be no
> + // further action to take.
> + if (rtems_rfs_bitmap_match(element, map[index]))
> + return 0;
> + control->free--;
> + rtems_rfs_buffer_mark_dirty (control->buffer);
> if (rtems_rfs_bitmap_match(map[index], RTEMS_RFS_BITMAP_ELEMENT_SET))
> {
> bit = index;
> index = rtems_rfs_bitmap_map_index (bit);
> offset = rtems_rfs_bitmap_map_offset (bit);
> search_map[index] = rtems_rfs_bitmap_set (search_map[index], 1 << offset);
> - control->free--;
> - rtems_rfs_buffer_mark_dirty (control->buffer);
> }
> return 0;
> }
> @@ -213,11 +219,12 @@ int
> rtems_rfs_bitmap_map_clear (rtems_rfs_bitmap_control* control,
> rtems_rfs_bitmap_bit bit)
> {
> - rtems_rfs_bitmap_map map;
> - rtems_rfs_bitmap_map search_map;
> - int index;
> - int offset;
> - int rc;
> + rtems_rfs_bitmap_map map;
> + rtems_rfs_bitmap_map search_map;
> + int index;
> + int offset;
> + int rc;
> + rtems_rfs_bitmap_element element;
> rc = rtems_rfs_bitmap_load_map (control, &map);
> if (rc > 0)
> return rc;
> @@ -226,7 +233,12 @@ rtems_rfs_bitmap_map_clear (rtems_rfs_bitmap_control* control,
> search_map = control->search_bits;
> index = rtems_rfs_bitmap_map_index (bit);
> offset = rtems_rfs_bitmap_map_offset (bit);
> - map[index] = rtems_rfs_bitmap_clear (map[index], 1 << offset);
> + element = map[index];
> + map[index] = rtems_rfs_bitmap_clear (element, 1 << offset);
> + // If the element does not change, the bit was already clear. There will be no
> + // further action to take.
> + if (rtems_rfs_bitmap_match(element, map[index]))
> + return 0;
> bit = index;
> index = rtems_rfs_bitmap_map_index (bit);
> offset = rtems_rfs_bitmap_map_offset(bit);
>
More information about the devel
mailing list