HFI: fix tidinfo and length calculation in program_rcvarray()
This commit is contained in:
@ -60,10 +60,10 @@
|
|||||||
#define dkprintf(...) do { if(0) kprintf(__VA_ARGS__); } while (0)
|
#define dkprintf(...) do { if(0) kprintf(__VA_ARGS__); } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int program_rcvarray(struct hfi1_filedata *, uintptr_t, size_t, u32 *);
|
static int program_rcvarray(struct hfi1_filedata *, unsigned long, uintptr_t,
|
||||||
static int set_rcvarray_entry(struct hfi1_filedata *, uintptr_t,
|
size_t, u32 *);
|
||||||
u32, struct tid_group *,
|
static int set_rcvarray_entry(struct hfi1_filedata *, unsigned long, uintptr_t,
|
||||||
u16);
|
u32, struct tid_group *, int, u32);
|
||||||
static int unprogram_rcvarray(struct hfi1_filedata *, u32, struct tid_group **);
|
static int unprogram_rcvarray(struct hfi1_filedata *, u32, struct tid_group **);
|
||||||
static void clear_tid_node(struct hfi1_filedata *, struct tid_rb_node *);
|
static void clear_tid_node(struct hfi1_filedata *, struct tid_rb_node *);
|
||||||
|
|
||||||
@ -170,7 +170,7 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd, struct hfi1_tid_info *tinf
|
|||||||
len = MAX_EXPECTED_BUFFER;
|
len = MAX_EXPECTED_BUFFER;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = program_rcvarray(fd, phys, len, tidlist + tididx);
|
ret = program_rcvarray(fd, vaddr, phys, len, tidlist + tididx);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
kprintf("Failed to program RcvArray entries: %d\n",
|
kprintf("Failed to program RcvArray entries: %d\n",
|
||||||
ret);
|
ret);
|
||||||
@ -240,23 +240,32 @@ int hfi1_user_exp_rcv_clear(struct hfi1_filedata *fd, struct hfi1_tid_info *tinf
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kprintf("%s: 0x%llx:%lu -> %d TIDs unprogrammed\n",
|
||||||
|
__FUNCTION__, tinfo->vaddr, tinfo->length, tinfo->tidcnt);
|
||||||
|
|
||||||
|
spin_lock(&fd->tid_lock);
|
||||||
fd->tid_used -= tididx;
|
fd->tid_used -= tididx;
|
||||||
|
spin_unlock(&fd->tid_lock);
|
||||||
|
|
||||||
tinfo->tidcnt = tididx;
|
tinfo->tidcnt = tididx;
|
||||||
done:
|
done:
|
||||||
kfree(tidinfo);
|
kfree(tidinfo);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* program_rcvarray() - program an RcvArray group with receive buffers
|
* program_rcvarray() - program an RcvArray group with receive buffers
|
||||||
*/
|
*/
|
||||||
static int program_rcvarray(struct hfi1_filedata *fd, uintptr_t phys,
|
static int program_rcvarray(struct hfi1_filedata *fd,
|
||||||
|
unsigned long vaddr,
|
||||||
|
uintptr_t phys,
|
||||||
size_t len, u32 *ptid)
|
size_t len, u32 *ptid)
|
||||||
{
|
{
|
||||||
struct hfi1_ctxtdata *uctxt = fd->uctxt;
|
struct hfi1_ctxtdata *uctxt = fd->uctxt;
|
||||||
struct hfi1_devdata *dd = uctxt->dd;
|
struct hfi1_devdata *dd = uctxt->dd;
|
||||||
u16 idx = 0;
|
u16 idx = 0;
|
||||||
s16 order;
|
|
||||||
u32 tidinfo = 0, rcventry;
|
u32 tidinfo = 0, rcventry;
|
||||||
int ret = -ENOMEM, count = 0;
|
int ret = -ENOMEM, count = 0;
|
||||||
struct tid_group *grp = NULL;
|
struct tid_group *grp = NULL;
|
||||||
@ -264,6 +273,9 @@ static int program_rcvarray(struct hfi1_filedata *fd, uintptr_t phys,
|
|||||||
/* lock is taken at loop edges */
|
/* lock is taken at loop edges */
|
||||||
spin_lock(&fd->tid_lock);
|
spin_lock(&fd->tid_lock);
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
|
size_t tid_len;
|
||||||
|
size_t tid_npages;
|
||||||
|
|
||||||
if (!grp) {
|
if (!grp) {
|
||||||
if (!uctxt->tid_used_list.count) {
|
if (!uctxt->tid_used_list.count) {
|
||||||
if (!uctxt->tid_group_list.count) {
|
if (!uctxt->tid_group_list.count) {
|
||||||
@ -286,26 +298,23 @@ static int program_rcvarray(struct hfi1_filedata *fd, uintptr_t phys,
|
|||||||
}
|
}
|
||||||
spin_unlock(&fd->tid_lock);
|
spin_unlock(&fd->tid_lock);
|
||||||
|
|
||||||
|
tid_len = (len > MAX_EXPECTED_BUFFER) ? MAX_EXPECTED_BUFFER :
|
||||||
/* order is power of two of 4k (2^12) pages */
|
(1 << (fls(len) - 1));
|
||||||
order = fls(len) - 13;
|
tid_npages = (tid_len > PAGE_SIZE) ? tid_len >> PAGE_SHIFT : 1;
|
||||||
if (order < 0)
|
|
||||||
order = 0;
|
|
||||||
dkprintf("len %u, order %u\n", len, order);
|
|
||||||
|
|
||||||
rcventry = grp->base + idx;
|
rcventry = grp->base + idx;
|
||||||
rcv_array_wc_fill(dd, rcventry);
|
rcv_array_wc_fill(dd, rcventry);
|
||||||
ret = set_rcvarray_entry(fd, phys, rcventry, grp,
|
tidinfo = rcventry2tidinfo(rcventry - uctxt->expected_base) |
|
||||||
order);
|
EXP_TID_SET(LEN, tid_npages);
|
||||||
|
ret = set_rcvarray_entry(fd, vaddr, phys, rcventry,
|
||||||
|
grp, tid_npages, tidinfo);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
tidinfo = rcventry2tidinfo(rcventry - uctxt->expected_base) |
|
|
||||||
EXP_TID_SET(LEN, 1 << order);
|
|
||||||
ptid[count++] = tidinfo;
|
ptid[count++] = tidinfo;
|
||||||
len -= 1 << (order + 12);
|
len -= tid_len;
|
||||||
phys += 1 << (order + 12);
|
vaddr += tid_len;
|
||||||
|
phys += tid_len;
|
||||||
|
|
||||||
spin_lock(&fd->tid_lock);
|
spin_lock(&fd->tid_lock);
|
||||||
grp->used++;
|
grp->used++;
|
||||||
@ -327,10 +336,10 @@ static int program_rcvarray(struct hfi1_filedata *fd, uintptr_t phys,
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_rcvarray_entry(struct hfi1_filedata *fd,
|
||||||
static int set_rcvarray_entry(struct hfi1_filedata *fd, uintptr_t phys,
|
unsigned long vaddr, uintptr_t phys,
|
||||||
u32 rcventry, struct tid_group *grp,
|
u32 rcventry, struct tid_group *grp,
|
||||||
u16 order)
|
int npages, u32 tidinfo)
|
||||||
{
|
{
|
||||||
struct hfi1_ctxtdata *uctxt = fd->uctxt;
|
struct hfi1_ctxtdata *uctxt = fd->uctxt;
|
||||||
struct hfi1_devdata *dd = uctxt->dd;
|
struct hfi1_devdata *dd = uctxt->dd;
|
||||||
@ -346,18 +355,17 @@ static int set_rcvarray_entry(struct hfi1_filedata *fd, uintptr_t phys,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
dkprintf("Registering rcventry %d, phys 0x%p, len %u\n", rcventry,
|
dkprintf("Registering rcventry %d, phys 0x%p, len %u\n", rcventry,
|
||||||
phys, 1 << (order+12));
|
phys, npages << PAGE_SHIFT);
|
||||||
|
|
||||||
node->phys = phys;
|
node->phys = phys;
|
||||||
node->len = 1 << (order+12);
|
node->len = npages << PAGE_SHIFT;
|
||||||
node->rcventry = rcventry;
|
node->rcventry = rcventry;
|
||||||
node->grp = grp;
|
node->grp = grp;
|
||||||
// TODO: check node->rcventry - uctxt->expected_base is within
|
// TODO: check node->rcventry - uctxt->expected_base is within
|
||||||
// [0; uctxt->expected_count[ ?
|
// [0; uctxt->expected_count[ ?
|
||||||
fd->entry_to_rb[node->rcventry - uctxt->expected_base] = node;
|
fd->entry_to_rb[node->rcventry - uctxt->expected_base] = node;
|
||||||
|
|
||||||
|
hfi1_put_tid(dd, rcventry, PT_EXPECTED, phys, fls(npages));
|
||||||
hfi1_put_tid(dd, rcventry, PT_EXPECTED, phys, order+1);
|
|
||||||
#if 0
|
#if 0
|
||||||
trace_hfi1_exp_tid_reg(uctxt->ctxt, fd->subctxt, rcventry, npages,
|
trace_hfi1_exp_tid_reg(uctxt->ctxt, fd->subctxt, rcventry, npages,
|
||||||
node->mmu.addr, node->phys, phys);
|
node->mmu.addr, node->phys, phys);
|
||||||
|
|||||||
Reference in New Issue
Block a user