/** * zfcp_diag_adapter_setup() - Setup storage for adapter diagnostics. * @adapter: the adapter to setup diagnostics for. * * Creates the data-structures to store the diagnostics for an adapter. This * overwrites whatever was stored before at &zfcp_adapter->diagnostics! * * Return: * * 0 - Everyting is OK * * -ENOMEM - Could not allocate all/parts of the data-structures; * &zfcp_adapter->diagnostics remains unchanged
*/ int zfcp_diag_adapter_setup(struct zfcp_adapter *const adapter)
{ struct zfcp_diag_adapter *diag; struct zfcp_diag_header *hdr;
diag = kzalloc(sizeof(*diag), GFP_KERNEL); if (diag == NULL) return -ENOMEM;
/* setup header for port_data */
hdr = &diag->port_data.header;
spin_lock_init(&hdr->access_lock);
hdr->buffer = &diag->port_data.data;
hdr->buffer_size = sizeof(diag->port_data.data); /* set the timestamp so that the first test on age will always fail */
hdr->timestamp = jiffies - msecs_to_jiffies(diag->max_age);
/* setup header for config_data */
hdr = &diag->config_data.header;
spin_lock_init(&hdr->access_lock);
hdr->buffer = &diag->config_data.data;
hdr->buffer_size = sizeof(diag->config_data.data); /* set the timestamp so that the first test on age will always fail */
hdr->timestamp = jiffies - msecs_to_jiffies(diag->max_age);
adapter->diagnostics = diag; return 0;
}
/** * zfcp_diag_adapter_free() - Frees all adapter diagnostics allocations. * @adapter: the adapter whose diagnostic structures should be freed. * * Frees all data-structures in the given adapter that store diagnostics * information. Can savely be called with partially setup diagnostics.
*/ void zfcp_diag_adapter_free(struct zfcp_adapter *const adapter)
{
kfree(adapter->diagnostics);
adapter->diagnostics = NULL;
}
/** * zfcp_diag_update_xdata() - Update a diagnostics buffer. * @hdr: the meta data to update. * @data: data to use for the update. * @incomplete: flag stating whether the data in @data is incomplete.
*/ void zfcp_diag_update_xdata(struct zfcp_diag_header *const hdr, constvoid *const data, constbool incomplete)
{ constunsignedlong capture_timestamp = jiffies; unsignedlong flags;
spin_lock_irqsave(&hdr->access_lock, flags);
/* make sure we never go into the past with an update */ if (!time_after_eq(capture_timestamp, hdr->timestamp)) goto out;
/** * zfcp_diag_update_port_data_buffer() - Implementation of * &typedef zfcp_diag_update_buffer_func * to collect and update Port Data. * @adapter: Adapter to collect Port Data from. * * This call is SYNCHRONOUS ! It blocks till the respective command has * finished completely, or has failed in some way. * * Return: * * 0 - Successfully retrieved new Diagnostics and Updated the buffer; * this also includes cases where data was retrieved, but * incomplete; you'll have to check the flag ``incomplete`` * of &struct zfcp_diag_header. * * see zfcp_fsf_exchange_port_data_sync() for possible error-codes ( * excluding -EAGAIN)
*/ int zfcp_diag_update_port_data_buffer(struct zfcp_adapter *const adapter)
{ int rc;
rc = zfcp_fsf_exchange_port_data_sync(adapter->qdio, NULL); if (rc == -EAGAIN)
rc = 0; /* signaling incomplete via struct zfcp_diag_header */
/* buffer-data was updated in zfcp_fsf_exchange_port_data_handler() */
return rc;
}
/** * zfcp_diag_update_config_data_buffer() - Implementation of * &typedef zfcp_diag_update_buffer_func * to collect and update Config Data. * @adapter: Adapter to collect Config Data from. * * This call is SYNCHRONOUS ! It blocks till the respective command has * finished completely, or has failed in some way. * * Return: * * 0 - Successfully retrieved new Diagnostics and Updated the buffer; * this also includes cases where data was retrieved, but * incomplete; you'll have to check the flag ``incomplete`` * of &struct zfcp_diag_header. * * see zfcp_fsf_exchange_config_data_sync() for possible error-codes ( * excluding -EAGAIN)
*/ int zfcp_diag_update_config_data_buffer(struct zfcp_adapter *const adapter)
{ int rc;
rc = zfcp_fsf_exchange_config_data_sync(adapter->qdio, NULL); if (rc == -EAGAIN)
rc = 0; /* signaling incomplete via struct zfcp_diag_header */
/* buffer-data was updated in zfcp_fsf_exchange_config_data_handler() */
/* * every thread waiting here went via an interruptible wait, * so its fine to only wake those
*/
wake_up_interruptible_all(&__zfcp_diag_publish_wait);
}
/* * Should not happen (data is from the future).. if it does, still * signal that it needs refresh
*/ if (!time_after_eq(now, hdr->timestamp)) returnfalse;
if (jiffies_to_msecs(now - hdr->timestamp) >= diag->max_age) returnfalse;
returntrue;
}
/** * zfcp_diag_update_buffer_limited() - Collect diagnostics and update a * diagnostics buffer rate limited. * @adapter: Adapter to collect the diagnostics from. * @hdr: buffer-header for which to update with the collected diagnostics. * @buffer_update: Specific implementation for collecting and updating. * * This function will cause an update of the given @hdr by calling the also * given @buffer_update function. If called by multiple sources at the same * time, it will synchornize the update by only allowing one source to call * @buffer_update and the others to wait for that source to complete instead * (the wait is interruptible). * * Additionally this version is rate-limited and will only exit if either the * buffer is fresh enough (within the limit) - it will do nothing if the buffer * is fresh enough to begin with -, or if the source/thread that started this * update is the one that made the update (to prevent endless loops). * * Return: * * 0 - If the update was successfully published and/or the buffer is * fresh enough * * -EINTR - If the thread went into the wait-state and was interrupted * * whatever @buffer_update returns
*/ int zfcp_diag_update_buffer_limited(struct zfcp_adapter *const adapter, struct zfcp_diag_header *const hdr,
zfcp_diag_update_buffer_func buffer_update)
{ unsignedlong flags; int rc;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.