Commit fee90dd9 authored by Federico Vaga's avatar Federico Vaga Committed by Federico Vaga

buffer: option to remove old block on store

The new option is "prefer-new" and it is boolean.

0 means that you prefer old blocks. So, when buffer is full all new
incoming blocks will be discarder.

1 means that you prefer new blocks. So, when buffer is full the oldest
block is removed in order to store the new one
Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
Acked-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent 65ae51dc
......@@ -96,8 +96,10 @@ static struct zio_block *zbk_alloc_block(struct zio_bi *bi,
/* alloc fails if we overflow the buffer size */
spin_lock_irqsave(&bi->lock, flags);
if (zbki->nitem >= bi->zattr_set.std_zattr[ZIO_ATTR_ZBUF_MAXLEN].value)
if (zbki->nitem >= bi->zattr_set.std_zattr[ZIO_ATTR_ZBUF_MAXLEN].value) {
bi->flags |= ZIO_BI_NOSPACE;
goto out_unlock;
}
zbki->nitem++;
spin_unlock_irqrestore(&bi->lock, flags);
......@@ -149,6 +151,7 @@ static void zbk_free_block(struct zio_bi *bi, struct zio_block *block)
if (((bi->flags & ZIO_DIR) == ZIO_DIR_OUTPUT) &&
zbki->nitem < bi->zattr_set.std_zattr[ZIO_ATTR_ZBUF_MAXLEN].value)
awake = 1;
bi->flags &= ~ZIO_BI_NOSPACE;
zbki->nitem--;
spin_unlock_irqrestore(&bi->lock, flags);
......
......@@ -201,8 +201,15 @@ static struct zio_block *zbk_alloc_block(struct zio_bi *bi,
return &item->block;
out_free:
if (offset != ZIO_FFA_NOSPACE)
if (offset != ZIO_FFA_NOSPACE) {
zio_ffa_free_s(zbki->ffa, offset, datalen);
} else {
/* NOSPACE means that the buffer is 'full', there is
* no space for the requested datalen */
spin_lock_irqsave(&bi->lock, flags);
bi->flags |= ZIO_BI_NOSPACE;
spin_unlock_irqrestore(&bi->lock, flags);
}
kmem_cache_free(zbk_slab, item);
zio_free_control(ctrl);
return NULL;
......@@ -229,6 +236,7 @@ static void zbk_free_block(struct zio_bi *bi, struct zio_block *block)
spin_lock_irqsave(&bi->lock, flags);
zbki->alloc_size -= item->len;
bi->flags &= ~ZIO_BI_NOSPACE;
spin_unlock_irqrestore(&bi->lock, flags);
out_free:
......
......@@ -84,7 +84,12 @@ struct zio_bi {
/* first 4bit are reserved for zio object universal flags */
enum zio_bi_flag_mask {
/* Status */
ZIO_BI_PUSHING = 0x10, /* a push is being performed */
ZIO_BI_NOSPACE = 0x20, /**< No space left in the buffer
(e.g. buffer is full ) */
/* Configuration */
ZIO_BI_PREF_NEW = 0x100, /**< prefer new blocks instead old ones */
};
......@@ -182,7 +187,19 @@ static inline int zio_buffer_free_block(struct zio_bi *bi,
static inline struct zio_block *zio_buffer_alloc_block(struct zio_bi *bi,
size_t datalen, gfp_t gfp)
{
return bi->b_op->alloc_block(bi, datalen, gfp);
struct zio_block *block;
block = bi->b_op->alloc_block(bi, datalen, gfp);
if (!block && (bi->flags & ZIO_BI_NOSPACE)) {
/* We cannot allocate because the buffer is full */
if (bi->flags & ZIO_BI_PREF_NEW) {
/* try by removing the oldest block */
block = bi->b_op->retr_block(bi);
bi->b_op->free_block(bi, block);
block = bi->b_op->alloc_block(bi, datalen, gfp);
}
}
return block;
}
#endif /* __ZIO_BUFFER_H__ */
......@@ -791,6 +791,7 @@ static ssize_t zio_buf_flush(struct device *dev,
return count;
}
/**
* It returns the data direction of a given channel set
*/
......@@ -802,6 +803,36 @@ static ssize_t zio_show_dire(struct device *dev,
return sprintf(buf, "%s\n", cset->flags & ZIO_DIR ? "output" : "input");
}
/**
* It configures the buffer preference:
* 0 - it will keep the oldest block when the buffer is full
* 1 - it will remove old blocks in order to store the new ones
*/
static ssize_t zio_store_pref(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct zio_bi *bi = to_zio_bi(dev);
unsigned long flags;
spin_lock_irqsave(&bi->lock, flags);
if (buf[0] == '0')
bi->flags &= ~ZIO_BI_PREF_NEW;
else
bi->flags |= ZIO_BI_PREF_NEW;
spin_unlock_irqrestore(&bi->lock, flags);
return count;
}
static ssize_t zio_show_pref(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct zio_bi *bi = to_zio_bi(dev);
return sprintf(buf, "%d\n", !!(bi->flags & ZIO_BI_PREF_NEW));
}
#if ZIO_HAS_BINARY_CONTROL
/*
* zobj_read_cur_ctrl
......@@ -880,6 +911,7 @@ enum zio_default_attribute_numeration {
ZIO_DAN_FLUS, /* flush */
ZIO_DAN_ALAR, /* alarms */
ZIO_DAN_DIRE, /* direction */
ZIO_DAN_PREF, /* prefer-new */
};
/* default zio attributes */
......@@ -902,6 +934,8 @@ static struct device_attribute zio_default_attributes[] = {
zio_show_alarm, zio_store_alarm),
[ZIO_DAN_DIRE] = __ATTR(direction, ZIO_RO_PERM,
zio_show_dire, NULL),
[ZIO_DAN_PREF] = __ATTR(prefer-new, ZIO_RW_PERM,
zio_show_pref, zio_store_pref),
__ATTR_NULL,
};
/* default attributes for most of the zio objects */
......@@ -932,6 +966,7 @@ static struct attribute *def_chan_attrs_ptr[] = {
static struct attribute *def_bi_attrs_ptr[] = {
&zio_default_attributes[ZIO_DAN_NAME].attr,
&zio_default_attributes[ZIO_DAN_FLUS].attr,
&zio_default_attributes[ZIO_DAN_PREF].attr,
NULL,
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment