Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b8abe346 authored by Mitko Haralanov's avatar Mitko Haralanov Committed by Doug Ledford
Browse files

staging/hfi1: TID group definitions and support funcs



Definitions and functions use to manage sets of TID/RcvArray groups.
These will be used by the TID cacheline functionality coming with
later patches.

TID groups (or RcvArray groups) are groups of TID/RcvArray entries
organized in sets of 8 and aligned on cacheline boundaries. The
TID/RcvArray entries are managed in this way to make taking
advantage of write-combining easier - each group is a entire
cacheline.

rcv_array_wc_fill() is provided to allow of generating writes to
TIDs which are not currently being used in order to cause the
flush of the write-combining buffer.

Signed-off-by: default avatarMitko Haralanov <mitko.haralanov@intel.com>
Reviewed-by: default avatarIra Weiny <ira.weiny@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent acac10fd
Loading
Loading
Loading
Loading
+64 −0
Original line number Original line Diff line number Diff line
@@ -52,6 +52,14 @@
#include "user_exp_rcv.h"
#include "user_exp_rcv.h"
#include "trace.h"
#include "trace.h"


struct tid_group {
	struct list_head list;
	unsigned base;
	u8 size;
	u8 used;
	u8 map;
};

struct mmu_rb_node {
struct mmu_rb_node {
	struct rb_node rbnode;
	struct rb_node rbnode;
	unsigned long virt;
	unsigned long virt;
@@ -75,6 +83,8 @@ static const char * const mmu_types[] = {
	"RANGE"
	"RANGE"
};
};


#define EXP_TID_SET_EMPTY(set) (set.count == 0 && list_empty(&set.list))

static inline int mmu_addr_cmp(struct mmu_rb_node *, unsigned long,
static inline int mmu_addr_cmp(struct mmu_rb_node *, unsigned long,
			       unsigned long);
			       unsigned long);
static struct mmu_rb_node *mmu_rb_search_by_addr(struct rb_root *,
static struct mmu_rb_node *mmu_rb_search_by_addr(struct rb_root *,
@@ -94,6 +104,43 @@ static inline void mmu_notifier_range_start(struct mmu_notifier *,
					    struct mm_struct *,
					    struct mm_struct *,
					    unsigned long, unsigned long);
					    unsigned long, unsigned long);


static inline void exp_tid_group_init(struct exp_tid_set *set)
{
	INIT_LIST_HEAD(&set->list);
	set->count = 0;
}

static inline void tid_group_remove(struct tid_group *grp,
				    struct exp_tid_set *set)
{
	list_del_init(&grp->list);
	set->count--;
}

static inline void tid_group_add_tail(struct tid_group *grp,
				      struct exp_tid_set *set)
{
	list_add_tail(&grp->list, &set->list);
	set->count++;
}

static inline struct tid_group *tid_group_pop(struct exp_tid_set *set)
{
	struct tid_group *grp =
		list_first_entry(&set->list, struct tid_group, list);
	list_del_init(&grp->list);
	set->count--;
	return grp;
}

static inline void tid_group_move(struct tid_group *group,
				  struct exp_tid_set *s1,
				  struct exp_tid_set *s2)
{
	tid_group_remove(group, s1);
	tid_group_add_tail(group, s2);
}

static struct mmu_notifier_ops __maybe_unused mn_opts = {
static struct mmu_notifier_ops __maybe_unused mn_opts = {
	.invalidate_page = mmu_notifier_page,
	.invalidate_page = mmu_notifier_page,
	.invalidate_range_start = mmu_notifier_range_start,
	.invalidate_range_start = mmu_notifier_range_start,
@@ -114,6 +161,23 @@ int hfi1_user_exp_rcv_free(struct hfi1_filedata *fd)
	return -EINVAL;
	return -EINVAL;
}
}


/*
 * Write an "empty" RcvArray entry.
 * This function exists so the TID registaration code can use it
 * to write to unused/unneeded entries and still take advantage
 * of the WC performance improvements. The HFI will ignore this
 * write to the RcvArray entry.
 */
static inline void rcv_array_wc_fill(struct hfi1_devdata *dd, u32 index)
{
	/*
	 * Doing the WC fill writes only makes sense if the device is
	 * present and the RcvArray has been mapped as WC memory.
	 */
	if ((dd->flags & HFI1_PRESENT) && dd->rcvarray_wc)
		writeq(0, dd->rcvarray_wc + (index * 8));
}

int hfi1_user_exp_rcv_setup(struct file *fp, struct hfi1_tid_info *tinfo)
int hfi1_user_exp_rcv_setup(struct file *fp, struct hfi1_tid_info *tinfo)
{
{
	return -EINVAL;
	return -EINVAL;