forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
drivers: hv: vmbus: Introduce latency testing
Introduce user specified latency in the packet reception path By exposing the test parameters as part of the debugfs channel attributes. We will control the testing state via these attributes. Signed-off-by: Branden Bonaby <[email protected]> Reviewed-by: Michael Kelley <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
- Loading branch information
1 parent
d21987d
commit af9ca6f
Showing
10 changed files
with
269 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
What: /sys/kernel/debug/hyperv/<UUID>/fuzz_test_state | ||
Date: October 2019 | ||
KernelVersion: 5.5 | ||
Contact: Branden Bonaby <[email protected]> | ||
Description: Fuzz testing status of a vmbus device, whether its in an ON | ||
state or a OFF state | ||
Users: Debugging tools | ||
|
||
What: /sys/kernel/debug/hyperv/<UUID>/delay/fuzz_test_buffer_interrupt_delay | ||
Date: October 2019 | ||
KernelVersion: 5.5 | ||
Contact: Branden Bonaby <[email protected]> | ||
Description: Fuzz testing buffer interrupt delay value between 0 - 1000 | ||
microseconds (inclusive). | ||
Users: Debugging tools | ||
|
||
What: /sys/kernel/debug/hyperv/<UUID>/delay/fuzz_test_message_delay | ||
Date: October 2019 | ||
KernelVersion: 5.5 | ||
Contact: Branden Bonaby <[email protected]> | ||
Description: Fuzz testing message delay value between 0 - 1000 microseconds | ||
(inclusive). | ||
Users: Debugging tools |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7578,6 +7578,7 @@ F: include/uapi/linux/hyperv.h | |
F: include/asm-generic/mshyperv.h | ||
F: tools/hv/ | ||
F: Documentation/ABI/stable/sysfs-bus-vmbus | ||
F: Documentation/ABI/testing/debugfs-hyperv | ||
|
||
HYPERBUS SUPPORT | ||
M: Vignesh Raghavendra <[email protected]> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* | ||
* Authors: | ||
* Branden Bonaby <[email protected]> | ||
*/ | ||
|
||
#include <linux/hyperv.h> | ||
#include <linux/debugfs.h> | ||
#include <linux/delay.h> | ||
#include <linux/err.h> | ||
|
||
#include "hyperv_vmbus.h" | ||
|
||
struct dentry *hv_debug_root; | ||
|
||
static int hv_debugfs_delay_get(void *data, u64 *val) | ||
{ | ||
*val = *(u32 *)data; | ||
return 0; | ||
} | ||
|
||
static int hv_debugfs_delay_set(void *data, u64 val) | ||
{ | ||
if (val > 1000) | ||
return -EINVAL; | ||
*(u32 *)data = val; | ||
return 0; | ||
} | ||
|
||
DEFINE_DEBUGFS_ATTRIBUTE(hv_debugfs_delay_fops, hv_debugfs_delay_get, | ||
hv_debugfs_delay_set, "%llu\n"); | ||
|
||
static int hv_debugfs_state_get(void *data, u64 *val) | ||
{ | ||
*val = *(bool *)data; | ||
return 0; | ||
} | ||
|
||
static int hv_debugfs_state_set(void *data, u64 val) | ||
{ | ||
if (val == 1) | ||
*(bool *)data = true; | ||
else if (val == 0) | ||
*(bool *)data = false; | ||
else | ||
return -EINVAL; | ||
return 0; | ||
} | ||
|
||
DEFINE_DEBUGFS_ATTRIBUTE(hv_debugfs_state_fops, hv_debugfs_state_get, | ||
hv_debugfs_state_set, "%llu\n"); | ||
|
||
/* Setup delay files to store test values */ | ||
static int hv_debug_delay_files(struct hv_device *dev, struct dentry *root) | ||
{ | ||
struct vmbus_channel *channel = dev->channel; | ||
char *buffer = "fuzz_test_buffer_interrupt_delay"; | ||
char *message = "fuzz_test_message_delay"; | ||
int *buffer_val = &channel->fuzz_testing_interrupt_delay; | ||
int *message_val = &channel->fuzz_testing_message_delay; | ||
struct dentry *buffer_file, *message_file; | ||
|
||
buffer_file = debugfs_create_file(buffer, 0644, root, | ||
buffer_val, | ||
&hv_debugfs_delay_fops); | ||
if (IS_ERR(buffer_file)) { | ||
pr_debug("debugfs_hyperv: file %s not created\n", buffer); | ||
return PTR_ERR(buffer_file); | ||
} | ||
|
||
message_file = debugfs_create_file(message, 0644, root, | ||
message_val, | ||
&hv_debugfs_delay_fops); | ||
if (IS_ERR(message_file)) { | ||
pr_debug("debugfs_hyperv: file %s not created\n", message); | ||
return PTR_ERR(message_file); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
/* Setup test state value for vmbus device */ | ||
static int hv_debug_set_test_state(struct hv_device *dev, struct dentry *root) | ||
{ | ||
struct vmbus_channel *channel = dev->channel; | ||
bool *state = &channel->fuzz_testing_state; | ||
char *status = "fuzz_test_state"; | ||
struct dentry *test_state; | ||
|
||
test_state = debugfs_create_file(status, 0644, root, | ||
state, | ||
&hv_debugfs_state_fops); | ||
if (IS_ERR(test_state)) { | ||
pr_debug("debugfs_hyperv: file %s not created\n", status); | ||
return PTR_ERR(test_state); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
/* Bind hv device to a dentry for debugfs */ | ||
static void hv_debug_set_dir_dentry(struct hv_device *dev, struct dentry *root) | ||
{ | ||
if (hv_debug_root) | ||
dev->debug_dir = root; | ||
} | ||
|
||
/* Create all test dentry's and names for fuzz testing */ | ||
int hv_debug_add_dev_dir(struct hv_device *dev) | ||
{ | ||
const char *device = dev_name(&dev->device); | ||
char *delay_name = "delay"; | ||
struct dentry *delay, *dev_root; | ||
int ret; | ||
|
||
if (!IS_ERR(hv_debug_root)) { | ||
dev_root = debugfs_create_dir(device, hv_debug_root); | ||
if (IS_ERR(dev_root)) { | ||
pr_debug("debugfs_hyperv: hyperv/%s/ not created\n", | ||
device); | ||
return PTR_ERR(dev_root); | ||
} | ||
hv_debug_set_test_state(dev, dev_root); | ||
hv_debug_set_dir_dentry(dev, dev_root); | ||
delay = debugfs_create_dir(delay_name, dev_root); | ||
|
||
if (IS_ERR(delay)) { | ||
pr_debug("debugfs_hyperv: hyperv/%s/%s/ not created\n", | ||
device, delay_name); | ||
return PTR_ERR(delay); | ||
} | ||
ret = hv_debug_delay_files(dev, delay); | ||
|
||
return ret; | ||
} | ||
pr_debug("debugfs_hyperv: hyperv/ not in root debugfs path\n"); | ||
return PTR_ERR(hv_debug_root); | ||
} | ||
|
||
/* Remove dentry associated with released hv device */ | ||
void hv_debug_rm_dev_dir(struct hv_device *dev) | ||
{ | ||
if (!IS_ERR(hv_debug_root)) | ||
debugfs_remove_recursive(dev->debug_dir); | ||
} | ||
|
||
/* Remove all dentrys associated with vmbus testing */ | ||
void hv_debug_rm_all_dir(void) | ||
{ | ||
debugfs_remove_recursive(hv_debug_root); | ||
} | ||
|
||
/* Delay buffer/message reads on a vmbus channel */ | ||
void hv_debug_delay_test(struct vmbus_channel *channel, enum delay delay_type) | ||
{ | ||
struct vmbus_channel *test_channel = channel->primary_channel ? | ||
channel->primary_channel : | ||
channel; | ||
bool state = test_channel->fuzz_testing_state; | ||
|
||
if (state) { | ||
if (delay_type == 0) | ||
udelay(test_channel->fuzz_testing_interrupt_delay); | ||
else | ||
udelay(test_channel->fuzz_testing_message_delay); | ||
} | ||
} | ||
|
||
/* Initialize top dentry for vmbus testing */ | ||
int hv_debug_init(void) | ||
{ | ||
hv_debug_root = debugfs_create_dir("hyperv", NULL); | ||
if (IS_ERR(hv_debug_root)) { | ||
pr_debug("debugfs_hyperv: hyperv/ not created\n"); | ||
return PTR_ERR(hv_debug_root); | ||
} | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters