15
15
#include <linux/module.h>
16
16
#include <linux/random.h>
17
17
#include <linux/rculist.h>
18
+ #include <linux/pci-p2pdma.h>
18
19
19
20
#include "nvmet.h"
20
21
@@ -365,9 +366,93 @@ static void nvmet_ns_dev_disable(struct nvmet_ns *ns)
365
366
nvmet_file_ns_disable (ns );
366
367
}
367
368
369
+ static int nvmet_p2pmem_ns_enable (struct nvmet_ns * ns )
370
+ {
371
+ int ret ;
372
+ struct pci_dev * p2p_dev ;
373
+
374
+ if (!ns -> use_p2pmem )
375
+ return 0 ;
376
+
377
+ if (!ns -> bdev ) {
378
+ pr_err ("peer-to-peer DMA is not supported by non-block device namespaces\n" );
379
+ return - EINVAL ;
380
+ }
381
+
382
+ if (!blk_queue_pci_p2pdma (ns -> bdev -> bd_queue )) {
383
+ pr_err ("peer-to-peer DMA is not supported by the driver of %s\n" ,
384
+ ns -> device_path );
385
+ return - EINVAL ;
386
+ }
387
+
388
+ if (ns -> p2p_dev ) {
389
+ ret = pci_p2pdma_distance (ns -> p2p_dev , nvmet_ns_dev (ns ), true);
390
+ if (ret < 0 )
391
+ return - EINVAL ;
392
+ } else {
393
+ /*
394
+ * Right now we just check that there is p2pmem available so
395
+ * we can report an error to the user right away if there
396
+ * is not. We'll find the actual device to use once we
397
+ * setup the controller when the port's device is available.
398
+ */
399
+
400
+ p2p_dev = pci_p2pmem_find (nvmet_ns_dev (ns ));
401
+ if (!p2p_dev ) {
402
+ pr_err ("no peer-to-peer memory is available for %s\n" ,
403
+ ns -> device_path );
404
+ return - EINVAL ;
405
+ }
406
+
407
+ pci_dev_put (p2p_dev );
408
+ }
409
+
410
+ return 0 ;
411
+ }
412
+
413
+ /*
414
+ * Note: ctrl->subsys->lock should be held when calling this function
415
+ */
416
+ static void nvmet_p2pmem_ns_add_p2p (struct nvmet_ctrl * ctrl ,
417
+ struct nvmet_ns * ns )
418
+ {
419
+ struct device * clients [2 ];
420
+ struct pci_dev * p2p_dev ;
421
+ int ret ;
422
+
423
+ if (!ctrl -> p2p_client )
424
+ return ;
425
+
426
+ if (ns -> p2p_dev ) {
427
+ ret = pci_p2pdma_distance (ns -> p2p_dev , ctrl -> p2p_client , true);
428
+ if (ret < 0 )
429
+ return ;
430
+
431
+ p2p_dev = pci_dev_get (ns -> p2p_dev );
432
+ } else {
433
+ clients [0 ] = ctrl -> p2p_client ;
434
+ clients [1 ] = nvmet_ns_dev (ns );
435
+
436
+ p2p_dev = pci_p2pmem_find_many (clients , ARRAY_SIZE (clients ));
437
+ if (!p2p_dev ) {
438
+ pr_err ("no peer-to-peer memory is available that's supported by %s and %s\n" ,
439
+ dev_name (ctrl -> p2p_client ), ns -> device_path );
440
+ return ;
441
+ }
442
+ }
443
+
444
+ ret = radix_tree_insert (& ctrl -> p2p_ns_map , ns -> nsid , p2p_dev );
445
+ if (ret < 0 )
446
+ pci_dev_put (p2p_dev );
447
+
448
+ pr_info ("using p2pmem on %s for nsid %d\n" , pci_name (p2p_dev ),
449
+ ns -> nsid );
450
+ }
451
+
368
452
int nvmet_ns_enable (struct nvmet_ns * ns )
369
453
{
370
454
struct nvmet_subsys * subsys = ns -> subsys ;
455
+ struct nvmet_ctrl * ctrl ;
371
456
int ret ;
372
457
373
458
mutex_lock (& subsys -> lock );
@@ -384,6 +469,13 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
384
469
if (ret )
385
470
goto out_unlock ;
386
471
472
+ ret = nvmet_p2pmem_ns_enable (ns );
473
+ if (ret )
474
+ goto out_unlock ;
475
+
476
+ list_for_each_entry (ctrl , & subsys -> ctrls , subsys_entry )
477
+ nvmet_p2pmem_ns_add_p2p (ctrl , ns );
478
+
387
479
ret = percpu_ref_init (& ns -> ref , nvmet_destroy_namespace ,
388
480
0 , GFP_KERNEL );
389
481
if (ret )
@@ -418,13 +510,17 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
418
510
mutex_unlock (& subsys -> lock );
419
511
return ret ;
420
512
out_dev_put :
513
+ list_for_each_entry (ctrl , & subsys -> ctrls , subsys_entry )
514
+ pci_dev_put (radix_tree_delete (& ctrl -> p2p_ns_map , ns -> nsid ));
515
+
421
516
nvmet_ns_dev_disable (ns );
422
517
goto out_unlock ;
423
518
}
424
519
425
520
void nvmet_ns_disable (struct nvmet_ns * ns )
426
521
{
427
522
struct nvmet_subsys * subsys = ns -> subsys ;
523
+ struct nvmet_ctrl * ctrl ;
428
524
429
525
mutex_lock (& subsys -> lock );
430
526
if (!ns -> enabled )
@@ -434,6 +530,10 @@ void nvmet_ns_disable(struct nvmet_ns *ns)
434
530
list_del_rcu (& ns -> dev_link );
435
531
if (ns -> nsid == subsys -> max_nsid )
436
532
subsys -> max_nsid = nvmet_max_nsid (subsys );
533
+
534
+ list_for_each_entry (ctrl , & subsys -> ctrls , subsys_entry )
535
+ pci_dev_put (radix_tree_delete (& ctrl -> p2p_ns_map , ns -> nsid ));
536
+
437
537
mutex_unlock (& subsys -> lock );
438
538
439
539
/*
@@ -450,6 +550,7 @@ void nvmet_ns_disable(struct nvmet_ns *ns)
450
550
percpu_ref_exit (& ns -> ref );
451
551
452
552
mutex_lock (& subsys -> lock );
553
+
453
554
subsys -> nr_namespaces -- ;
454
555
nvmet_ns_changed (subsys , ns -> nsid );
455
556
nvmet_ns_dev_disable (ns );
@@ -727,6 +828,29 @@ EXPORT_SYMBOL_GPL(nvmet_req_execute);
727
828
728
829
int nvmet_req_alloc_sgl (struct nvmet_req * req )
729
830
{
831
+ struct pci_dev * p2p_dev = NULL ;
832
+
833
+ if (IS_ENABLED (CONFIG_PCI_P2PDMA )) {
834
+ if (req -> sq -> ctrl && req -> ns )
835
+ p2p_dev = radix_tree_lookup (& req -> sq -> ctrl -> p2p_ns_map ,
836
+ req -> ns -> nsid );
837
+
838
+ req -> p2p_dev = NULL ;
839
+ if (req -> sq -> qid && p2p_dev ) {
840
+ req -> sg = pci_p2pmem_alloc_sgl (p2p_dev , & req -> sg_cnt ,
841
+ req -> transfer_len );
842
+ if (req -> sg ) {
843
+ req -> p2p_dev = p2p_dev ;
844
+ return 0 ;
845
+ }
846
+ }
847
+
848
+ /*
849
+ * If no P2P memory was available we fallback to using
850
+ * regular memory
851
+ */
852
+ }
853
+
730
854
req -> sg = sgl_alloc (req -> transfer_len , GFP_KERNEL , & req -> sg_cnt );
731
855
if (!req -> sg )
732
856
return - ENOMEM ;
@@ -737,7 +861,11 @@ EXPORT_SYMBOL_GPL(nvmet_req_alloc_sgl);
737
861
738
862
void nvmet_req_free_sgl (struct nvmet_req * req )
739
863
{
740
- sgl_free (req -> sg );
864
+ if (req -> p2p_dev )
865
+ pci_p2pmem_free_sgl (req -> p2p_dev , req -> sg );
866
+ else
867
+ sgl_free (req -> sg );
868
+
741
869
req -> sg = NULL ;
742
870
req -> sg_cnt = 0 ;
743
871
}
@@ -939,6 +1067,37 @@ bool nvmet_host_allowed(struct nvmet_req *req, struct nvmet_subsys *subsys,
939
1067
return __nvmet_host_allowed (subsys , hostnqn );
940
1068
}
941
1069
1070
+ /*
1071
+ * Note: ctrl->subsys->lock should be held when calling this function
1072
+ */
1073
+ static void nvmet_setup_p2p_ns_map (struct nvmet_ctrl * ctrl ,
1074
+ struct nvmet_req * req )
1075
+ {
1076
+ struct nvmet_ns * ns ;
1077
+
1078
+ if (!req -> p2p_client )
1079
+ return ;
1080
+
1081
+ ctrl -> p2p_client = get_device (req -> p2p_client );
1082
+
1083
+ list_for_each_entry_rcu (ns , & ctrl -> subsys -> namespaces , dev_link )
1084
+ nvmet_p2pmem_ns_add_p2p (ctrl , ns );
1085
+ }
1086
+
1087
+ /*
1088
+ * Note: ctrl->subsys->lock should be held when calling this function
1089
+ */
1090
+ static void nvmet_release_p2p_ns_map (struct nvmet_ctrl * ctrl )
1091
+ {
1092
+ struct radix_tree_iter iter ;
1093
+ void __rcu * * slot ;
1094
+
1095
+ radix_tree_for_each_slot (slot , & ctrl -> p2p_ns_map , & iter , 0 )
1096
+ pci_dev_put (radix_tree_deref_slot (slot ));
1097
+
1098
+ put_device (ctrl -> p2p_client );
1099
+ }
1100
+
942
1101
u16 nvmet_alloc_ctrl (const char * subsysnqn , const char * hostnqn ,
943
1102
struct nvmet_req * req , u32 kato , struct nvmet_ctrl * * ctrlp )
944
1103
{
@@ -980,6 +1139,7 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,
980
1139
981
1140
INIT_WORK (& ctrl -> async_event_work , nvmet_async_event_work );
982
1141
INIT_LIST_HEAD (& ctrl -> async_events );
1142
+ INIT_RADIX_TREE (& ctrl -> p2p_ns_map , GFP_KERNEL );
983
1143
984
1144
memcpy (ctrl -> subsysnqn , subsysnqn , NVMF_NQN_SIZE );
985
1145
memcpy (ctrl -> hostnqn , hostnqn , NVMF_NQN_SIZE );
@@ -1044,6 +1204,7 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,
1044
1204
1045
1205
mutex_lock (& subsys -> lock );
1046
1206
list_add_tail (& ctrl -> subsys_entry , & subsys -> ctrls );
1207
+ nvmet_setup_p2p_ns_map (ctrl , req );
1047
1208
mutex_unlock (& subsys -> lock );
1048
1209
1049
1210
* ctrlp = ctrl ;
@@ -1071,6 +1232,7 @@ static void nvmet_ctrl_free(struct kref *ref)
1071
1232
struct nvmet_subsys * subsys = ctrl -> subsys ;
1072
1233
1073
1234
mutex_lock (& subsys -> lock );
1235
+ nvmet_release_p2p_ns_map (ctrl );
1074
1236
list_del (& ctrl -> subsys_entry );
1075
1237
mutex_unlock (& subsys -> lock );
1076
1238
0 commit comments