Skip to content

Commit

Permalink
Merge tag 'for-5.15/dm-changes' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/device-mapper/linux-dm

Pull device mapper updates from Mike Snitzer:

 - Add DM infrastructure for IMA-based remote attestion. These changes
   are the basis for deploying DM-based storage in a "cloud" that must
   validate configurations end-users run to maintain trust. These DM
   changes allow supported DM targets' configurations to be measured via
   IMA. But the policy and enforcement (of which configurations are
   valid) is managed by something outside the kernel (e.g. Keylime).

 - Fix DM crypt scalability regression on systems with many cpus due to
   percpu_counter spinlock contention in crypt_page_alloc().

 - Use in_hardirq() instead of deprecated in_irq() in DM crypt.

 - Add event counters to DM writecache to allow users to further assess
   how the writecache is performing.

 - Various code cleanup in DM writecache's main IO mapping function.

* tag 'for-5.15/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
  dm crypt: use in_hardirq() instead of deprecated in_irq()
  dm ima: update dm documentation for ima measurement support
  dm ima: update dm target attributes for ima measurements
  dm ima: add a warning in dm_init if duplicate ima events are not measured
  dm ima: prefix ima event name related to device mapper with dm_
  dm ima: add version info to dm related events in ima log
  dm ima: prefix dm table hashes in ima log with hash algorithm
  dm crypt: Avoid percpu_counter spinlock contention in crypt_page_alloc()
  dm: add documentation for IMA measurement support
  dm: update target status functions to support IMA measurement
  dm ima: measure data on device rename
  dm ima: measure data on table clear
  dm ima: measure data on device remove
  dm ima: measure data on device resume
  dm ima: measure data on table load
  dm writecache: add event counters
  dm writecache: report invalid return from writecache_map helpers
  dm writecache: further writecache_map() cleanup
  dm writecache: factor out writecache_map_remap_origin()
  dm writecache: split up writecache_map() to improve code readability
  • Loading branch information
Linus Torvalds committed Aug 31, 2021
2 parents a998a62 + d3703ef commit efa916a
Show file tree
Hide file tree
Showing 43 changed files with 2,235 additions and 197 deletions.
715 changes: 715 additions & 0 deletions Documentation/admin-guide/device-mapper/dm-ima.rst

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Documentation/admin-guide/device-mapper/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Device Mapper
dm-dust
dm-ebs
dm-flakey
dm-ima
dm-init
dm-integrity
dm-io
Expand Down
16 changes: 14 additions & 2 deletions Documentation/admin-guide/device-mapper/writecache.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,23 @@ Status:
2. the number of blocks
3. the number of free blocks
4. the number of blocks under writeback
5. the number of read requests
6. the number of read requests that hit the cache
7. the number of write requests
8. the number of write requests that hit uncommitted block
9. the number of write requests that hit committed block
10. the number of write requests that bypass the cache
11. the number of write requests that are allocated in the cache
12. the number of write requests that are blocked on the freelist
13. the number of flush requests
14. the number of discard requests

Messages:
flush
flush the cache device. The message returns successfully
Flush the cache device. The message returns successfully
if the cache device was flushed without an error
flush_on_suspend
flush the cache device on next suspend. Use this message
Flush the cache device on next suspend. Use this message
when you are going to remove the cache device. The proper
sequence for removing the cache device is:

Expand All @@ -98,3 +108,5 @@ Messages:
6. the cache device is now inactive and it can be deleted
cleaner
See above "cleaner" constructor documentation.
clear_stats
Clear the statistics that are reported on the status line
4 changes: 4 additions & 0 deletions drivers/md/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ ifeq ($(CONFIG_BLK_DEV_ZONED),y)
dm-mod-objs += dm-zone.o
endif

ifeq ($(CONFIG_IMA),y)
dm-mod-objs += dm-ima.o
endif

