22// / \brief Implementation of the DmaChannelBase class.
33// /
44// / \author Pascal Boeschoten ([email protected] )5+ // / \author Kostas Alexopoulos ([email protected] )56
67#include < boost/filesystem.hpp>
78#include " DmaChannelBase.h"
89#include < iostream>
9- #include " ChannelPaths.h"
10+ // #include "ChannelPaths.h"
1011#include " Common/System.h"
1112#include " Utilities/SmartPointer.h"
1213#include " Visitor.h"
@@ -47,6 +48,48 @@ void DmaChannelBase::checkParameters(Parameters& parameters)
4748 }
4849}
4950
51+ void DmaChannelBase::freeUnusedChannelBuffer ()
52+ {
53+ namespace bfs = boost::filesystem;
54+ InfoLogger::InfoLogger logger;
55+
56+ try {
57+ Pda::PdaLock lock{}; // We're messing around with PDA buffers so we need this even though we hold the DMA lock
58+ } catch (const LockException& exception) {
59+ log (" Failed to acquire PDA lock" , InfoLogger::InfoLogger::Debug);
60+ throw ;
61+ }
62+
63+ try {
64+ std::string pciPath = " /sys/bus/pci/drivers/uio_pci_dma/" ;
65+ if (boost::filesystem::exists (pciPath)) {
66+ for (auto &entry : boost::make_iterator_range (bfs::directory_iterator (pciPath), {})) {
67+ auto filename = entry.path ().filename ().string ();
68+ if (filename.size () == 12 ) {
69+ // The PCI directory names are 12 characters long
70+ auto pciAddress = filename.substr (5 ); // Remove leading '0000:'
71+
72+ if (PciAddress::fromString (pciAddress) && (pciAddress == mCardDescriptor .pciAddress .toString ())) {
73+ // This is a valid PCI address and it's *ours*
74+ std::string dmaPath (" /sys/bus/pci/drivers/uio_pci_dma/" + filename + " /dma" );
75+ for (auto &entry : boost::make_iterator_range (bfs::directory_iterator (dmaPath), {})) {
76+ auto bufferId = entry.path ().filename ().string ();
77+ if (bfs::is_directory (entry)) {
78+ std::string mapPath = dmaPath + " /" + bufferId + " /map" ;
79+ std::string freePath = dmaPath + " /free" ;
80+ logger << " Freeing PDA buffer '" + mapPath + " '" << InfoLogger::InfoLogger::endm;
81+ AliceO2::Common::System::executeCommand (" echo " + bufferId + " > " + freePath);
82+ }
83+ }
84+ }
85+ }
86+ }
87+ }
88+ } catch (const boost::filesystem::filesystem_error &e) {
89+ logger << " Failed to free buffers: " << e.what () << InfoLogger::InfoLogger::endm;
90+ throw ;
91+ }
92+ }
5093
5194DmaChannelBase::DmaChannelBase (CardDescriptor cardDescriptor, Parameters& parameters,
5295 const AllowedChannels& allowedChannels)
@@ -62,41 +105,24 @@ DmaChannelBase::DmaChannelBase(CardDescriptor cardDescriptor, Parameters& parame
62105 // Do some basic Parameters validity checks
63106 checkParameters (parameters);
64107
65- // Create parent directories
66- auto paths = getPaths ();
67- for (const auto & p : {paths.fifo (), paths.lock ()}) {
68- Common::System::makeParentDirectories (p);
69- }
70-
71- // Get lock
108+ // try to acquire lock
72109 log (" Acquiring DMA channel lock" , InfoLogger::InfoLogger::Debug);
73- try {
74- Utilities::resetSmartPtr (mInterprocessLock , paths. lock (), paths. namedMutex () );
110+ try {
111+ Utilities::resetSmartPtr (mInterprocessLock , " Alice_O2_RoC_DMA_ " + cardDescriptor. pciAddress . toString () + " _lock " );
75112 }
76- catch (const NamedMutexLockException& exception) {
77- if (parameters.getForcedUnlockEnabled ().get_value_or (false )) {
78- log (" Failed to acquire DMA channel mutex. Forced unlock enabled - attempting cleanup and retry" ,
79- InfoLogger::InfoLogger::Warning);
80- // The user has indicated to the driver that it is safe to force the unlock. We do it by deleting the lock.
81- boost::interprocess::named_mutex::remove (paths.namedMutex ().c_str ());
82- // Try again...
83- Utilities::resetSmartPtr (mInterprocessLock , paths.lock (), paths.namedMutex ());
84- } else {
85- log (" Failed to acquire DMA channel lock" , InfoLogger::InfoLogger::Debug);
86- throw ;
87- }
113+ catch (const LockException& exception) {
114+ log (" Failed to acquire DMA channel lock" , InfoLogger::InfoLogger::Debug);
115+ throw ;
88116 }
117+
89118 log (" Acquired DMA channel lock" , InfoLogger::InfoLogger::Debug);
119+
120+ freeUnusedChannelBuffer ();
90121}
91122
92123DmaChannelBase::~DmaChannelBase ()
93124{
94125 log (" Releasing DMA channel lock" , InfoLogger::InfoLogger::Debug);
95-
96- std::string channelLockPath = " /dev/shm/AliceO2_RoC_" + std::string (getCardDescriptor ().pciAddress .toString ()) + " _Channel_" + std::to_string ((int ) getChannelNumber ()) + " .lock" ;
97- std::string channelMutexPath = " /dev/shm/sem.AliceO2_RoC_" + std::string (getCardDescriptor ().pciAddress .toString ()) + " _Channel_" + std::to_string ((int ) getChannelNumber ()) + " _Mutex" ;
98- bfs::remove (channelLockPath);
99- bfs::remove (channelMutexPath);
100126}
101127
102128void DmaChannelBase::log (const std::string& message, boost::optional<InfoLogger::InfoLogger::Severity> severity)
0 commit comments