Pārlūkot izejas kodu

data_request: for prefetches, only take a reference on the destination replicate when really transferring

For fetches, we want to make sure to keep the room as soon as the fetch
request, to avoid interlocks. For prefetches however, we want to allow
buffer eviction to proceed, since we may get processed way later.
Samuel Thibault 4 gadi atpakaļ
vecāks
revīzija
d5b9886019
2 mainītis faili ar 17 papildinājumiem un 2 dzēšanām
  1. 8 0
      src/datawizard/copy_driver.c
  2. 9 2
      src/datawizard/data_request.c

+ 8 - 0
src/datawizard/copy_driver.c

@@ -203,12 +203,20 @@ int STARPU_ATTRIBUTE_WARN_UNUSED_RESULT _starpu_driver_copy_data_1_to_1(starpu_d
 									unsigned may_alloc,
 									enum starpu_is_prefetch prefetch STARPU_ATTRIBUTE_UNUSED)
 {
+	_starpu_spin_checklocked(&handle->header_lock);
+
 	if (!donotread)
 	{
 		STARPU_ASSERT(src_replicate->allocated);
 		STARPU_ASSERT(src_replicate->refcnt);
 	}
 
+	/* For prefetches, we take a reference on the destination only now that
+	 * we will really try to fetch the data (instead of in
+	 * _starpu_create_data_request) */
+	if (req->prefetch > STARPU_FETCH)
+		dst_replicate->refcnt++;
+
 	unsigned src_node = src_replicate->memory_node;
 	unsigned dst_node = dst_replicate->memory_node;
 

+ 9 - 2
src/datawizard/data_request.c

@@ -194,8 +194,9 @@ struct _starpu_data_request *_starpu_create_data_request(starpu_data_handle_t ha
 
 	_starpu_spin_lock(&r->lock);
 
-	/* Take a reference on the target for the request to be able to write it */
-	if (dst_replicate)
+	/* For a fetch, take a reference as soon as now on the target, to avoid
+	 * replicate eviction */
+	if (is_prefetch == STARPU_FETCH && dst_replicate)
 		dst_replicate->refcnt++;
 	handle->busy_count++;
 
@@ -882,7 +883,13 @@ int _starpu_check_that_no_data_request_is_pending(unsigned node, unsigned peer_n
 
 void _starpu_update_prefetch_status(struct _starpu_data_request *r, enum starpu_is_prefetch prefetch)
 {
+	_starpu_spin_checklocked(&r->handle->header_lock);
 	STARPU_ASSERT(r->prefetch > prefetch);
+
+	if (prefetch == STARPU_FETCH)
+		/* That would have been done by _starpu_create_data_request */
+		r->dst_replicate->refcnt++;
+
 	r->prefetch=prefetch;
 
 	if (prefetch >= STARPU_IDLEFETCH)