ifeq ($(CONFIG_DM_VERITY_FEC),y)
dm-verity-objs += dm-verity-fec.o
endif
Expand Down
24 changes: 24 additions & 0 deletions drivers/md/dm-cache-target.c
Original file line number Diff line number Diff line change
Expand Up @@ -3122,6 +3122,30 @@ static void cache_status(struct dm_target *ti, status_type_t type,
DMEMIT(" %s", cache->ctr_args[i]);
if (cache->nr_ctr_args)
DMEMIT(" %s", cache->ctr_args[cache->nr_ctr_args - 1]);
break;

case STATUSTYPE_IMA:
DMEMIT_TARGET_NAME_VERSION(ti->type);
if (get_cache_mode(cache) == CM_FAIL)
DMEMIT(",metadata_mode=fail");
else if (get_cache_mode(cache) == CM_READ_ONLY)
DMEMIT(",metadata_mode=ro");
else
DMEMIT(",metadata_mode=rw");

format_dev_t(buf, cache->metadata_dev->bdev->bd_dev);
DMEMIT(",cache_metadata_device=%s", buf);
format_dev_t(buf, cache->cache_dev->bdev->bd_dev);
DMEMIT(",cache_device=%s", buf);
format_dev_t(buf, cache->origin_dev->bdev->bd_dev);
DMEMIT(",cache_origin_device=%s", buf);
DMEMIT(",writethrough=%c", writethrough_mode(cache) ? 'y' : 'n');
DMEMIT(",writeback=%c", writeback_mode(cache) ? 'y' : 'n');
DMEMIT(",passthrough=%c", passthrough_mode(cache) ? 'y' : 'n');
DMEMIT(",metadata2=%c", cache->features.metadata_version == 2 ? 'y' : 'n');
DMEMIT(",no_discard_passdown=%c", cache->features.discard_passdown ? 'n' : 'y');
DMEMIT(";");
break;
}

return;
Expand Down
5 changes: 5 additions & 0 deletions drivers/md/dm-clone-target.c
Original file line number Diff line number Diff line change
Expand Up @@ -1499,6 +1499,11 @@ static void clone_status(struct dm_target *ti, status_type_t type,

for (i = 0; i < clone->nr_ctr_args; i++)
DMEMIT(" %s", clone->ctr_args[i]);
break;

case STATUSTYPE_IMA:
*result = '\0';
break;
}

return;
Expand Down
5 changes: 5 additions & 0 deletions drivers/md/dm-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <trace/events/block.h>

#include "dm.h"
#include "dm-ima.h"

#define DM_RESERVED_MAX_IOS 1024

Expand Down Expand Up @@ -119,6 +120,10 @@ struct mapped_device {
unsigned int nr_zones;
unsigned int *zwp_offset;
#endif

#ifdef CONFIG_IMA
struct dm_ima_measurements ima;
#endif
};

/*
Expand Down
38 changes: 35 additions & 3 deletions drivers/md/dm-crypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -2223,11 +2223,11 @@ static void kcryptd_queue_crypt(struct dm_crypt_io *io)
if ((bio_data_dir(io->base_bio) == READ && test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags)) ||
(bio_data_dir(io->base_bio) == WRITE && test_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags))) {
/*
* in_irq(): Crypto API's skcipher_walk_first() refuses to work in hard IRQ context.
* in_hardirq(): Crypto API's skcipher_walk_first() refuses to work in hard IRQ context.
* irqs_disabled(): the kernel may run some IO completion from the idle thread, but
* it is being executed with irqs disabled.
*/
if (in_irq() || irqs_disabled()) {
if (in_hardirq() || irqs_disabled()) {
tasklet_init(&io->tasklet, kcryptd_crypt_tasklet, (unsigned long)&io->work);
tasklet_schedule(&io->tasklet);
return;
Expand Down Expand Up @@ -2661,7 +2661,12 @@ static void *crypt_page_alloc(gfp_t gfp_mask, void *pool_data)
struct crypt_config *cc = pool_data;
struct page *page;

if (unlikely(percpu_counter_compare(&cc->n_allocated_pages, dm_crypt_pages_per_client) >= 0) &&
/*
* Note, percpu_counter_read_positive() may over (and under) estimate
* the current usage by at most (batch - 1) * num_online_cpus() pages,
* but avoids potential spinlock contention of an exact result.
*/
if (unlikely(percpu_counter_read_positive(&cc->n_allocated_pages) >= dm_crypt_pages_per_client) &&
likely(gfp_mask & __GFP_NORETRY))
return NULL;

Expand Down Expand Up @@ -3485,7 +3490,34 @@ static void crypt_status(struct dm_target *ti, status_type_t type,
if (test_bit(CRYPT_IV_LARGE_SECTORS, &cc->cipher_flags))
DMEMIT(" iv_large_sectors");
}
break;

case STATUSTYPE_IMA:
DMEMIT_TARGET_NAME_VERSION(ti->type);
DMEMIT(",allow_discards=%c", ti->num_discard_bios ? 'y' : 'n');
DMEMIT(",same_cpu_crypt=%c", test_bit(DM_CRYPT_SAME_CPU, &cc->flags) ? 'y' : 'n');
DMEMIT(",submit_from_crypt_cpus=%c", test_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags) ?
'y' : 'n');
DMEMIT(",no_read_workqueue=%c", test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags) ?
'y' : 'n');
DMEMIT(",no_write_workqueue=%c", test_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags) ?
'y' : 'n');
DMEMIT(",iv_large_sectors=%c", test_bit(CRYPT_IV_LARGE_SECTORS, &cc->cipher_flags) ?
'y' : 'n');

