How does Linux kernel handle the concurrent file lookup - concurrency

Assuming there are two processes looking up a file at the same time, and this file does not existed in the dcache yet. These two lookups will return NULL (dentry) to the process.
My question is that how does Linux kernel ensure that after a failed dentry lookup, it only creates one dentry?

1912 /**
1913 * d_lookup - search for a dentry
1914 * #parent: parent dentry
1915 * #name: qstr of name we wish to find
1916 * Returns: dentry, or NULL
1917 *
1918 * d_lookup searches the children of the parent dentry for the name in
1919 * question. If the dentry is found its reference count is incremented and the
1920 * dentry is returned. The caller must use dput to free the entry when it has
1921 * finished using it. %NULL is returned if the dentry does not exist.
1922 */
d_lookup does not create any dentry objects by yourself. Take a look at the do_filp_open logic and it shows how dentries are created.

Related

DFU bootloader immediately jumping to application in STM32F405RG

I am trying to immediately jump to the DFU bootloader via software on the STM32F405RG, but instead it is doing a software reset and the RCC_FLAG_SFTRST flag is thrown. The program continues to repeatedly execute the code for jumping to bootloader and finally stays in bootloader mode after multiple seconds. I experienced success with entering bootloader mode on the first try if interrupts are disabled. However, I cannot upload code while in DFU mode since it requires interrupts to be enabled. I am unsure what is causing the bootloader to jump back to the application and was hoping to get assistance on this. Below is the code for jumping to bootloader, which is called immediately after Init_HAL() under main.
void JumpToBootloader(void) {
void (*SysMemBootJump)(void);
volatile uint32_t addr = 0x1FFF0000;
HAL_RCC_DeInit();
HAL_DeInit();
/**
* Step: Disable systick timer and reset it to default values
*/
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
/**
* Step: Interrupts are not disabled since they are needed for DFU mode
*/
// __disable_irq();
/**
* Step: Remap system memory to address 0x0000 0000 in address space
* For each family registers may be different.
* Check reference manual for each family.
*
* For STM32F4xx, MEMRMP register in SYSCFG is used (bits[1:0])
* For STM32F0xx, CFGR1 register in SYSCFG is used (bits[1:0])
* For others, check family reference manual
*/
__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH(); //Call HAL macro to do this for you
/**
* Step: Set jump memory location for system memory
* Use address with 4 bytes offset which specifies jump location where program starts
*/
SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4)));
/**
* Step: Set main stack pointer.
* This step must be done last otherwise local variables in this function
* don't have proper value since stack pointer is located on different position
*
* Set direct address location which specifies stack pointer in SRAM location
*/
__set_MSP(*(uint32_t *)addr);
/**
* Step: Actually call our function to jump to set location
* This will start system memory execution
*/
SysMemBootJump();
}
Taking a look at the Application Note AN2606, Rev.55, chapter 28 STM32F40xxx/41xxx devices bootloader, page 127, one can see that the first step is called "System Reset".
The DFU is not designed to be executed from your application, but to be called according to the bootloader selection after a system reset. Before you are even entering the main function of your application, a few steps are already executed to prepare the device. These steps may be different for the DFU. Calling the DFU from an unexpected system state can lead to undefined behaviour.
The best way to enter the DFU is to latch the BOOT0 pin high and then perform a system reset either by software reset, or by IWDG.
Another potential problem can arise from the HSE, which has to be provided externally, however since you stated that the DFU does eventually work, this seems unlikely.

Flink 1.11 StreamingFileSink flush record(s) early to in-progress file

