linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Unexpected behavior from xarray - Is it expected?
@ 2020-07-14 11:24 Boaz Harrosh
  2020-07-14 13:17 ` Boaz Harrosh
  2020-07-14 13:46 ` Matthew Wilcox
  0 siblings, 2 replies; 4+ messages in thread
From: Boaz Harrosh @ 2020-07-14 11:24 UTC (permalink / raw)
  To: Matthew Wilcox, linux-fsdevel

Matthew Hi

First I want to thank you for the great xarray tool. I use it heavily with great joy & ease

However I have encountered a bug in my code which I did not expect, as follows:

I need code in the very hot-path that is looping on the xarray in an unusual way.
What I need is to scan a range from x-x+l but I need to break on first "hole" ie.
first entry that was not __xa_store() to. So I am using this loop:
	rcu_read_lock();

	for (xae = xas_load(&xas); xae; xae = xas_next(&xas)) {
		...
	}

Every thing works fine and I usually get a NULL from xas_next() (or xas_load())
on first hole, And the loop exits.

But in the case that I have entered a *single* xa_store() *at index 0*, but then try
to GET a range 0-Y I get these unexpected results:
	xas_next() will return the same entry repeatedly
I have put some prints (see full code below):

zuf: pi_pr [zuf_pi_get_range:248] [5] [@x0] GET bn=0x11e8 xae=0x23d1 xa_index=0x0 xa_offset=0x0
zuf: pi_pr [zuf_pi_get_range:248] [5] [@x1] GET bn=0x11e8 xae=0x23d1 xa_index=0x1 xa_offset=0x0
zuf: pi_pr [zuf_pi_get_range:248] [5] [@x2] GET bn=0x11e8 xae=0x23d1 xa_index=0x2 xa_offset=0x0
zuf: pi_pr [zuf_pi_get_range:248] [5] [@x3] GET bn=0x11e8 xae=0x23d1 xa_index=0x3 xa_offset=0x0
zuf: pi_pr [zuf_pi_get_range:248] [5] [@x4] GET bn=0x11e8 xae=0x23d1 xa_index=0x4 xa_offset=0x0
zuf: pi_pr [zuf_pi_get_range:248] [5] [@x5] GET bn=0x11e8 xae=0x23d1 xa_index=0x5 xa_offset=0x0
zuf: pi_pr [zuf_pi_get_range:248] [5] [@x6] GET bn=0x11e8 xae=0x23d1 xa_index=0x6 xa_offset=0x0

The loop only stopped because of some other condition.

[Q] Is this expected from a single xa_store() at 0?

[I am not even sure how to safely check this because consecutive entries may have
 the same exact value.

 Should I check for xa_offset not changing or should I use something else other than
 xas_next()?

 Do I must use xa_load() and take/release the rcu_lock every iteration?
]

Here is the full code.

<pi.c>
#include <linux/xarray.h>

#define xa_2_bn(xae)	xa_to_value(xae)

struct _pi_info {
	/* IN */
	ulong start;	/* start index to get	*/
	uint requested;	/* Num bns requested	*/
	/* OUT */
	ulong *bns;	/* array of block-numbers */
	uint cached;	/* Number of bns filled from page-index */
};

void zuf_pi_get_range(struct inode *inode, struct _pi_info *pi)
{
	XA_STATE(xas, &inode->i_mapping->i_pages, pi->start);
	void *xae;

	rcu_read_lock();

	for (xae = xas_load(&xas); xae; xae = xas_next(&xas)) {
		ulong  bn;

		if (xas_retry(&xas, xae)) {
			zuf_warn("See this yet e=0x%lx" _FMT_XAS "\n",
				 (ulong)xae, _PR_XAS(xas));
			continue;
		}

		bn = xa_2_bn(xae);

		zuf_dbg_pi("[%ld] [@x%lx] GET bn=0x%lx xae=0x%lx xa_index=0x%lx xa_offset=0x%x\n",
			   inode->i_ino, pi->start + pi->cached, bn, (ulong)xae, xas.xa_index, xas.xa_offset);

		pi->bns[pi->cached++] = bn;
		if (pi->cached == pi->requested)
			break; /* ALL DONE */
	}

	rcu_read_unlock();
}
<pi.c>

Thank you for looking, good day
Boaz


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-07-14 19:46 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-07-14 11:24 Unexpected behavior from xarray - Is it expected? Boaz Harrosh
2020-07-14 13:17 ` Boaz Harrosh
2020-07-14 13:46 ` Matthew Wilcox
2020-07-14 17:54   ` Boaz Harrosh

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).