if (cc->on_disk_tag_size)
DMEMIT(",integrity_tag_size=%u,cipher_auth=%s",
cc->on_disk_tag_size, cc->cipher_auth);
if (cc->sector_size != (1 << SECTOR_SHIFT))
DMEMIT(",sector_size=%d", cc->sector_size);
if (cc->cipher_string)
DMEMIT(",cipher_string=%s", cc->cipher_string);

DMEMIT(",key_size=%u", cc->key_size);
DMEMIT(",key_parts=%u", cc->key_parts);
DMEMIT(",key_extra_size=%u", cc->key_extra_size);
DMEMIT(",key_mac_size=%u", cc->key_mac_size);
DMEMIT(";");
break;
}
}
Expand Down
4 changes: 4 additions & 0 deletions drivers/md/dm-delay.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,10 @@ static void delay_status(struct dm_target *ti, status_type_t type,
DMEMIT_DELAY_CLASS(&dc->flush);
}
break;

case STATUSTYPE_IMA:
*result = '\0';
break;
}
}

Expand Down
4 changes: 4 additions & 0 deletions drivers/md/dm-dust.c
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,10 @@ static void dust_status(struct dm_target *ti, status_type_t type,
DMEMIT("%s %llu %u", dd->dev->name,
(unsigned long long)dd->start, dd->blksz);
break;

case STATUSTYPE_IMA:
*result = '\0';
break;
}
}

Expand Down
3 changes: 3 additions & 0 deletions drivers/md/dm-ebs-target.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,9 @@ static void ebs_status(struct dm_target *ti, status_type_t type,
snprintf(result, maxlen, ec->u_bs_set ? "%s %llu %u %u" : "%s %llu %u",
ec->dev->name, (unsigned long long) ec->start, ec->e_bs, ec->u_bs);
break;
case STATUSTYPE_IMA:
*result = '\0';
break;
}
}

Expand Down
4 changes: 4 additions & 0 deletions drivers/md/dm-era-target.c
Original file line number Diff line number Diff line change
Expand Up @@ -1644,6 +1644,10 @@ static void era_status(struct dm_target *ti, status_type_t type,
format_dev_t(buf, era->origin_dev->bdev->bd_dev);
DMEMIT("%s %u", buf, era->sectors_per_block);
break;

case STATUSTYPE_IMA:
*result = '\0';
break;
}

return;
Expand Down
4 changes: 4 additions & 0 deletions drivers/md/dm-flakey.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,10 @@ static void flakey_status(struct dm_target *ti, status_type_t type,
fc->corrupt_bio_value, fc->corrupt_bio_flags);

break;

case STATUSTYPE_IMA:
result[0] = '\0';
break;
}
}

Expand Down
Loading

0 comments on commit efa916a

Please sign in to comment.