We have a hourly bucketed StreamingFileSink (to HDFS) where records are relatively infrequent.
Is there a way to configure Flink to flush records to in-progress file as soon as they arrive (less than 1 minute), instead of Flink keeping them in buffer?
The requirement is for successor data analysis process to read in-progress file near-real time.
I know how to shorten InactivityInterval but it results in too many small files in the end, which is undesirable.
May be you can look at the implementation of the write function. There are several implementations which will write the data to the hdfs file in real time.StreamingFileSink itself will not keep them in buffer, but there will be some buffers inside the FileOutputStream
public interface InProgressFileWriter<IN, BucketID> extends PartFileInfo<BucketID> {
/**
* Write a element to the part file.
*
* #param element the element to be written.
* #param currentTime the writing time.
* #throws IOException Thrown if writing the element fails.
*/
void write(final IN element, final long currentTime) throws IOException;
/**
* #return The state of the current part file.
* #throws IOException Thrown if persisting the part file fails.
*/
InProgressFileRecoverable persist() throws IOException;
/**
* #return The state of the pending part file. {#link Bucket} uses this to commit the pending
* file.
* #throws IOException Thrown if an I/O error occurs.
*/
PendingFileRecoverable closeForCommit() throws IOException;
/** Dispose the part file. */
void dispose();
// ------------------------------------------------------------------------
/** A handle can be used to recover in-progress file.. */
interface InProgressFileRecoverable extends PendingFileRecoverable {}
/** The handle can be used to recover pending file. */
interface PendingFileRecoverable {}
}
StreamingFileSink time data is written to HDFS in real time and will not keep them in buffer
In order to support exactly once semantics, the in-progress file will only be renamed into a formal file during checkpoint and then you can do successor data analysis
StreamingFileSink does not support real-time data query, you can reduce the interval of cp to improve the real-time performance of data visibility, but if the cp interval is too small, it will easily lead to small file problems
Have you considered the enable the file compaction option? https://nightlies.apache.org/flink/flink-docs-master/docs/connectors/table/filesystem/#file-compaction

How can I flash the NXP S32K148 using J-Link?

I'm working on a S32K148 with VS Code and J-Link. This is part of NXP's S32Kxxx series of 32-bit ARM Cortex M4-based MCUs targeted for high-reliability automobile and industrial applications.
I want to flash the chip using JFlash (with J-Link), but it seems that flashing has been disabled.
My research suggests that I need to have a LinkScript file for the S32Kxxx device, but I cannot find such a file anywhere.
Is my assumption correct that a LinkScript file is needed? If so, where can I find this file?
First, you need to ensure that the MCU's reset pin is connected to the reset pin of the J-Link. Without this done properly, you will not be able to connect via J-Link.
Next, it must be noted that the design of the S32Kxxx series makes it impossible to attach to a debugging session via J-Link out of the box. The Segger wiki contains a more detailed description:
ECC protected internal RAM
The device series provide ECC protected internal RAM. By default, J-Link resets the MCU on connect and initializes the RAM contents to 0x00. This is done for the following reasons:
If a memory window in the debugger is open during the debug session and points to a non-initialized RAM region, on the next single step etc. a non-maskable ECC error interrupt would be thrown
J-Link temporarily uses some portions of the RAM during flash programming and accesses to non-initialized RAM areas would throw non maskable ECC error interrupts
Attach to debug session
For the reasons mentioned [above, in the section "ECC protected internal RAM"], no out of the box attach is possible. This is because there is no way to distinguish between an attach and a connect.
To attach to the device the following J-Link script file can be used:
File:NXP_Kinetis_S32_Attach.JLinkScript
Note:
This script file is only supposed to be used in case of an attach, as it skips the device specific connect.
So, your research is correct: in order to attach to the device, you must use a J-Link script, which can be downloaded here from Segger. The contents are reprinted below:
* (c) SEGGER Microcontroller GmbH & Co. KG *
* The Embedded Experts *
* www.segger.com *
**********************************************************************
-------------------------- END-OF-HEADER -----------------------------
File : NXP_Kinetis_S32_Attach.JLinkScript
Purpose : Script file to skip the device specific connect for the
NXP Kinetis S32 devices, to make an attach possible.
Literature:
[1] J-Link User Guide
*/
/*********************************************************************
*
* Constants (similar to defines)
*
**********************************************************************
*/
/*********************************************************************
*
* Global variables
*
**********************************************************************
*/
/*********************************************************************
*
* Local functions
*
**********************************************************************
*/
/*********************************************************************
*
* Global functions
*
**********************************************************************
*/
/*********************************************************************
*
* InitTarget()
*
* Function description
* If present, called right before performing generic connect sequence.
* Usually used for targets which need a special connect sequence.
* E.g.: TI devices with ICEPick TAP on them where core TAP needs to be enabled via specific ICEPick sequences first
*
* Return value
* >= 0: O.K.
* < 0: Error
*
* Notes
* (1) Must not use high-level API functions like JLINK_MEM_ etc.
* (2) For target interface JTAG, this device has to setup the JTAG chain + JTAG TAP Ids.
*/
int InitTarget(void) {
//
// As this script file is only used for attach purposes, no special handling is required.
// Therefore, we override the default connect handled by the J-Link DLL for this device.
// as it would trigger a reset.
//
return 0;
}
/*************************** end of file ****************************/

