Skip to content

Commit

Permalink
scst_lib,scst_sysfs: Add aen_disabled setting
Browse files Browse the repository at this point in the history
Add a setting to scst_tgt that can prevent scst_gen_aen_or_ua from
generating an AEN, even if the underlying transport is capable of
transmitting them.  It will instead generate a UA.
  • Loading branch information
bmeagherix committed Apr 10, 2023
1 parent 87681c0 commit 2242124
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 0 deletions.
7 changes: 7 additions & 0 deletions scst/README
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,13 @@ Every target should have at least the following entries:

For instance, read_unaligned_cmd_count means number of 4K unaligned IOs.

- aen_disabled - if set this target port is not to send AEN (Asynchronous
Event Notification), but rather generate a Unit Attention - even if the
underlying transport does support AEN.

This could prove useful in different situations including when the target
is also a forward_dst.

A target driver may have also the following entries:

- "hw_target" - if the target driver supports both hardware and virtual
Expand Down
9 changes: 9 additions & 0 deletions scst/include/scst.h
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,9 @@ enum scst_exec_res {
/* Cache of tgt->tgt_forward_dst */
#define SCST_TGT_DEV_FORWARD_DST 5

/* Cache of tgt->tgt_aen_disabled */
#define SCST_TGT_DEV_AEN_DISABLED 6

/*************************************************************
** I/O grouping types. Changing them don't forget to change
** the corresponding *_STR values in scst_const.h!
Expand Down Expand Up @@ -1694,6 +1697,12 @@ struct scst_tgt {
*/
unsigned tgt_forward_dst:1;

/*
* Set if do not to wish to send AEN from this target port, even if
* supported by the transport. Send a UA instead.
*/
unsigned int tgt_aen_disabled:1;

/* Per target analog of the corresponding driver's fields */
unsigned tgt_dif_supported:1;
unsigned tgt_hw_dif_type1_supported:1;
Expand Down
13 changes: 13 additions & 0 deletions scst/src/scst_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -2511,6 +2511,15 @@ void scst_gen_aen_or_ua(struct scst_tgt_dev *tgt_dev,
sess->shut_phase != SCST_SESS_SPH_READY)
goto out;

if (unlikely(test_bit(SCST_TGT_DEV_AEN_DISABLED,
&tgt_dev->tgt_dev_flags))) {
/*
* We have decided not to generate an AEN
* even if supported by the transport.
*/
goto queue_ua;
}

if (tgtt->report_aen != NULL) {
struct scst_aen *aen;
int rc;
Expand Down Expand Up @@ -5300,6 +5309,10 @@ static int scst_alloc_add_tgt_dev(struct scst_session *sess,
set_bit(SCST_TGT_DEV_FORWARD_DST, &tgt_dev->tgt_dev_flags);
else
clear_bit(SCST_TGT_DEV_FORWARD_DST, &tgt_dev->tgt_dev_flags);
if (sess->tgt->tgt_aen_disabled)
set_bit(SCST_TGT_DEV_AEN_DISABLED, &tgt_dev->tgt_dev_flags);
else
clear_bit(SCST_TGT_DEV_AEN_DISABLED, &tgt_dev->tgt_dev_flags);
tgt_dev->hw_dif_same_sg_layout_required = sess->tgt->tgt_hw_dif_same_sg_layout_required;
tgt_dev->tgt_dev_dif_guard_format = acg_dev->acg_dev_dif_guard_format;
if (tgt_dev->tgt_dev_dif_guard_format == SCST_DIF_GUARD_FORMAT_IP)
Expand Down
96 changes: 96 additions & 0 deletions scst/src/scst_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2599,6 +2599,101 @@ static struct kobj_attribute scst_tgt_forwarding =
__ATTR(forwarding, S_IRUGO | S_IWUSR, scst_tgt_forward_dst_show,
scst_tgt_forward_dst_store);

static ssize_t scst_tgt_aen_disabled_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
struct scst_tgt *tgt;
int res;

TRACE_ENTRY();

tgt = container_of(kobj, struct scst_tgt, tgt_kobj);

res = sprintf(buf, "%d\n%s", tgt->tgt_aen_disabled,
tgt->tgt_aen_disabled ? SCST_SYSFS_KEY_MARK "\n" : "");

TRACE_EXIT_RES(res);
return res;
}

static ssize_t scst_tgt_aen_disabled_store(struct kobject *kobj,
struct kobj_attribute *attr, const char *buf, size_t count)
{
int res = 0;
struct scst_tgt *tgt;
struct scst_session *sess;
int old;

TRACE_ENTRY();

if ((buf == NULL) || (count == 0)) {
res = 0;
goto out;
}

tgt = container_of(kobj, struct scst_tgt, tgt_kobj);

mutex_lock(&scst_mutex);

old = tgt->tgt_aen_disabled;

switch (buf[0]) {
case '0':
tgt->tgt_aen_disabled = 0;
break;
case '1':
tgt->tgt_aen_disabled = 1;
break;
default:
PRINT_ERROR("%s: Requested action not understood: %s",
__func__, buf);
res = -EINVAL;
goto out_unlock;
}

if (tgt->tgt_aen_disabled == old)
goto out_unlock;

list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) {
int i;

for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) {
struct list_head *head = &sess->sess_tgt_dev_list[i];
struct scst_tgt_dev *tgt_dev;

list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) {
if (tgt->tgt_aen_disabled)
set_bit(SCST_TGT_DEV_AEN_DISABLED,
&tgt_dev->tgt_dev_flags);
else
clear_bit(SCST_TGT_DEV_AEN_DISABLED,
&tgt_dev->tgt_dev_flags);
}
}
}

if (tgt->tgt_aen_disabled)
PRINT_INFO("Set AEN disabled for target %s",
tgt->tgt_name);
else
PRINT_INFO("Clear AEN disabled for target %s",
tgt->tgt_name);

out_unlock:
mutex_unlock(&scst_mutex);

if (res == 0)
res = count;

out:
TRACE_EXIT_RES(res);
return res;
}

static struct kobj_attribute scst_tgt_aen_disabled =
__ATTR(aen_disabled, 0644, scst_tgt_aen_disabled_show,
scst_tgt_aen_disabled_store);

static ssize_t scst_tgt_comment_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
Expand Down Expand Up @@ -2873,6 +2968,7 @@ static struct attribute *scst_tgt_attrs[] = {
&scst_rel_tgt_id.attr,
&scst_tgt_forward_src.attr,
&scst_tgt_forward_dst.attr,
&scst_tgt_aen_disabled.attr,
&scst_tgt_forwarding.attr,
&scst_tgt_comment.attr,
&scst_tgt_addr_method.attr,
Expand Down

0 comments on commit 2242124

Please sign in to comment.