Windows shared memory access time slow

I am currently using shared memory with two mapped files (1.9 GBytes for the first one and 600 MBytes for the second) in a software.
I am using a process that read data from the first file, process the data and write the results to the second file.
I have noticed a strong delay sometimes (the reason is out of my knowledge) when reading or writing to the mapping view with memcpy function.
Mapped files are created this way :
m_hFile = ::CreateFileW(SensorFileName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
m_hMappedFile = CreateFileMapping(m_hFile,
NULL,
PAGE_READWRITE,
dwFileMapSizeHigh,
dwFileMapSizeLow,
NULL);
And memory mapping is done this way :
m_lpMapView = MapViewOfFile(m_hMappedFile,
FILE_MAP_ALL_ACCESS,
dwOffsetHigh,
dwOffsetLow,
m_i64ViewSize);
The dwOffsetHigh/dwOffsetLow are "matching" granularity from the system info.
The process is reading about 300KB * N times, storing that in a buffer, processing and then writing 300KB * N times the processed contents of the previous buffer to the second file.
I have two different memory views (created/moved with MapViewOfFile function) with a size of 10 MBytes as default size.
For memory view size, I tested 10kBytes, 100kB, 1MB, 10MB and 100MB. Statistically no difference, 80% of the time reading process is as described below (~200ms) but writing process is really slow.
Normally :
1/ Reading is done in ~200ms.
2/ Process done in 2.9 seconds.
3/ Writing is done in ~200ms.
I can see that 80% of the time, either reading or writing (in the worst case both are slow) will take between 2 and 10 seconds.
Example : For writing, I am using the below code
for (unsigned int i = 0 ; i < N ; i++) // N = 500~3k
{
// Check the position of the memory view for ponderation
if (###)
MoveView(iOffset);
if (m_lpMapView)
{
memcpy((BYTE*)m_lpMapView + iOffset, pANNHeader, uiANNStatus);
// uiSize = ~300 kBytes
memcpy((BYTE*)m_lpMapView + iTemp, pLine[i], uiSize);
}
else
return uiANNStatus;
}
After using GetTickCount function to pinpoint where is the delay, I am seeing that the second memcpy call is always the one taking most of the time.
So, so far I am seeing N (for test, I used N = 500) calls to memcpy taking 10 seconds at the worst time when using those shared memories.
I made a temporary software that was doing the same quantity of memcpy calls, same amount of data and couldn't see the problem.
For tests, I used the following conditions, they all show the same delay :
1/ I can see this on various computers, 32 or 64 bits from windows 7 to windows 10.
2/ Using the main thread or multi-threads (up to 8 with critical sections for synchronization purpose) for reading/writing.
3/ OS on SATA or SSD, memory mapped files of the software physically on a SATA or SSD hard-disk, and if on external hard-disk, tests were done through USB1, USB2 or USB3.
I am kindly asking you what you would think my mistake is for memcpy to go slow.
Best regards.
I found a solution that works for me but not might be the case for others.
Following Thomas Matthews comments, I checked the MSDN and found two interesting functions FlushViewOfFile and FlushFileBuffers (but couldn't find anything interesting about locking memory).
Calling both after the for loop force update of the mapped file.
I am having no more "random" delay, but instead of the expected 200ms, I have an average of 400ms which is enough for my application.
After doing some tests I saw that calling those too often will cause heavy hard-disk access and will make the delay worse (10 seconds for every for loop) so the flush should be use carefully.
Thanks.

d2: get full count of units in core.time.Duration

I'm messing with core.time.Durations - in particular, I'm trying to properly get number of full minutes in "2 days and 1 hour" Duration. As it have cleared, get!"minutes" returns number of minutes without hours, days and weeks (e.g. 0 in this case), so it's inappropriate for me, because I expect answer of 2940.
I've looked into sources and found core.time.getUnitsFromHNSecs function, which does exactly what I need, but it's private to core.time and uses private field _hnsecs of Duration objects.
Of course, it's possible to do
long minutes_in_duration(Duration d) {
return (d.get!"minutes"() + d.get!"hours"() * 60 +
d.get!"days"() * 24 * 60 + d.get!("weeks") * 7 * 24 * 60);
}
but this is clumsy as hell. Is there better way to do the same thing without scattering away Duration's guts?
More thorough reading through source revealed overlooked .total!"unit" property, which does exactly what it should.